Merge pull request #1 from thegtproject/winsupport

mpq/stormlib now works on windows
This commit is contained in:
Alex Yatskov 2018-12-28 17:35:47 -08:00 committed by GitHub
commit 9fdcd8bb39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 68 additions and 18 deletions

1
extract.bat Normal file
View File

@ -0,0 +1 @@
go run .\tools\mpq --target="assets" extract mpq\d2data.mpq

16
formats/mpq/build.go Normal file
View File

@ -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"

View File

@ -1,22 +1,30 @@
package mpq package mpq
// #cgo LDFLAGS: -L./stormlib/ -lstorm -lz -lbz2 -lstdc++ // #ifdef _MPQ_WINDOWS
// #include <windows.h>
// #include <stdlib.h> // #include <stdlib.h>
// #endif
// #ifdef _MPQ_LINUX
// #include <stdlib.h>
// #define WINAPI
// DWORD GetLastError();
// #endif
//
// #define DWORD unsigned int // #define DWORD unsigned int
// #define HANDLE void *
// #define LONG int
// #define LPDWORD unsigned int * // #define LPDWORD unsigned int *
// #define LPOVERLAPPED void * // #define LPOVERLAPPED void *
// #define TCHAR char // #define TCHAR char
// #define WINAPI // #define HANDLE void *
// #define bool unsigned char // #define bool unsigned char
// #define LONG int
//
// bool WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq); // bool WINAPI SFileOpenArchive(const TCHAR * szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE * phMpq);
// bool WINAPI SFileCloseArchive(HANDLE hMpq); // bool WINAPI SFileCloseArchive(HANDLE hMpq);
// bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile); // bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char * szFileName, DWORD dwSearchScope, HANDLE * phFile);
// DWORD WINAPI SFileSetFilePointer(HANDLE hFile, LONG lFilePos, LONG * plFilePosHigh, DWORD dwMoveMethod); // 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 SFileReadFile(HANDLE hFile, void * lpBuffer, DWORD dwToRead, LPDWORD pdwRead, LPOVERLAPPED lpOverlapped);
// bool WINAPI SFileCloseFile(HANDLE hFile); // bool WINAPI SFileCloseFile(HANDLE hFile);
// DWORD GetLastError(); //
import "C" import "C"
import ( import (
"bytes" "bytes"
@ -65,7 +73,7 @@ func (f *file) Read(data []byte) (int, error) {
var bytesRead int 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 { if result := C.SFileReadFile(f.handle, unsafe.Pointer(&data[0]), C.uint(len(data)), (*C.uint)(unsafe.Pointer(&bytesRead)), nil); result == 0 {
lastError := getLastError() lastError := getLastError()
if lastError == 1002 { // ERROR_HANDLE_EOF if lastError == sysEOF { // ERROR_HANDLE_EOF
return bytesRead, io.EOF return bytesRead, io.EOF
} }
@ -161,7 +169,7 @@ func (a *archive) buildPathMap() error {
for _, line := range lines { for _, line := range lines {
pathInt := strings.TrimSpace(line) pathInt := strings.TrimSpace(line)
if len(pathInt) > 0 { if len(pathInt) > 0 {
pathExt := santizePath(pathInt) pathExt := sanitizePath(pathInt)
a.paths[pathExt] = pathInt a.paths[pathExt] = pathInt
} }
} }
@ -169,7 +177,7 @@ func (a *archive) buildPathMap() error {
return nil return nil
} }
func santizePath(path string) string { func sanitizePath(path string) string {
return strings.ToLower(strings.Replace(path, "\\", string(os.PathSeparator), -1)) return strings.ToLower(strings.Replace(path, "\\", string(os.PathSeparator), -1))
} }

7
formats/mpq/mpq_linux.go Normal file
View File

@ -0,0 +1,7 @@
// +build linux
package mpq
const (
sysEOF = 1002
)

View File

@ -0,0 +1,7 @@
// +build windows
package mpq
const (
sysEOF = 38
)

11
formats/mpq/readme.txt Normal file
View File

@ -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.

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"path" "path/filepath"
"github.com/FooSoft/lazarus/formats/mpq" "github.com/FooSoft/lazarus/formats/mpq"
"github.com/bmatcuk/doublestar" "github.com/bmatcuk/doublestar"
@ -57,8 +57,8 @@ func extract(mpqPath, filter, targetDir string) error {
} }
defer resFile.Close() defer resFile.Close()
sysPath := path.Join(targetDir, resPath) sysPath := filepath.Join(targetDir, resPath)
if err := os.MkdirAll(path.Dir(sysPath), 0777); err != nil { if err := os.MkdirAll(filepath.Dir(sysPath), 0777); err != nil {
return err return err
} }
@ -85,7 +85,7 @@ func main() {
) )
flag.Usage = func() { 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") fmt.Fprintf(os.Stderr, "Parameters:\n\n")
flag.PrintDefaults() flag.PrintDefaults()
} }