UNPKG

@dada78641/bwmapimage

Version:

Generates images of StarCraft: Brood War and Remastered maps

203 lines (149 loc) 9.27 kB
[![MIT license](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT) [![npm version](https://badge.fury.io/js/@dada78641%2Fbwmapimage.svg)](https://badge.fury.io/js/@dada78641%2Fbwmapimage) # @dada78641/bwmapimage Library for generating map images for *StarCraft: Brood War* and *Remastered*. Both **map files** (.scm and .scx) as well as **replay files** (.rep) are supported as input. This is a wrapper library around the [bw-chk](https://github.com/ShieldBattery/bw-chk), [jssuh](https://github.com/ShieldBattery/jssuh) and [scm-extractor](https://github.com/ShieldBattery/scm-extractor) libraries made by the [Shield Battery](https://shieldbattery.net/) project. All the heavy lifting is done by their code—this library mostly just simplifies the process and passes the result through an image encoder. ## Usage This library is available via npm. ```bash npm i --save @dada78641/bwmapimage ``` Basic usage involves passing a filename and getting an image buffer in return: ```js import fs from 'fs/promises' import {BwMapImage} from '@dada78641/bwmapimage' const bwMapImage = new BwMapImage('(4)Vermeer SE_2.1.scm', {}) const [buffer, metadata] = await bwMapImage.renderMapImage() await fs.writeFile(`out${metadata.extension}`, buffer, null) ``` By default, the library will generate a full size .png file (which can take a bit of time and be quite large). ### Reference **Function:** ```js new BwMapImage(file, options) ``` **Parameters:** * `file` **string|buffer**\ Either a path to a .scm, .scx or .rep file; or a buffer of one of such files. * `options` **object|null**\ See below. **Returns:** A `BwMapImage` object for the given file and options object. For the source file, you can pass either a string or a buffer. If a string is passed, the file will be read from disk, with the file type assumed from the extension; a buffer will be processed in the same way. ---- **Function:** ```js await bwMapImage.renderMapImage() ``` **Returns:** * `buffer` **string**\ Image buffer that can be directly saved to a file. * `metadata.type` **string**\ Either `"map"` or `"replay"`. * `metadata.extension` **string**\ A recommended file extension for the given format, e.g. `".jpg"` * `metadata.format` **string**\ Image format used. * `metadata.channels` **number**\ Number of channels in the output image. * `metadata.size` **number**\ Size of the buffer in bytes. * `metadata.width` **number**\ Final width of the image buffer after resizing. * `metadata.height` **number**\ Final height of the image buffer after resizing. * `metadata.fullWidth` **number**\ Full width of the bitmap prior to resizing. * `metadata.fullHeight` **number**\ Full height of the bitmap prior to resizing. * `metadata.mapTitle` **string**\ Raw title for the map. Can contain escape sequences. * `metadata.mapTitleStripped` **string**\ Title for the map with escape sequences stripped. * `metadata.mapDescription` **string**\ Description for the map. * `metadata.mapHash` **string**\ XXH64 hash of the map data, for caching purposes. * `metadata.mapTileWidth` **number**\ Map width in tiles. * `metadata.mapTileHeight` **number**\ Map height in tiles. * `metadata.mapTilesetName` **string**\ Name of the tileset used. * `metadata.mapTilesetId` **number**\ Tileset ID for the map—see [sctoolsdata](https://github.com/msikma/sctoolsdata) for more information. * `metadata.mapEncoding` **string**\ Character encoding for the map; typically either `"cp949"`, `"cp1252"` or `"utf8"`. * `metadata.resolvedOptions` **object**\ The user's passed options with default options merged in. Generates an image from a map or replay file. ---- **Function:** ```js await bwMapImage.getMapMetadata() ``` **Returns:** * `metadata.mapTitle` **string**\ Raw title for the map. Can contain escape sequences. * `metadata.mapTitleStripped` **string**\ Title for the map with escape sequences stripped. * `metadata.mapDescription` **string**\ Description for the map. * `metadata.mapHash` **string**\ XXH64 hash of the map data, for caching purposes. * `metadata.mapTileWidth` **number**\ Map width in tiles. * `metadata.mapTileHeight` **number**\ Map height in tiles. * `metadata.mapTilesetName` **string**\ Name of the tileset used. * `metadata.mapTilesetId` **number**\ Tileset ID for the map—see [@dada78641/bwtoolsdata](https://github.com/msikma/bwtoolsdata) for more information. * `metadata.mapEncoding` **string**\ Character encoding for the map; typically either `"cp949"`, `"cp1252"` or `"utf8"`. This returns metadata about the map data itself, before the image is generated. This allows for you to, for example, check the `mapHash` against a cache. Note that the hash is specific to the map data, not to the generated image. It's designed specifically to be used for **caching** purposes, in that two maps with the same hash will always produce the same image. ### Options The following options can be passed: | Setting | Type | Default | Notes | |:--------|:-----|:--------|:------| | bwGraphicsPath | **string\|null** | `null` | If null, this gets set to ~/.config/bwmapimage, where ~ is the user's home directory. | | forceType | **string\|null** | `null` | Either `"map"` or `"replay"`, but normally autodetected. | | tileSize | **number** | `32` | Either `32`, `16` or `8`. Base tile size; 32 is full size, anything smaller results in smaller images for much less processing time and memory. | | encoderType | **string** | `"png"` | E.g. `"png"`, `"jpeg"`, `"avif"`, etc—anything supported by [sharp](https://github.com/lovell/sharp). | | encoderOptions | **object** | `{}` | Options passed on to [sharp](https://github.com/lovell/sharp) for the given output type. | | targetWidth | **number\|null** | `null` | Width the image will be resized to. See target size note below. | | targetHeight | **number\|null** | `null` | Height the image will be resized to. | | targetFit | **string\|null** | `"inside"` | Resizing fit; typically you want `"inside"`. See the [sharp api](https://sharp.pixelplumbing.com/api-resize) for other options. | | preEncodeHook | **function\|null** | `null` | Callback for manually utilizing the [sharp](https://github.com/lovell/sharp) object with the full size map image buffer (prior to resizing). | Note that, by default, this library will create a lossless .png file at full size. This is extremely time consuming (on a fast machine it can take 3-5 seconds) and results in *huge* files (10–15 MB, 4096×4096 for a 128×128 tile map). It will also take a lot of memory to generate the initial uncompressed bitmap. To downscale the resulting image, you only need to set one of `targetWidth` or `targetHeight`; if you set one, the final image will be resized within a square by that size. So if you set one of them to `512`, a square map like [Fighting Spirit](https://liquipedia.net/starcraft/Fighting_Spirit) will end up being 512×512, and a slightly thinner map like [Invader](https://liquipedia.net/starcraft/Invader) will be 512×448. The `preEncodeHook` value can be used to manually do something with the [sharp](https://github.com/lovell/sharp) object before the image is finalized and returned. For example, here's a function that boosts the brightness of the generated images: ```js /** Converts Photoshop style levels to linear multiplier/offset values. */ function levelsToLinear(min, max) { const a = 255 / (max - min) const b = -min * a return [a, b] } await bwMapImage.renderMapImage('map.scm', { // see: https://sharp.pixelplumbing.com/api-operation#linear preEncodeHook: image => image.linear(...levelsToLinear(0, 150)) }) ``` The callback runs *prior* to resizing and compression. ### Graphics To be able to generate map images, you'll need to extract the required graphics from StarCraft. **[A copy of the required graphics can be found here](https://archive.org/details/StarCraftMapGraphics)** (18.5M), provided for convenience reasons. You can also extract them from the game files directly using a program such as [CascView](http://www.zezula.net/en/casc/main.html). The following files are needed: * all files listed in [units.js](https://github.com/ShieldBattery/bw-chk/blob/master/units.js) and [sprites.js](https://github.com/ShieldBattery/bw-chk/blob/master/sprites.js) files from [bw-chk](https://github.com/ShieldBattery/bw-chk); * for all tilesets `['badlands', 'platform', 'install', 'ashworld', 'jungle', 'desert', 'ice', 'twilight']`, all files of extension `['.cv5', '.vx4', '.vr4', '.wpe', '.vx4ex']`. All filenames should be lowercase, as that's how bw-chk expects them to be (although on case insensitive filesystems this doesn't matter). By default, the library will look for the graphics in the **~/.config/bwmapimage** directory. ## External links * [bw-chk](https://github.com/ShieldBattery/bw-chk), [jssuh](https://github.com/ShieldBattery/jssuh) and [scm-extractor](https://github.com/ShieldBattery/scm-extractor) – libraries that do most of the work * [sharp](https://github.com/lovell/sharp) – library used for final image generation * [StarCraft map graphics](https://archive.org/details/StarCraftMapGraphics) package ## License MIT license.