Browse Source

Add idSkip

In Windows 95 FREECELL.EXE, the resource IDs are changed to 403, 404 and
405. For some reason.
master
Causal Agent 5 months ago
parent
commit
5d03f0a940
Signed by: Curtis McEnroe <june@causal.agency> GPG Key ID: CEA2F97ADCFCD77C
1 changed files with 18 additions and 8 deletions
  1. 18
    8
      cards.c

+ 18
- 8
cards.c View File

@@ -84,7 +84,10 @@ fail:

// exefmt.txt
static int
loadNE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint16 neOffset) {
loadNE(
SDL_Surface **surfaces, size_t count,
SDL_RWops *rw, Uint16 neOffset, Uint32 idSkip
) {
if (SDL_RWseek(rw, neOffset + 0x24, RW_SEEK_SET) < 0) return -1;
Uint16 resourceTableOffset = neOffset + SDL_ReadLE16(rw);

@@ -114,6 +117,7 @@ loadNE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint16 neOffset) {
SDL_ReadLE32(rw); // reserved

resourceID &= 0x7FFF;
if (resourceID >= idSkip) resourceID -= idSkip;
if (resourceID >= count) continue;

Sint64 nextResource = SDL_RWtell(rw);
@@ -134,7 +138,10 @@ loadNE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint16 neOffset) {

// <https://docs.microsoft.com/en-us/windows/desktop/Debug/pe-format>
static int
loadPE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint16 peOffset) {
loadPE(
SDL_Surface **surfaces, size_t count,
SDL_RWops *rw, Uint16 peOffset, Uint32 idSkip
) {
if (SDL_RWseek(rw, peOffset + 0x04 + 0x02, RW_SEEK_SET) < 0) return -1;
Uint16 sectionCount = SDL_ReadLE16(rw);

@@ -192,8 +199,10 @@ loadPE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint16 peOffset) {

for (Uint16 i = 0; i < nameIDCount; ++i) {
Uint32 nameID = SDL_ReadLE32(rw);
Uint32 subdirOffset = SDL_ReadLE32(rw);
if (nameID >= idSkip) nameID -= idSkip;
if (nameID >= count) continue;

Uint32 subdirOffset = SDL_ReadLE32(rw);
if (!(subdirOffset & (1 << 31))) {
SDL_SetError("bitmap name entry does not point to table");
return -1;
@@ -236,7 +245,8 @@ loadPE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint16 peOffset) {
return 0;
}

static int loadEXE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw) {
static int
loadEXE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw, Uint32 idSkip) {
if (SDL_RWseek(rw, 0, RW_SEEK_SET) < 0) return -1;
if (SDL_ReadU8(rw) != 'M' || SDL_ReadU8(rw) != 'Z') {
SDL_SetError("invalid MZ signature");
@@ -250,9 +260,9 @@ static int loadEXE(SDL_Surface **surfaces, size_t count, SDL_RWops *rw) {
Uint8 sig[2] = { SDL_ReadU8(rw), SDL_ReadU8(rw) };

if (sig[0] == 'N' && sig[1] == 'E') {
return loadNE(surfaces, count, rw, offset);
return loadNE(surfaces, count, rw, offset, idSkip);
} else if (sig[0] == 'P' && sig[1] == 'E') {
return loadPE(surfaces, count, rw, offset);
return loadPE(surfaces, count, rw, offset, idSkip);
} else {
SDL_SetError("invalid NE/PE signature");
return -1;
@@ -341,7 +351,7 @@ Cards_LoadCards(
SDL_RWops *rw, enum Cards_Flag flags
) {
memset(surfaces, 0, sizeof(*surfaces) * count);
if (loadEXE(surfaces, count, rw) < 0) return -1;
if (loadEXE(surfaces, count, rw, 0) < 0) return -1;
if (checkRange(surfaces, count, Cards_A, Cards_Back12) < 0) return -1;
if (checkRange(surfaces, count, Cards_X, Cards_O) < 0) return -1;
if (flags & Cards_ColorKey) {
@@ -362,7 +372,7 @@ Cards_LoadFreeCell(
SDL_RWops *rw, enum Cards_Flag flags
) {
memset(surfaces, 0, sizeof(*surfaces) * count);
if (loadEXE(surfaces, count, rw) < 0) return -1;
if (loadEXE(surfaces, count, rw, 402) < 0) return -1;
if (checkRange(surfaces, count, Cards_KingRight, Cards_KingWin) < 0) {
return -1;
}

Loading…
Cancel
Save