diff options
-rw-r--r-- | cards.c | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/cards.c b/cards.c index dac93fe..c6403b9 100644 --- a/cards.c +++ b/cards.c @@ -143,32 +143,11 @@ static int setBlackBorders(struct Cards *cards) { return 0; } -struct Cards *Cards_Load(SDL_RWops *rw, enum Cards_Flags flags) { - struct Cards *cards = calloc(1, sizeof(*cards)); - if (!cards) { - SDL_SetError("calloc error: %s", strerror(errno)); - return NULL; - } - - if (SDL_RWseek(rw, 0, RW_SEEK_SET) < 0) goto fail; - if (SDL_ReadU8(rw) != 'M' || SDL_ReadU8(rw) != 'Z') { - SDL_SetError("invalid MZ signature"); - goto fail; - } - - if (SDL_RWseek(rw, 0x3C, RW_SEEK_SET) < 0) goto fail; - Uint16 neOffset = SDL_ReadLE16(rw); - - if (SDL_RWseek(rw, neOffset, RW_SEEK_SET) < 0) goto fail; - if (SDL_ReadU8(rw) != 'N' || SDL_ReadU8(rw) != 'E') { - SDL_SetError("invalid NE signature"); - goto fail; - } - - if (SDL_RWseek(rw, neOffset + 0x24, RW_SEEK_SET) < 0) goto fail; +static int loadNE(struct Cards *cards, SDL_RWops *rw, Uint16 neOffset) { + if (SDL_RWseek(rw, neOffset + 0x24, RW_SEEK_SET) < 0) return -1; Uint16 resourceTableOffset = neOffset + SDL_ReadLE16(rw); - if (SDL_RWseek(rw, resourceTableOffset, RW_SEEK_SET) < 0) goto fail; + if (SDL_RWseek(rw, resourceTableOffset, RW_SEEK_SET) < 0) return -1; Uint16 alignmentShift = SDL_ReadLE16(rw); Uint16 resourceCount; @@ -179,11 +158,11 @@ struct Cards *Cards_Load(SDL_RWops *rw, enum Cards_Flags flags) { if (!typeID) { SDL_SetError("no bitmap resources"); - goto fail; + return -1; } if (typeID == 0x8002) break; - if (SDL_RWseek(rw, 0x0C * resourceCount, RW_SEEK_CUR) < 0) goto fail; + if (SDL_RWseek(rw, 0x0C * resourceCount, RW_SEEK_CUR) < 0) return -1; } for (Uint16 i = 0; i < resourceCount; ++i) { @@ -197,16 +176,52 @@ struct Cards *Cards_Load(SDL_RWops *rw, enum Cards_Flags flags) { if (id >= Cards_Count) continue; Sint64 next = SDL_RWtell(rw); - if (next < 0) goto fail; + if (next < 0) return -1; cards->surfaces[id] = dibSurface( rw, (Uint32)offset << alignmentShift, (Uint32)length << alignmentShift ); - if (!cards->surfaces[id]) goto fail; + if (!cards->surfaces[id]) return -1; + + if (SDL_RWseek(rw, next, RW_SEEK_SET) < 0) return -1; + } + + return 0; +} - if (SDL_RWseek(rw, next, RW_SEEK_SET) < 0) goto fail; +static int loadPE(struct Cards *cards, SDL_RWops *rw, Uint16 peOffset) { + SDL_SetError("loadPE unimplemented"); + return -1; +} + +struct Cards *Cards_Load(SDL_RWops *rw, enum Cards_Flags flags) { + struct Cards *cards = calloc(1, sizeof(*cards)); + if (!cards) { + SDL_SetError("calloc error: %s", strerror(errno)); + return NULL; + } + + if (SDL_RWseek(rw, 0, RW_SEEK_SET) < 0) goto fail; + if (SDL_ReadU8(rw) != 'M' || SDL_ReadU8(rw) != 'Z') { + SDL_SetError("invalid MZ signature"); + goto fail; + } + + if (SDL_RWseek(rw, 0x3C, RW_SEEK_SET) < 0) goto fail; + Uint16 offset = SDL_ReadLE16(rw); + + if (SDL_RWseek(rw, offset, RW_SEEK_SET) < 0) goto fail; + Uint8 sig[] = { SDL_ReadU8(rw), SDL_ReadU8(rw) }; + + if (sig[0] == 'N' && sig[1] == 'E') { + if (loadNE(cards, rw, offset) < 0) goto fail; + } else if (sig[0] == 'P' && sig[1] == 'E') { + if (loadPE(cards, rw, offset) < 0) goto fail; + } else { + SDL_SetError("invalid NE/PE signature"); + goto fail; } for (int i = Cards_Club + Cards_A; i <= Cards_Spade + Cards_K; ++i) { |