mirror of
https://github.com/kichikuou/system3-sdl2.git
synced 2026-10-11 00:38:10 +03:00
Rewrite fade in / fade out implementation
Before this change, fade in and fade out was implemented using a 16-steps dithering pattern. Now fading uses alpha-blending. It behaves like the PC98 version, where fading was done by palette animation. This reduces `sizeof(AGS)` by 1.2MB.
This commit is contained in:
+38
-67
@@ -330,10 +330,6 @@ AGS::AGS(NACT* parent, const Config& config) : nact(parent), dirty(false)
|
||||
// マウスカーソル
|
||||
cursor_color = 15;
|
||||
cursor_index = 0;
|
||||
|
||||
// フェード状態
|
||||
fader = false;
|
||||
memset(fader_screen, 0, sizeof(fader_screen));
|
||||
}
|
||||
|
||||
AGS::~AGS()
|
||||
@@ -405,51 +401,36 @@ void AGS::set_pixel(int dest, int x, int y, uint8 color)
|
||||
vram[dest][y][x] = color;
|
||||
}
|
||||
|
||||
void AGS::fade_start()
|
||||
void AGS::fade_out(int duration_ms, bool white)
|
||||
{
|
||||
memcpy(fader_screen, hBmpDest->pixels, sizeof(fader_screen));
|
||||
}
|
||||
if (fade_level)
|
||||
return;
|
||||
|
||||
void AGS::fade_end()
|
||||
{
|
||||
memcpy(hBmpDest->pixels, fader_screen, sizeof(fader_screen));
|
||||
}
|
||||
fade_color = white ? 255 : 0;
|
||||
|
||||
void AGS::fade_out(int depth, bool white)
|
||||
{
|
||||
// 通常画面 → 白黒画面
|
||||
int fx = fade_x[depth];
|
||||
int fy = fade_y[depth];
|
||||
fader = true;
|
||||
|
||||
for(int y = 0; y < 480; y += 4) {
|
||||
uint32* dest = surface_line(hBmpDest, y + fy) + fx;
|
||||
for(int x = 0; x < 640; x += 4) {
|
||||
dest[x] = white ? 0xffffff : 0;
|
||||
}
|
||||
Uint32 dwStart = SDL_GetTicks();
|
||||
while (fade_level < 255) {
|
||||
nact->sys_sleep(16);
|
||||
int t = SDL_GetTicks() - dwStart;
|
||||
fade_level = t >= duration_ms ? 255 : t * 255 / duration_ms;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
// 画面更新
|
||||
invalidate_screen(0, 0, 640, screen_height);
|
||||
update_screen();
|
||||
}
|
||||
|
||||
void AGS::fade_in(int depth)
|
||||
void AGS::fade_in(int duration_ms)
|
||||
{
|
||||
// 白黒画面 → 通常画面
|
||||
int fx = fade_x[depth];
|
||||
int fy = fade_y[depth];
|
||||
fader = (depth == 15) ? false : true;
|
||||
if (fade_level == 0)
|
||||
return;
|
||||
|
||||
for(int y = 0; y < 480; y += 4) {
|
||||
uint32* src = &fader_screen[640 * (y + fy) + fx];
|
||||
uint32* dest = surface_line(hBmpDest, y + fy) + fx;
|
||||
for(int x = 0; x < 640; x += 4) {
|
||||
dest[x] = src[x];
|
||||
}
|
||||
Uint32 dwStart = SDL_GetTicks();
|
||||
while (fade_level > 0) {
|
||||
nact->sys_sleep(16);
|
||||
int t = SDL_GetTicks() - dwStart;
|
||||
fade_level = t >= duration_ms ? 0 : (duration_ms - t) * 255 / duration_ms;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
// 画面更新
|
||||
invalidate_screen(0, 0, 640, screen_height);
|
||||
update_screen();
|
||||
}
|
||||
|
||||
void AGS::flush_screen(bool update)
|
||||
@@ -473,36 +454,20 @@ void AGS::flush_screen(bool update)
|
||||
|
||||
void AGS::draw_screen(int sx, int sy, int width, int height)
|
||||
{
|
||||
if(fader) {
|
||||
for(int y = sy; y < (sy + height) && y < 480; y++) {
|
||||
uint32* src = vram[0][y];
|
||||
uint32* dest = &fader_screen[640 * y];
|
||||
for(int x = sx; x < (sx + width) && x < 640; x++) {
|
||||
uint32 a=src[x];
|
||||
if (nact->sys_ver == 3 && src[x] & 0x80000000) {
|
||||
// あゆみちゃん物語 フルカラー実写版
|
||||
dest[x] = src[x] & 0xffffff;
|
||||
} else {
|
||||
dest[x] = screen_palette[src[x] & 0xff];
|
||||
}
|
||||
for(int y = sy; y < (sy + height) && y < 480; y++) {
|
||||
uint32* src = vram[0][y];
|
||||
uint32* dest = surface_line(hBmpDest, y);
|
||||
for(int x = sx; x < (sx + width) && x < 640; x++) {
|
||||
uint32 a=src[x];
|
||||
if (nact->sys_ver == 3 && src[x] & 0x80000000) {
|
||||
// あゆみちゃん物語 フルカラー実写版
|
||||
dest[x] = src[x] & 0xffffff;
|
||||
} else {
|
||||
dest[x] = screen_palette[src[x] & 0xff];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int y = sy; y < (sy + height) && y < 480; y++) {
|
||||
uint32* src = vram[0][y];
|
||||
uint32* dest = surface_line(hBmpDest, y);
|
||||
for(int x = sx; x < (sx + width) && x < 640; x++) {
|
||||
uint32 a=src[x];
|
||||
if (nact->sys_ver == 3 && src[x] & 0x80000000) {
|
||||
// あゆみちゃん物語 フルカラー実写版
|
||||
dest[x] = src[x] & 0xffffff;
|
||||
} else {
|
||||
dest[x] = screen_palette[src[x] & 0xff];
|
||||
}
|
||||
}
|
||||
}
|
||||
invalidate_screen(sx, sy, width, height);
|
||||
}
|
||||
invalidate_screen(sx, sy, width, height);
|
||||
}
|
||||
|
||||
void AGS::invalidate_screen(int sx, int sy, int width, int height)
|
||||
@@ -528,6 +493,12 @@ void AGS::update_screen()
|
||||
return;
|
||||
SDL_RenderClear(sdlRenderer);
|
||||
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
|
||||
if (fade_level) {
|
||||
SDL_SetRenderDrawBlendMode(sdlRenderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetRenderDrawColor(sdlRenderer, fade_color, fade_color, fade_color, fade_level);
|
||||
SDL_RenderFillRect(sdlRenderer, NULL);
|
||||
SDL_SetRenderDrawBlendMode(sdlRenderer, SDL_BLENDMODE_NONE);
|
||||
}
|
||||
SDL_RenderPresent(sdlRenderer);
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
+4
-11
@@ -12,10 +12,6 @@
|
||||
#include "nact.h"
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
// フェード処理
|
||||
static const int fade_x[16] = {0, 2, 2, 0, 1, 3, 3, 1, 1, 3, 3, 1, 0, 2, 2, 0};
|
||||
static const int fade_y[16] = {0, 2, 0, 2, 1, 3, 1, 3, 0, 2, 0, 2, 1, 3, 1, 3};
|
||||
|
||||
#define MAX_CG 10000
|
||||
|
||||
static inline uint32 SETPALETTE256(uint32 R, uint32 G, uint32 B)
|
||||
@@ -89,8 +85,8 @@ private:
|
||||
uint32 screen_palette[256];
|
||||
uint8 gaiji[188][32];
|
||||
|
||||
bool fader; // フェードの状態
|
||||
uint32 fader_screen[640 * 480];
|
||||
int fade_level = 0; // 0-255
|
||||
int fade_color = 0; // 0: black, 255: white
|
||||
|
||||
public:
|
||||
AGS(NACT* parent, const Config& config);
|
||||
@@ -106,11 +102,8 @@ public:
|
||||
uint8 get_pixel(int dest, int x, int y);
|
||||
void set_pixel(int dest, int x, int y, uint8 color);
|
||||
|
||||
void fade_start();
|
||||
void fade_end();
|
||||
void fade_out(int depth, bool white);
|
||||
void fade_in(int depth);
|
||||
bool now_fade() { return fader; }
|
||||
void fade_out(int duration_ms, bool white);
|
||||
void fade_in(int duration_ms);
|
||||
|
||||
void copy(int sx, int sy, int ex, int ey, int dx, int dy);
|
||||
void gcopy(int gsc, int gde, int glx, int gly, int gsw);
|
||||
|
||||
@@ -15,7 +15,7 @@ void AGS::clear_text_window(int index, bool erase)
|
||||
int ey = text_w[index - 1].ey;
|
||||
|
||||
if(erase) {
|
||||
if(text_w[index - 1].frame && fader) {
|
||||
if(text_w[index - 1].frame && fade_level) {
|
||||
draw_window(sx - 8, sy - 8, ex + 8, ey + 8, true, text_frame_color, text_back_color);
|
||||
} else {
|
||||
box_fill(0, sx, sy, ex, ey, text_back_color);
|
||||
@@ -95,7 +95,7 @@ void AGS::open_text_window(int index, bool erase)
|
||||
text_w[index - 1].screen_height = height;
|
||||
|
||||
for(int y = 0; y < height && y + sy < 480; y++) {
|
||||
uint32* scr = fader ? &fader_screen[640 * (y + sy) + sx] : surface_line(hBmpDest, y + sy) + sx;
|
||||
uint32* scr = surface_line(hBmpDest, y + sy) + sx;
|
||||
for(int x = 0; x < width && x + sx < 640; x++) {
|
||||
uint32 col = vram[0][y + sy][x + sx];
|
||||
if(!(col & 0x80000000)) {
|
||||
@@ -157,7 +157,7 @@ void AGS::close_text_window(int index, bool update)
|
||||
text_w[index - 1].window_height = height;
|
||||
|
||||
for(int y = 0; y < height && y + sy < 480; y++) {
|
||||
uint32* scr = fader ? &fader_screen[640 * (y + sy) + sx] : surface_line(hBmpDest, y + sy) + sx;
|
||||
uint32* scr = surface_line(hBmpDest, y + sy) + sx;
|
||||
for(int x = 0; x < width && x + sx < 640; x++) {
|
||||
uint32 col = vram[0][y + sy][x + sx];
|
||||
if(!(col & 0x80000000)) {
|
||||
@@ -230,7 +230,7 @@ void AGS::open_menu_window(int index)
|
||||
menu_w[index - 1].screen_height = wheight;
|
||||
|
||||
for(int y = 0; y < wheight && y + wsy < 480; y++) {
|
||||
uint32* scr = fader ? &fader_screen[640 * (y + wsy) + wsx] : surface_line(hBmpDest, y + wsy) + wsx;
|
||||
uint32* scr = surface_line(hBmpDest, y + wsy) + wsx;
|
||||
for(int x = 0; x < wwidth && x + wsx < 640; x++) {
|
||||
uint32 col = vram[0][y + wsy][x + wsx];
|
||||
if(!(col & 0x80000000)) {
|
||||
|
||||
+1
-1
@@ -227,7 +227,6 @@ protected:
|
||||
int menu_select(int num_items);
|
||||
void wait_after_open_menu();
|
||||
|
||||
void sys_sleep(int ms);
|
||||
uint8 get_key();
|
||||
void get_cursor(int* x, int* y);
|
||||
void set_cursor(int x, int y);
|
||||
@@ -253,6 +252,7 @@ protected:
|
||||
|
||||
public:
|
||||
bool mainloop();
|
||||
void sys_sleep(int ms);
|
||||
|
||||
int get_screen_height();
|
||||
|
||||
|
||||
+2
-20
@@ -1188,29 +1188,11 @@ void NACT_Sys2::cmd_y()
|
||||
break;
|
||||
case 40:
|
||||
case 42:
|
||||
if(ags->now_fade()) {
|
||||
Uint32 dwStart = SDL_GetTicks();
|
||||
for(int i = 0; i < 16; i++) {
|
||||
ags->fade_in(i);
|
||||
int32 ms = dwStart + param * 1000 / 60 * i - SDL_GetTicks();
|
||||
if (ms > 0)
|
||||
sys_sleep(ms);
|
||||
}
|
||||
ags->fade_end();
|
||||
}
|
||||
ags->fade_in(param * 16 * 1000 / 60);
|
||||
break;
|
||||
case 41:
|
||||
case 43:
|
||||
if(!ags->now_fade()) {
|
||||
ags->fade_start();
|
||||
Uint32 dwStart = SDL_GetTicks();
|
||||
for(int i = 0; i < 16; i++) {
|
||||
ags->fade_out(i, (cmd == 41) ? false : true);
|
||||
int32 ms = dwStart + param * 1000 / 60 * i - SDL_GetTicks();
|
||||
if (ms > 0)
|
||||
sys_sleep(ms);
|
||||
}
|
||||
}
|
||||
ags->fade_out(param * 16 * 1000 / 60, cmd == 43);
|
||||
break;
|
||||
case 221:
|
||||
case 222:
|
||||
|
||||
+2
-20
@@ -1160,29 +1160,11 @@ void NACT_Sys3::cmd_y()
|
||||
break;
|
||||
case 40:
|
||||
case 42:
|
||||
if(ags->now_fade()) {
|
||||
Uint32 dwStart = SDL_GetTicks();
|
||||
for(int i = 0; i < 16; i++) {
|
||||
ags->fade_in(i);
|
||||
int32 ms = dwStart + param * 1000 / 60 * i - SDL_GetTicks();
|
||||
if (ms > 0)
|
||||
sys_sleep(ms);
|
||||
}
|
||||
ags->fade_end();
|
||||
}
|
||||
ags->fade_in(param * 16 * 1000 / 60);
|
||||
break;
|
||||
case 41:
|
||||
case 43:
|
||||
if(!ags->now_fade()) {
|
||||
ags->fade_start();
|
||||
Uint32 dwStart = SDL_GetTicks();
|
||||
for(int i = 0; i < 16; i++) {
|
||||
ags->fade_out(i, (cmd == 41) ? false : true);
|
||||
int32 ms = dwStart + param * 1000 / 60 * i - SDL_GetTicks();
|
||||
if (ms > 0)
|
||||
sys_sleep(ms);
|
||||
}
|
||||
}
|
||||
ags->fade_out(param * 16 * 1000 / 60, cmd == 43);
|
||||
break;
|
||||
case 45:
|
||||
ags->extract_palette = param ? true : false;
|
||||
|
||||
Reference in New Issue
Block a user