diff --git a/README.md b/README.md index 5c45552..2d408b8 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Here is a list of available game IDs and their corresponding titles: | `ayumi_fd` | あゆみちゃん物語 | | | `ayumi_hint` | あゆみちゃん物語 ヒントディスク | | | `ayumi_live_256` | あゆみちゃん物語 実写版 | | -| `ayumi_live_full` | あゆみちゃん物語 フルカラー実写版 | | +| `ayumi_live_full` | あゆみちゃん物語 フルカラー実写版 | Unsupported | | `ayumi_proto` | あゆみちゃん物語 PROTO | | | `bunkasai` | あぶない文化祭前夜 | | | `crescent` | クレセントムーンがぁる | | diff --git a/src/sys/ags.cpp b/src/sys/ags.cpp index b687189..108185d 100644 --- a/src/sys/ags.cpp +++ b/src/sys/ags.cpp @@ -79,14 +79,19 @@ AGS::AGS(const Config& config, const GameId& game_id) : game_id(game_id), dirty( // DIBSection 8bpp * 3 (表, 裏, メニュー) for(int i = 0; i < 3; i++) { - hBmpScreen[i] = SDL_CreateRGBSurface(0, 640, 480, 32, 0, 0, 0, 0); + hBmpScreen[i] = SDL_CreateRGBSurfaceWithFormat(0, 640, 480, 8, SDL_PIXELFORMAT_INDEX8); + + // all surfaces share the same palette + if (i > 0) { + SDL_SetSurfacePalette(hBmpScreen[i], hBmpScreen[0]->format->palette); + } // TODO: clear surface // memset(lpBmpScreen[i], 0, 640 * 480 * sizeof(DWORD)); // 仮想VRAMへのポインタ取得 for(int j = 0; j < 480; j++) { - vram[i][j] = surface_line(hBmpScreen[i], j); + vram[i][j] = (uint8_t*)hBmpScreen[i]->pixels + hBmpScreen[i]->pitch * j; } } @@ -448,11 +453,7 @@ void AGS::set_palette(int index, int r, int g, int b) uint8 AGS::get_pixel(int dest, int x, int y) { - if(vram[dest][y][x] & 0x80000000) { - return 0; - } else { - return (uint8)vram[dest][y][x]; - } + return vram[dest][y][x]; } void AGS::set_pixel(int dest, int x, int y, uint8 color) @@ -496,15 +497,10 @@ void AGS::flush_screen(bool update) { if(update) { for(int y = 0; y < screen_height; y++) { - uint32* src = vram[0][y]; + uint8_t* src = vram[0][y]; uint32* dest = surface_line(hBmpDest, y); for(int x = 0; x < screen_width; x++) { - if (game_id.sys_ver == 3 && src[x] & 0x80000000) { - // あゆみちゃん物語 フルカラー実写版 - dest[x] = src[x] & 0xffffff; - } else { - dest[x] = screen_palette[src[x] & 0xff]; - } + dest[x] = screen_palette[src[x]]; } } } @@ -519,16 +515,10 @@ void AGS::draw_screen(int sx, int sy, int width, int height) SDL_IntersectRect(&rect, &screen, &clip); for (int y = clip.y; y < clip.y + clip.h; y++) { - uint32* src = vram[0][y]; + uint8_t* src = vram[0][y]; uint32* dest = surface_line(hBmpDest, y); for(int x = clip.x; x < clip.x + clip.w; x++) { - uint32 a=src[x]; - if (game_id.sys_ver == 3 && src[x] & 0x80000000) { - // あゆみちゃん物語 フルカラー実写版 - dest[x] = src[x] & 0xffffff; - } else { - dest[x] = screen_palette[src[x] & 0xff]; - } + dest[x] = screen_palette[src[x]]; } } invalidate_screen(clip.x, clip.y, clip.w, clip.h); diff --git a/src/sys/ags.h b/src/sys/ags.h index f0679e0..23fc90e 100644 --- a/src/sys/ags.h +++ b/src/sys/ags.h @@ -82,7 +82,7 @@ private: uint8 palB(uint8 col) { return screen_palette[col] & 0xff; } int nearest_color(int r, int g, int b); - uint32* vram[3][480]; // 仮想VRAMへのポインタ + uint8_t* vram[3][480]; // 仮想VRAMへのポインタ Palette program_palette; Palette screen_palette; @@ -181,13 +181,13 @@ public: int ey; bool frame; bool push; - uint32* screen; + uint8_t* screen; int screen_x; int screen_y; int screen_width; int screen_height; Palette screen_palette; - uint32* window; + uint8_t* window; int window_x; int window_y; int window_width; diff --git a/src/sys/ags_bmp.cpp b/src/sys/ags_bmp.cpp index 1cf1587..bd717bf 100644 --- a/src/sys/ags_bmp.cpp +++ b/src/sys/ags_bmp.cpp @@ -20,27 +20,6 @@ void AGS::load_bmp(const char* file_name) } if(extract_cg) { - assert(false); -#if 0 - // BMP読み込み - WCHAR wszFilePath[_MAX_PATH]; - MultiByteToWideChar(CP_ACP, 0, FILEIO::GetFilePath(file_name), -1, wszFilePath, _MAX_PATH); - Gdiplus::Bitmap *pBitmap = Gdiplus::Bitmap::FromFile(wszFilePath); - for(unsigned int y = 0; y < pBitmap->GetHeight(); y++) { - for(unsigned int x = 0; x < pBitmap->GetWidth(); x++) { - Gdiplus::Color srcColor; - pBitmap->GetPixel(x, y, &srcColor); - vram[dest_screen][y + sy][sx + x] = SETPALETTE256(srcColor.GetR(), srcColor.GetG(), srcColor.GetB()) | 0x80000000; - } - } - - // 画面更新 - if(dest_screen == 0) { - draw_screen(sx, sy, pBitmap->GetWidth(), pBitmap->GetHeight()); - } - - // BMP開放 - delete pBitmap; -#endif + WARNING("not implemented"); } } diff --git a/src/sys/ags_draw.cpp b/src/sys/ags_draw.cpp index 81a8143..b7b9ba1 100644 --- a/src/sys/ags_draw.cpp +++ b/src/sys/ags_draw.cpp @@ -78,24 +78,6 @@ void AGS::load_cg(int page, int transparent) void AGS::copy(int sx, int sy, int ex, int ey, int dx, int dy) { -#if 0 - int width = ex - sx + 1; - int height = ey - sy + 1; - - uint32 tmp[640 * 480]; - memcpy(tmp, lpBmpScreen[src_screen], sizeof(tmp)); - - for(int y = 0; y < height && y + sy < 480 && y + dy < 480; y++) { - uint32* src = &tmp[640 * (479 - (y + sy))]; - uint32* dest = vram[dest_screen][y + dy]; - for(int x = 0; x < width && x + sx < 640 && x + dx < 640; x++) { - dest[x + dx] = src[x + sx]; - } - } - if(dest_screen == 0) { - draw_screen(dx, dy, width, height); - } -#else int width = ex - sx + 1; int height = ey - sy + 1; SDL_Rect srcrect = {sx, sy, width, height}; @@ -106,7 +88,6 @@ void AGS::copy(int sx, int sy, int ex, int ey, int dx, int dy) if(dest_screen == 0) { draw_screen(dx, dy, ex - sx + 1, ey - sy + 1); } -#endif } void AGS::gcopy(int gsc, int gde, int glx, int gly, int gsw) @@ -130,7 +111,7 @@ void AGS::gcopy(int gsc, int gde, int glx, int gly, int gsw) void AGS::paint(int x, int y, uint8 color) { - int old_color = vram[0][y][x]; + uint8_t old_color = vram[0][y][x]; if (old_color == color) return; diff --git a/src/sys/ags_gl3.cpp b/src/sys/ags_gl3.cpp index 0684e9f..05444c4 100644 --- a/src/sys/ags_gl3.cpp +++ b/src/sys/ags_gl3.cpp @@ -127,7 +127,7 @@ void AGS::load_gl3(uint8* data, int page, int transparent) c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8); c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8); - uint32* dest = &vram[dest_screen][y + sy][(x + sx) * 8]; + uint8_t* dest = &vram[dest_screen][y + sy][(x + sx) * 8]; if(transparent == -1) { for(int i = 0; i < 8; i++) { dest[i] = c[i] | base; diff --git a/src/sys/ags_gm3.cpp b/src/sys/ags_gm3.cpp index fa675c2..1ae2317 100644 --- a/src/sys/ags_gm3.cpp +++ b/src/sys/ags_gm3.cpp @@ -128,8 +128,8 @@ void AGS::load_gm3(uint8* data, int page, int transparent) c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4); c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4); - uint32* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8]; - uint32* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8]; + uint8_t* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8]; + uint8_t* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8]; if(transparent == -1) { for(int i = 0; i < 8; i++) { dest0[i] = dest1[i] = c[i] | base; diff --git a/src/sys/ags_pms.cpp b/src/sys/ags_pms.cpp index be3c8f4..aadae9d 100644 --- a/src/sys/ags_pms.cpp +++ b/src/sys/ags_pms.cpp @@ -150,7 +150,7 @@ void AGS::load_pms(uint8* data, int page, int transparent) // VRAMに転送 if(extract_cg) { - uint32* dest = &vram[dest_screen][y + sy][sx]; + uint8_t* dest = &vram[dest_screen][y + sy][sx]; if(transparent == -1) { for(int x = 0; x < width; x++) { cgdata[2][x] = cgdata[1][x]; diff --git a/src/sys/ags_text.cpp b/src/sys/ags_text.cpp index 328cf78..240b7d8 100644 --- a/src/sys/ags_text.cpp +++ b/src/sys/ags_text.cpp @@ -442,7 +442,7 @@ void AGS::draw_char(int dest, int dest_x, int dest_y, uint16 code, TTF_Font* fon // パターン出力 for (int y = std::max(0, -dest_y); y < fs->h && dest_y + y < 480; y++) { - uint8 *pattern = (uint8*)surface_line(fs, y); // FIXME: do not assume 8bpp + uint8_t* pattern = (uint8_t*)fs->pixels + fs->pitch * y; for(int x = 0; x < fs->w && dest_x + x < 640; x++) { if(pattern[x] != 0) { vram[dest][dest_y + y][dest_x + x] = color; @@ -477,8 +477,8 @@ void AGS::draw_char_antialias(int dest, int dest_x, int dest_y, uint16 code, TTF // パターン出力 for (int y = std::max(0, -dest_y); y < fs->h && dest_y + y < 480; y++) { - uint8 *pattern = (uint8*)surface_line(fs, y); - uint32 *dp = &vram[dest][dest_y + y][dest_x]; + uint8_t* pattern = (uint8_t*)fs->pixels + fs->pitch * y; + uint8_t* dp = &vram[dest][dest_y + y][dest_x]; for(int x = 0; x < fs->w && dest_x + x < 640; x++, dp++) { uint8 bg = *dp; int alpha = pattern[x] >> 5; diff --git a/src/sys/ags_vsp.cpp b/src/sys/ags_vsp.cpp index 32e99a8..29a4cd2 100644 --- a/src/sys/ags_vsp.cpp +++ b/src/sys/ags_vsp.cpp @@ -141,7 +141,7 @@ void AGS::load_vsp(uint8* data, int page, int transparent) c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4) | ((b3 << 2) & 8); c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4) | ((b3 << 3) & 8); - uint32* dest; + uint8_t* dest; // Gakuen Senki uses exact sx values rather than 8x. if (game_id.is(GameId::GAKUEN)) dest = &vram[dest_screen][y + sy][(x * 8) + sx]; diff --git a/src/sys/ags_vsp2l.cpp b/src/sys/ags_vsp2l.cpp index 03f7a7c..5ad34cd 100644 --- a/src/sys/ags_vsp2l.cpp +++ b/src/sys/ags_vsp2l.cpp @@ -119,8 +119,8 @@ void AGS::load_vsp2l(uint8* data, int page, int transparent) c[6] = ((b0 >> 1) & 1) | ((b1 ) & 2) | ((b2 << 1) & 4); c[7] = ((b0 ) & 1) | ((b1 << 1) & 2) | ((b2 << 2) & 4); - uint32* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8]; - uint32* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8]; + uint8_t* dest0 = &vram[dest_screen][(y + sy) * 2 + 0][(x + sx) * 8]; + uint8_t* dest1 = &vram[dest_screen][(y + sy) * 2 + 1][(x + sx) * 8]; if(transparent == -1) { for(int i = 0; i < 8; i++) { dest0[i] = dest1[i] = c[i] | base; diff --git a/src/sys/ags_window.cpp b/src/sys/ags_window.cpp index 98c8437..19ac3bd 100644 --- a/src/sys/ags_window.cpp +++ b/src/sys/ags_window.cpp @@ -88,19 +88,17 @@ void AGS::open_text_window(int index, bool erase) free(text_w[index - 1].screen); } - text_w[index - 1].screen = (uint32*)malloc(width * height * sizeof(uint32)); + text_w[index - 1].screen = (uint8_t*)malloc(width * height); text_w[index - 1].screen_x = sx; text_w[index - 1].screen_y = sy; text_w[index - 1].screen_width = width; text_w[index - 1].screen_height = height; for(int y = 0; y < height && y + sy < 480; y++) { - uint32* scr = surface_line(hBmpDest, y + sy) + sx; + uint32_t* 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)) { - text_w[index - 1].screen_palette[col & 0xff] = scr[x]; - } + uint8_t col = vram[0][y + sy][x + sx]; + text_w[index - 1].screen_palette[col] = scr[x]; text_w[index - 1].screen[x + width * y] = col; } } @@ -149,7 +147,7 @@ void AGS::close_text_window(int index, bool update) free(text_w[index - 1].window); } - text_w[index - 1].window = (uint32*)malloc(width * height * sizeof(uint32)); + text_w[index - 1].window = (uint8_t*)malloc(width * height); text_w[index - 1].window_x = sx; text_w[index - 1].window_y = sy; text_w[index - 1].window_width = width; @@ -158,10 +156,8 @@ void AGS::close_text_window(int index, bool update) for(int y = 0; y < height && y + sy < 480; y++) { 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)) { - text_w[index - 1].window_palette[col & 0xff] = scr[x]; - } + uint8_t col = vram[0][y + sy][x + sx]; + text_w[index - 1].window_palette[col] = scr[x]; text_w[index - 1].window[x + width * y] = col; } } @@ -197,7 +193,7 @@ void AGS::close_text_window(int index, bool update) void AGS::clear_menu_window() { // TODO: use draw function - memset(hBmpScreen[2]->pixels, menu_back_color, 640 * 480 * sizeof(Uint32)); + memset(hBmpScreen[2]->pixels, menu_back_color, 640 * 480); } void AGS::open_menu_window(int index) @@ -221,7 +217,7 @@ void AGS::open_menu_window(int index) free(menu_w[index - 1].screen); } - menu_w[index - 1].screen = (uint32*)malloc(wwidth * wheight * sizeof(uint32)); + menu_w[index - 1].screen = (uint8_t*)malloc(wwidth * wheight); menu_w[index - 1].screen_x = wsx; menu_w[index - 1].screen_y = wsy; menu_w[index - 1].screen_width = wwidth; @@ -230,10 +226,8 @@ void AGS::open_menu_window(int index) for(int y = 0; y < wheight && y + wsy < 480; y++) { 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)) { - menu_w[index - 1].screen_palette[col & 0xff] = scr[x]; - } + uint8_t col = vram[0][y + wsy][x + wsx]; + menu_w[index - 1].screen_palette[col] = scr[x]; menu_w[index - 1].screen[x + wwidth * y] = col; } } @@ -294,7 +288,7 @@ void AGS::draw_window(int sx, int sy, int ex, int ey, bool frame, uint8 frame_co { // 領域の塗り潰し for(int y = sy; y <= ey && y < 480; y++) { - uint32* dest = vram[0][y]; + uint8_t* dest = vram[0][y]; for(int x = sx; x <= ex && x < 640; x++) { dest[x] = back_color; }