Add function to load only screenshot from snapshot file

This commit is contained in:
OV2 2019-12-19 18:18:45 +01:00
parent 2e7a345dca
commit 3c2ef2aa21
2 changed files with 153 additions and 29 deletions

View File

@ -1069,6 +1069,38 @@ int S9xUnfreezeGameMem (const uint8 *buf, uint32 bufSize)
return result;
}
void S9xMessageFromResult(int result, const char* base)
{
switch(result)
{
case WRONG_FORMAT:
S9xMessage(S9X_ERROR, S9X_WRONG_FORMAT, SAVE_ERR_WRONG_FORMAT);
break;
case WRONG_VERSION:
S9xMessage(S9X_ERROR, S9X_WRONG_VERSION, SAVE_ERR_WRONG_VERSION);
break;
case WRONG_MOVIE_SNAPSHOT:
S9xMessage(S9X_ERROR, S9X_WRONG_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_WRONG_MOVIE);
break;
case NOT_A_MOVIE_SNAPSHOT:
S9xMessage(S9X_ERROR, S9X_NOT_A_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_NOT_MOVIE);
break;
case SNAPSHOT_INCONSISTENT:
S9xMessage(S9X_ERROR, S9X_SNAPSHOT_INCONSISTENT, MOVIE_ERR_SNAPSHOT_INCONSISTENT);
break;
case FILE_NOT_FOUND:
default:
sprintf(String, SAVE_ERR_ROM_NOT_FOUND, base);
S9xMessage(S9X_ERROR, S9X_ROM_NOT_FOUND, String);
break;
}
}
bool8 S9xUnfreezeGame (const char *filename)
{
STREAM stream = NULL;
@ -1088,35 +1120,7 @@ bool8 S9xUnfreezeGame (const char *filename)
if (result != SUCCESS)
{
switch (result)
{
case WRONG_FORMAT:
S9xMessage(S9X_ERROR, S9X_WRONG_FORMAT, SAVE_ERR_WRONG_FORMAT);
break;
case WRONG_VERSION:
S9xMessage(S9X_ERROR, S9X_WRONG_VERSION, SAVE_ERR_WRONG_VERSION);
break;
case WRONG_MOVIE_SNAPSHOT:
S9xMessage(S9X_ERROR, S9X_WRONG_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_WRONG_MOVIE);
break;
case NOT_A_MOVIE_SNAPSHOT:
S9xMessage(S9X_ERROR, S9X_NOT_A_MOVIE_SNAPSHOT, MOVIE_ERR_SNAPSHOT_NOT_MOVIE);
break;
case SNAPSHOT_INCONSISTENT:
S9xMessage(S9X_ERROR, S9X_SNAPSHOT_INCONSISTENT, MOVIE_ERR_SNAPSHOT_INCONSISTENT);
break;
case FILE_NOT_FOUND:
default:
sprintf(String, SAVE_ERR_ROM_NOT_FOUND, base);
S9xMessage(S9X_ERROR, S9X_ROM_NOT_FOUND, String);
break;
}
S9xMessageFromResult(result, base);
return (FALSE);
}
@ -1141,6 +1145,34 @@ bool8 S9xUnfreezeGame (const char *filename)
return (FALSE);
}
bool8 S9xUnfreezeScreenshot(const char *filename, uint16 **image_buffer, int &width, int &height)
{
STREAM stream = NULL;
const char *base = S9xBasename(filename);
if(S9xOpenSnapshotFile(filename, TRUE, &stream))
{
int result;
result = S9xUnfreezeScreenshotFromStream(stream, image_buffer, width, height);
S9xCloseSnapshotFile(stream);
if(result != SUCCESS)
{
S9xMessageFromResult(result, base);
return (FALSE);
}
return (TRUE);
}
sprintf(String, SAVE_ERR_SAVE_NOT_FOUND, base);
S9xMessage(S9X_INFO, S9X_FREEZE_FILE_INFO, String);
return (FALSE);
}
void S9xFreezeToStream (STREAM stream)
{
char buffer[8192];
@ -1801,6 +1833,96 @@ int S9xUnfreezeFromStream (STREAM stream)
return (result);
}
// load screenshot from file, allocating memory for it
int S9xUnfreezeScreenshotFromStream(STREAM stream, uint16 **image_buffer, int &width, int &height)
{
int result = SUCCESS;
int version, len;
char buffer[PATH_MAX + 1];
len = strlen(SNAPSHOT_MAGIC) + 1 + 4 + 1;
if(READ_STREAM(buffer, len, stream) != (unsigned int)len)
return (WRONG_FORMAT);
if(strncmp(buffer, SNAPSHOT_MAGIC, strlen(SNAPSHOT_MAGIC)) != 0)
return (WRONG_FORMAT);
version = atoi(&buffer[strlen(SNAPSHOT_MAGIC) + 1]);
if(version > SNAPSHOT_VERSION)
return (WRONG_VERSION);
result = UnfreezeBlock(stream, "NAM", (uint8 *)buffer, PATH_MAX);
if(result != SUCCESS)
return (result);
uint8 *local_screenshot = NULL;
// skip all blocks until screenshot
SkipBlockWithName(stream, "CPU");
SkipBlockWithName(stream, "REG");
SkipBlockWithName(stream, "PPU");
SkipBlockWithName(stream, "DMA");
SkipBlockWithName(stream, "VRA");
SkipBlockWithName(stream, "RAM");
SkipBlockWithName(stream, "SRA");
SkipBlockWithName(stream, "FIL");
SkipBlockWithName(stream, "SND");
SkipBlockWithName(stream, "CTL");
SkipBlockWithName(stream, "TIM");
SkipBlockWithName(stream, "SFX");
SkipBlockWithName(stream, "SA1");
SkipBlockWithName(stream, "SAR");
SkipBlockWithName(stream, "DP1");
SkipBlockWithName(stream, "DP2");
SkipBlockWithName(stream, "DP4");
SkipBlockWithName(stream, "CX4");
SkipBlockWithName(stream, "ST0");
SkipBlockWithName(stream, "OBC");
SkipBlockWithName(stream, "OBM");
SkipBlockWithName(stream, "S71");
SkipBlockWithName(stream, "SRT");
SkipBlockWithName(stream, "CLK");
SkipBlockWithName(stream, "BSX");
SkipBlockWithName(stream, "MSU");
result = UnfreezeStructCopy(stream, "SHO", &local_screenshot, SnapScreenshot, COUNT(SnapScreenshot), version);
if(result == SUCCESS && local_screenshot)
{
SnapshotScreenshotInfo *ssi = new SnapshotScreenshotInfo;
UnfreezeStructFromCopy(ssi, SnapScreenshot, COUNT(SnapScreenshot), local_screenshot, version);
width = min(ssi->Width, IMAGE_WIDTH);
height = min(ssi->Height, IMAGE_HEIGHT);
*image_buffer = (uint16 *)malloc(width * height * sizeof(uint16));
uint8 *rowpix = ssi->Data;
uint16 *screen = (*image_buffer);
for(int y = 0; y < height; y++, screen += width)
{
for(int x = 0; x < width; x++)
{
uint32 r, g, b;
r = *(rowpix++);
g = *(rowpix++);
b = *(rowpix++);
screen[x] = BUILD_PIXEL(r, g, b);
}
}
delete ssi;
}
if(local_screenshot) delete[] local_screenshot;
return (result);
}
static int FreezeSize (int size, int type)
{
switch (type)

View File

@ -31,5 +31,7 @@ bool8 S9xUnfreezeGame (const char *);
int S9xUnfreezeGameMem (const uint8 *,uint32);
void S9xFreezeToStream (STREAM);
int S9xUnfreezeFromStream (STREAM);
bool8 S9xUnfreezeScreenshot(const char *filename, uint16 **image_buffer, int &width, int &height);
int S9xUnfreezeScreenshotFromStream(STREAM stream, uint16 **image_buffer, int &width, int &height);
#endif