1 | #define _CRT_SECURE_NO_DEPRECATE |
---|
2 | #define _CRT_SECURE_NO_WARNINGS |
---|
3 | |
---|
4 | #ifndef MPQ_H |
---|
5 | #define MPQ_H |
---|
6 | |
---|
7 | #include "libmpq/mpq.h" |
---|
8 | #include <string.h> |
---|
9 | #include <ctype.h> |
---|
10 | #include <vector> |
---|
11 | #include <iostream> |
---|
12 | #include <deque> |
---|
13 | |
---|
14 | using namespace std; |
---|
15 | |
---|
16 | typedef unsigned int uint32; |
---|
17 | class MPQArchive |
---|
18 | { |
---|
19 | |
---|
20 | public: |
---|
21 | mpq_archive mpq_a; |
---|
22 | |
---|
23 | MPQArchive(const char* filename); |
---|
24 | void close(); |
---|
25 | |
---|
26 | uint32 HashString(const char* Input, uint32 Offset) { |
---|
27 | uint32 seed1 = 0x7fed7fed; |
---|
28 | uint32 seed2 = 0xeeeeeeee; |
---|
29 | |
---|
30 | for (uint32 i = 0; i < strlen(Input); i++) { |
---|
31 | uint32 val = toupper(Input[i]); |
---|
32 | seed1 = mpq_a.buf[Offset + val] ^ (seed1 + seed2); |
---|
33 | seed2 = val + seed1 + seed2 + (seed2 << 5) + 3; |
---|
34 | } |
---|
35 | |
---|
36 | return seed1; |
---|
37 | } |
---|
38 | mpq_hash GetHashEntry(const char* Filename) { |
---|
39 | uint32 index = HashString(Filename, 0); |
---|
40 | index &= mpq_a.header->hashtablesize - 1; |
---|
41 | uint32 name1 = HashString(Filename, 0x100); |
---|
42 | uint32 name2 = HashString(Filename, 0x200); |
---|
43 | |
---|
44 | for(uint32 i = index; i < mpq_a.header->hashtablesize; ++i) { |
---|
45 | mpq_hash hash = mpq_a.hashtable[i]; |
---|
46 | if (hash.name1 == name1 && hash.name2 == name2) return hash; |
---|
47 | } |
---|
48 | |
---|
49 | mpq_hash nullhash; |
---|
50 | nullhash.blockindex = 0xFFFFFFFF; |
---|
51 | return nullhash; |
---|
52 | } |
---|
53 | |
---|
54 | vector<string> GetFileList() { |
---|
55 | vector<string> filelist; |
---|
56 | |
---|
57 | mpq_hash hash = GetHashEntry("(listfile)"); |
---|
58 | uint32 blockindex = hash.blockindex; |
---|
59 | |
---|
60 | if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) |
---|
61 | return filelist; |
---|
62 | |
---|
63 | uint32 size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, blockindex); |
---|
64 | char *buffer = new char[size]; |
---|
65 | |
---|
66 | libmpq_file_getdata(&mpq_a, hash, blockindex, (unsigned char*)buffer); |
---|
67 | |
---|
68 | char seps[] = "\n"; |
---|
69 | char *token; |
---|
70 | |
---|
71 | token = strtok( buffer, seps ); |
---|
72 | uint32 counter = 0; |
---|
73 | while ((token != NULL) && (counter < size)) { |
---|
74 | //cout << token << endl; |
---|
75 | token[strlen(token) - 1] = 0; |
---|
76 | string s = token; |
---|
77 | filelist.push_back(s); |
---|
78 | counter += strlen(token) + 2; |
---|
79 | token = strtok(NULL, seps); |
---|
80 | } |
---|
81 | |
---|
82 | delete buffer; |
---|
83 | return filelist; |
---|
84 | } |
---|
85 | }; |
---|
86 | typedef std::deque<MPQArchive*> ArchiveSet; |
---|
87 | |
---|
88 | class MPQFile |
---|
89 | { |
---|
90 | //MPQHANDLE handle; |
---|
91 | bool eof; |
---|
92 | char *buffer; |
---|
93 | size_t pointer,size; |
---|
94 | |
---|
95 | // disable copying |
---|
96 | MPQFile(const MPQFile &f) {} |
---|
97 | void operator=(const MPQFile &f) {} |
---|
98 | |
---|
99 | public: |
---|
100 | MPQFile(const char* filename); // filenames are not case sensitive |
---|
101 | ~MPQFile() { close(); } |
---|
102 | size_t read(void* dest, size_t bytes); |
---|
103 | size_t getSize() { return size; } |
---|
104 | size_t getPos() { return pointer; } |
---|
105 | char* getBuffer() { return buffer; } |
---|
106 | char* getPointer() { return buffer + pointer; } |
---|
107 | bool isEof() { return eof; } |
---|
108 | void seek(int offset); |
---|
109 | void seekRelative(int offset); |
---|
110 | void close(); |
---|
111 | }; |
---|
112 | |
---|
113 | inline void flipcc(char *fcc) |
---|
114 | { |
---|
115 | char t; |
---|
116 | t=fcc[0]; |
---|
117 | fcc[0]=fcc[3]; |
---|
118 | fcc[3]=t; |
---|
119 | t=fcc[1]; |
---|
120 | fcc[1]=fcc[2]; |
---|
121 | fcc[2]=t; |
---|
122 | } |
---|
123 | |
---|
124 | #endif |
---|