diff --git a/src/sys/ags.h b/src/sys/ags.h index 5baced4..16eb648 100644 --- a/src/sys/ags.h +++ b/src/sys/ags.h @@ -55,7 +55,7 @@ private: void load_gm3(const std::vector& data, int transparent); // Intruder -桜屋敷の探索- void load_vsp2l(const std::vector& data, int transparent); // Little Vampire void load_gl3(const std::vector& data, bool set_palette, int transparent); - void load_pms(const std::vector& data, bool set_palette, int transparent); + void load_pms(int page, const std::vector& data, bool set_palette, int transparent); void load_bmp(const char* file_name); // あゆみちゃん物語 フルカラー実写版 void load_vsp(const std::vector& data, bool set_palette, int transparent); diff --git a/src/sys/ags_draw.cpp b/src/sys/ags_draw.cpp index cf004b2..7c01230 100644 --- a/src/sys/ags_draw.cpp +++ b/src/sys/ags_draw.cpp @@ -56,12 +56,12 @@ void AGS::load_cg(int page, int transparent) load_vsp(data, set_palette, transparent); } else if (game_id.is_sdps()) { // Super D.P.S - load_pms(data, set_palette, transparent); + load_pms(page, data, set_palette, transparent); } else { if(data[0x8] == 0) { load_vsp(data, set_palette, transparent); } else { - load_pms(data, set_palette, transparent); + load_pms(page, data, set_palette, transparent); } } break; @@ -72,7 +72,7 @@ void AGS::load_cg(int page, int transparent) load_vsp(data, set_palette, transparent); } else { set_palette = set_palette || game_id.is(GameId::FUNNYBEE_CD); - load_pms(data, set_palette, transparent); + load_pms(page, data, set_palette, transparent); } break; } diff --git a/src/sys/ags_pms.cpp b/src/sys/ags_pms.cpp index 10bef81..97a9032 100644 --- a/src/sys/ags_pms.cpp +++ b/src/sys/ags_pms.cpp @@ -8,7 +8,7 @@ #include "game_id.h" #include -void AGS::load_pms(const std::vector& data, bool set_palette, int transparent) +void AGS::load_pms(int page, const std::vector& data, bool set_palette, int transparent) { // ヘッダ取得 int sx = data[0x0] | (data[0x1] << 8); @@ -87,66 +87,72 @@ void AGS::load_pms(const std::vector& data, bool set_palette, int trans } } - // PMS展開 - uint8 cgdata[3][640]; + if (!extract_cg) { + return; + } + // Extract pixel data + std::vector buf[3]; + buf[0].resize(width); + buf[1].resize(width); + buf[2].resize(width); int p = 0x320; - memset(cgdata, 0, sizeof(cgdata)); - for(int y = 0; y < height; y++) { + for (int y = 0; y < height; y++) { int x = 0; - while(x < width) { - uint8 d1 = data[p++]; - if(d1 == 0xff) { + while (x < width) { + // Some PMS images in Rance 4.1/4.2 English translation do not have + // enough pixels for the image size. + if (p >= data.size()) { + WARNING("CG #%d: PMS data is incomplete or corrupted.", page); + goto finish; + } + + uint8_t d1 = data[p++]; + if (d1 == 0xff) { int length = data[p++] + 3; - memcpy(cgdata[0] + x, cgdata[1] + x, length); + memcpy(buf[0].data() + x, buf[1].data() + x, length); x += length; - } else if(d1 == 0xfe) { + } else if (d1 == 0xfe) { int length = data[p++] + 3; - memcpy(cgdata[0] + x, cgdata[2] + x, length); + memcpy(buf[0].data() + x, buf[2].data() + x, length); x += length; - } else if(d1 == 0xfd) { + } else if (d1 == 0xfd) { int length = data[p++] + 4; - uint8 d2 = data[p++]; - memset(cgdata[0] + x, d2, length); + uint8_t d2 = data[p++]; + memset(buf[0].data() + x, d2, length); x += length; - } else if(d1 == 0xfc) { + } else if (d1 == 0xfc) { int length = data[p++] + 3; - uint8 d2 = data[p++]; - uint8 d3 = data[p++]; + uint8_t d2 = data[p++]; + uint8_t d3 = data[p++]; for(int i = 0; i < length; i++) { - cgdata[0][x++] = d2; - cgdata[0][x++] = d3; + buf[0][x++] = d2; + buf[0][x++] = d3; } - } else if(d1 == 0xfb || d1 == 0xfa || d1 == 0xf9 || d1 == 0xf8) { - cgdata[0][x++] = data[p++]; + } else if (d1 == 0xfb || d1 == 0xfa || d1 == 0xf9 || d1 == 0xf8) { + buf[0][x++] = data[p++]; } else { - cgdata[0][x++] = d1; + buf[0][x++] = d1; } } - // VRAMに転送 - if(extract_cg) { - 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]; - cgdata[1][x] = cgdata[0][x]; - dest[x] = cgdata[0][x]; - } - } else { - for(int x = 0; x < width; x++) { - cgdata[2][x] = cgdata[1][x]; - cgdata[1][x] = cgdata[0][x]; - if(cgdata[0][x] != transparent) { - dest[x] = cgdata[0][x]; - } + // Transfer the row to VRAM + uint8_t* dest = &vram[dest_screen][y + sy][sx]; + if (transparent == -1) { + memcpy(dest, buf[0].data(), width); + } else { + for (int x = 0; x < width; x++) { + if (buf[0][x] != transparent) { + dest[x] = buf[0][x]; } } } + buf[2].swap(buf[1]); + buf[1].swap(buf[0]); } - // 画面更新 - if(dest_screen == 0 && extract_cg) { +finish: + if (dest_screen == 0) { draw_screen(sx, sy, width, height); } }