diff options
Diffstat (limited to 'cards.c')
-rw-r--r-- | cards.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/cards.c b/cards.c index 9e92aa9..ddc5b86 100644 --- a/cards.c +++ b/cards.c @@ -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; } |