diff --git a/extract.bat b/extract.bat new file mode 100644 index 0000000..4d9d57d --- /dev/null +++ b/extract.bat @@ -0,0 +1 @@ +go run .\tools\mpq --target="assets" extract mpq\d2data.mpq diff --git a/formats/mpq/build.go b/formats/mpq/build.go new file mode 100644 index 0000000..86d6e7a --- /dev/null +++ b/formats/mpq/build.go @@ -0,0 +1,16 @@ +package mpq + +/* + +// Build Tags + +// Windows +#cgo windows CFLAGS: -D_MPQ_WINDOWS +#cgo windows LDFLAGS: -Lstormlib -lstorm -lwininet -lz -lbz2 -lstdc++ + +// Linux +#cgo linux CFLAGS: -D_MPQ_LINUX +#cgo linux LDFLAGS: -L./stormlib/ -lstorm -lz -lbz2 -lstdc++ + +*/ +import "C" diff --git a/formats/mpq/mpq.go b/formats/mpq/mpq.go index 88cb9c7..bdc30e4 100644 --- a/formats/mpq/mpq.go +++ b/formats/mpq/mpq.go @@ -1,22 +1,29 @@ package mpq -// #cgo LDFLAGS: -L./stormlib/ -lstorm -lz -lbz2 -lstdc++ -// #include +// #ifdef _MPQ_WINDOWS +// #include +// #include +// #endif +// #ifdef _MPQ_LINUX +// #include +// #define WINAPI +// DWORD GetLastError(); +// #endif // #define DWORD unsigned int // #define HANDLE void * // #define LONG int // #define LPDWORD unsigned int * // #define LPOVERLAPPED void * // #define TCHAR char -// #define WINAPI // #define bool unsigned char -// bool WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq); -// bool WINAPI SFileCloseArchive(HANDLE hMpq); -// bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile); +// +// bool WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq); +// bool WINAPI SFileCloseArchive(HANDLE hMpq); +// bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile); // DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod); -// bool WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped); -// bool WINAPI SFileCloseFile(HANDLE hFile); -// DWORD GetLastError(); +// bool WINAPI SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped); +// bool WINAPI SFileCloseFile(HANDLE hFile); +// import "C" import ( "bytes" @@ -65,7 +72,7 @@ func (f *file) Read(data []byte) (int, error) { var bytesRead int if result := C.SFileReadFile(f.handle, unsafe.Pointer(&data[0]), C.uint(len(data)), (*C.uint)(unsafe.Pointer(&bytesRead)), nil); result == 0 { lastError := getLastError() - if lastError == 1002 { // ERROR_HANDLE_EOF + if lastError == 1002 || lastError == 38 { // ERROR_HANDLE_EOF return bytesRead, io.EOF } @@ -161,7 +168,7 @@ func (a *archive) buildPathMap() error { for _, line := range lines { pathInt := strings.TrimSpace(line) if len(pathInt) > 0 { - pathExt := santizePath(pathInt) + pathExt := sanitizePath(pathInt) a.paths[pathExt] = pathInt } } @@ -169,7 +176,7 @@ func (a *archive) buildPathMap() error { return nil } -func santizePath(path string) string { +func sanitizePath(path string) string { return strings.ToLower(strings.Replace(path, "\\", string(os.PathSeparator), -1)) } diff --git a/formats/mpq/readme.txt b/formats/mpq/readme.txt new file mode 100644 index 0000000..8f91d2c --- /dev/null +++ b/formats/mpq/readme.txt @@ -0,0 +1,11 @@ +To compile and install stormlib on windows with mingw64: + +Copy the stormlib folder to an easy to access directory. I used /mingw64/home/thegtproject/stormlib + +(from mingw64 console) + +$ cd /mingw64/home/thegtproject/stormlib +$ cmake -DCMAKE_SYSTEM_NAME="windows" -DCMAKE_INSTALL_PREFIX="/mingw64" . +$ make && make install + +Done. \ No newline at end of file diff --git a/tools/mpq/mpq.go b/tools/mpq/mpq.go index 0e01c94..40e217f 100644 --- a/tools/mpq/mpq.go +++ b/tools/mpq/mpq.go @@ -5,7 +5,7 @@ import ( "fmt" "io" "os" - "path" + "path/filepath" "github.com/FooSoft/lazarus/formats/mpq" "github.com/bmatcuk/doublestar" @@ -57,8 +57,8 @@ func extract(mpqPath, filter, targetDir string) error { } defer resFile.Close() - sysPath := path.Join(targetDir, resPath) - if err := os.MkdirAll(path.Dir(sysPath), 0777); err != nil { + sysPath := filepath.Join(targetDir, resPath) + if err := os.MkdirAll(filepath.Dir(sysPath), 0777); err != nil { return err } @@ -85,7 +85,7 @@ func main() { ) flag.Usage = func() { - fmt.Fprintf(os.Stderr, "Usage: %s [options] command [files]\n", path.Base(os.Args[0])) + fmt.Fprintf(os.Stderr, "Usage: %s [options] command [files]\n", filepath.Base(os.Args[0])) fmt.Fprintf(os.Stderr, "Parameters:\n\n") flag.PrintDefaults() }