Skip to content

Commit

Permalink
fix path slash; upd test; change icon; add fixedsprites.zip; v2.0 final
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchen committed Mar 18, 2020
1 parent 350ef7b commit 86e6bdb
Show file tree
Hide file tree
Showing 19 changed files with 686 additions and 6,565 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*.lod
*.lnk
*.zip
!fixedsprites.zip


# Uncomment these types if you want even more clean repository. But be careful.
# It can make harm to an existing project source. Read explanations below.
Expand Down
47 changes: 39 additions & 8 deletions MMArchUnit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,14 @@ OtherMmarchException = class(Exception);
function withTrailingSlash(path: string): string;

resourcestring
FileNotFound = 'File %s is not found in the archive';
FileNameEmpty = 'File name is empty';
DirNotFound = 'Directory %s is not found';
SEPaletteMustExist = 'Image must be in 256 colors mode and palette must be added to bitmaps.lod';
SEPaletteNotFound = 'Failed to find matching palette in [*.]bitmaps.lod';
FileNotFound = 'File %s is not found in the archive';
FileNameEmpty = 'File name is empty';
DirNotFound = 'Directory %s is not found';
SEPaletteMustExist = 'Image must be in 256 colors mode and palette must be added to bitmaps.lod';
SEPaletteNotFound = 'Failed to find matching palette in [*.]bitmaps.lod';
ErrorStr = 'Error: %s';
FileErrorStr = 'File %s error: %s';
FileInArchiveErrorStr = 'File %s in archive %s error:';


implementation
Expand Down Expand Up @@ -335,7 +338,21 @@ procedure MMArchSimple.extractAll(folder: string; ext: string = '*');
) then
begin
RSCreateDir(folder); // this function checks DirectoryExists()
arch.Extract(i, folder);

try // the individual file will be skipped if it gets an exception
arch.Extract(i, folder);
except
on E: OtherMmarchException do
begin
WriteLn(format(FileInArchiveErrorStr, [fFiles.Name[i], fFiles.FileName]));
WriteLn(E.Message);
end;
on E: Exception do
begin
WriteLn(format(FileInArchiveErrorStr, [fFiles.Name[i], fFiles.FileName]));
WriteLn(E.Message);
end;
end;
end;
end;
end;
Expand Down Expand Up @@ -375,7 +392,14 @@ procedure MMArchSimple.deleteAll(ext: string = '*');
verifyExtractedExt(i, ext)
) then
begin
fFiles.Delete(i);
try // the individual file will be skipped if it gets an exception
fFiles.Delete(i);
except
on E: OtherMmarchException do
WriteLn(format(FileErrorStr, [fFiles.Name[i], E.Message]));
on E: Exception do
WriteLn(format(FileErrorStr, [fFiles.Name[i], E.Message]));
end;
end;
end;
optimize;
Expand Down Expand Up @@ -403,7 +427,14 @@ procedure MMArchSimple.addAll(folder: string; ext: string = '*');
fileNames := getAllFilesInFolder(folder, ext);
for fileName in fileNames do
begin
add(withTrailingSlash(folder) + fileName);
try // the individual file will be skipped if it gets an exception
add(withTrailingSlash(folder) + fileName);
except
on E: OtherMmarchException do
WriteLn(format(FileErrorStr, [fileName, E.Message]));
on E: Exception do
WriteLn(format(FileErrorStr, [fileName, E.Message]));
end;
end;
fileNames.Free;
end;
Expand Down
45 changes: 32 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ mmarch list <ARCHIVE_FILE> [SEPARATOR]

List all file names in the archive file.

`[SEPARATOR]` is a string that separates the file names, use double quote (`""`) to enclose the separator. By default (when `[SEPARATOR]` is not specified), windows newline (CRLF) will be used as the separator, which means it will output one file name per line.
`[SEPARATOR]` is a string that separates the file names, use double quotes (`""`) to enclose the separator. By default (when `[SEPARATOR]` is not specified), windows newline (CRLF) will be used as the separator, which means it will output one file name per line.

**Examples:**

Expand Down Expand Up @@ -209,7 +209,7 @@ Display help information.
The "Notes on `FOLDER`" applys to the argument representing a **folder path** in <code>mmarch <a href="#extract">extract</a></code> and <code>mmarch <a href="#create">create</a></code>.

* Folder path cannot be empty when it is required
* If folder path contains space (` `), use double quote (`""`) to enclose the folder path
* If folder path contains space (` `), use double quotes (`""`) to enclose the folder path
* Path without a leading slash, or with a leading `./`: **relative path**
* `.`: **current directory**
* `..`: parent directory of the current directory (use with **CAUTION!**)
Expand All @@ -224,20 +224,22 @@ The "Notes on `FILE_TO_XXXX_?`" applys to the argument representing a **file pat
* `*` or `*.*`: **all the files**
* `*.EXT` (e.g. `*.txt`): all the files with the specified **extension**
* `*.`: all the files **without extension**
* You can add directory path before the aforementioned wildcard character. Similar rules for folder path apply to the file path (incl. the double quote, relative and absolute path, slash usage)
* You can add directory path before the aforementioned wildcard character. Similar rules for folder path apply to the file path (incl. the double quotes, relative and absolute path, slash usage)

## Batch archive extraction

You can use wildcard for `<ARCHIVE_FILE>` in `mmarch extract` command to extract all archives in specified folder(s) with just one command.

* File path in `<ARCHIVE_FILE>`:
* `**`: zero or more directories (i.e. the current directory and all its subdirectories, **recursively**)
* `**`: zero or more directories (i.e. the current directory and all its subdirectories, **recursively**, non-hidden)
* `*`: any **ONE** directory
* Read the section "[§ Notes on `FOLDER`](#notes-on-folder)" above for **relative path** and **absolute path** (absolute path is **NOT recommended at all!**)
* File name at the end of `<ARCHIVE_FILE>`:
* `*` or `*.*`: all the **supported** archive files (`.lod`, `.pac`, `.snd`, `.vid`, `.lwd`, `.mm7`, `.dod` & `.mm6`)
* `*.EXT` (e.g. `*.lod`): all the **supported** archive files with the specified **extension** (`a.bitmaps.lod`'s extension is `.lod`, not `.bitmaps.lod`)
* `*.EXT1|EXT2|EXT3...` (e.g. `*.lod|lwd|vid`): all the supported archive files with any of the specified extensions
* `"*.EXT1|EXT2|EXT3..."` (e.g. `"*.lod|lwd|vid"`): all the supported archive files with any of the specified extensions, note that it has to be enclosed by double quotes

You might need to wait a few minutes if you are trying to extract all the archive files from a whole game.

**Examples:**

Expand All @@ -254,7 +256,7 @@ mmarch extract data/*.lod . *.txt
The command above can extract all `.txt` resource files in all `.lod` archive files in `data/` directory. The resources will be placed in an auto-named subdirectory in current directory (current directory = `.`).

```
mmarch extract */*.lod|lwd ../resource_folder
mmarch extract "*/*.lod|lwd" ../resource_folder
```

The command above can extract all the resource files in all `.lod` and `.lwd` archive files in any first level subdirectories of the current directory. The resources will be placed in an auto-named subdirectory in `resource_folder/` that belongs to the parent directory of the current directory.
Expand Down Expand Up @@ -287,12 +289,26 @@ mmarch create myfiles.sprites.lod mmspriteslod . mymonster01.bmp /p 23 mymonster

## Other tips and notes

Less important tips and notes include:

### Use initial letter for the first argument

For the first argument, the initial letter of <code><strong>e</strong>xtract</code>, <code><strong>l</strong>ist</code>, <code><strong>a</strong>dd</code>, <code><strong>d</strong>elete</code>, <code><strong>r</strong>ename</code>, <code><strong>c</strong>reate</code>, <code><strong>m</strong>erge</code>, <code><strong>o</strong>ptimize</code>, <code><strong>h</strong>elp</code> can be used instead of them; they can be optionally preceded by a leading `-` or `--` which will do the same job.

### Paths are case-insensitive

File names and paths are case-insensitive.

### Backup please

The tool changes or overrides original archive or unpacked resource files permanently, you should consider copying them to other directory or with other names to make backups (e.g. `copy a.lod a.backup.lod`).

### File will be skipped if it fails

If the program encounters an error when extracting, adding or deleting a resource file from archive file(s), this resource file will be skipped and the rest will still be processed.

### In-archive and extracted extension difference

For some archive format, some files have different file extensions in the archive and as extracted files out of the archive. Don't wrong, you can use either extension to refer to the file. Below is the list (same extension is used if not listed):

| Archive Format | In-Archive Ext | Extracted Ext |
Expand All @@ -308,6 +324,15 @@ For some archive format, some files have different file extensions in the archiv
| `mmspriteslod` | No Extension | `bmp` |
| `mm8loclod` | No Extension | `bmp` |

### Sprites with incorrect palette

Official Might and Magic VI and VII has some sprites with incorrect palette:

* MM6's bat images, stored in data/SPRITES.LOD as `BAT****` files, have incorrect palette: their palette should be 156 instead of 422 (pal422 exists in BITMAPS.LOD but is unrelated).
* MM7's "swptree" images, stored in data/SPRITES.LOD as `swptree*` files, have incorrect palette: their palette should be 120 instead of 940 (pal940 doesn't exist in BITMAPS.LOD at all).

**mmarch** will not fix their problem and will skip these sprite bitmaps (though GrayFace's MMArchive can fix them). However, you may find these sprites bitmap files well extracted with correct palette in [`fixedsprites.zip` in the repo](https://github.com/might-and-magic/mmarch/blob/master/fixedsprites.zip).

## Work with batch, NSIS and other scripts

**mmarch** can be used with [batch file](https://en.wikibooks.org/wiki/Windows_Batch_Scripting) (.bat) or [NSIS script](https://nsis.sourceforge.io/Main_Page) to produce game patch or MOD installation files. Also, with [Python](https://www.python.org/), [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript), batch files, [PowerShell](https://docs.microsoft.com/en-us/powershell/) script, etc., **mmarch** can automatize the workflow of the development of Heroes of Might and Magic 3 and Might and Magic 6, 7, 8 MODs and patches.
Expand Down Expand Up @@ -339,12 +364,6 @@ IF %errorlevel% == 0 (
)
```

Extract all resource files in all archive files in current folder, resource file will be placed in a subfolder with the same name of its archive file without extension:

```
for %i in (*) do ( mmarch extract "%~nxi" "%~ni" )
```

## Compilation

How to compile the source of **mmarch**:
Expand All @@ -357,7 +376,7 @@ How to compile the source of **mmarch**:

## Change Log
* [2020-03-11] v1.0: initial release
* [2020-03-17] v2.0: support palette; support `*.EXT` and batch archive extraction; deal with in-archive & extracted file extension differences and the "cannot find the path specified" problem caused by it
* [2020-03-18] v2.0: support palette; support `*.EXT` and batch archive extraction; deal with in-archive & extracted file extension differences and the "cannot find the path specified" problem caused by it

## License

Expand Down
Binary file added fixedsprites.zip
Binary file not shown.
Loading

0 comments on commit 86e6bdb

Please sign in to comment.