Git Product home page Git Product logo

bmp2tile's Introduction

BMP2Tile

It’s a program that can converts BMP, PNG, PCX and GIF format images into raw or compressed 8×8 pixel separated-bitplane tile data suitable for inclusion in SMS and GG homebrew programs. At the same time, it optimises duplicate tiles, creates a tilemap to recreate the original image and converts the palette for you.

http://www.smspower.org/maxim/Software/BMP2Tile https://github.com/maxim-zhao/bmp2tile

It has a Winamp-inspired plugin interface for data compression. Source for compressors is found here:

https://github.com/maxim-zhao/bmp2tilecompressors

Instructions

FIRST you have to prepare your file in an image editor. This is the important part! There are certain requirements for it to be processed by this program. If you are using an image editor that doesn't allow you to output in the right format then you might need to get one that can convert for you. I like Paint Shop Pro 7, it can easily do what you want here.

Requirement 1

The image should have a width and height that are multiples of 8. If it's not, the program can handle that (adding padding) but it's not ideal.

Requirement 2

The image must be in one of these formats:

  • PNG
  • BMP
  • GIF

Requirement 3

The image MUST be either in 1bpp, 4bpp or 8bpp format. Higher bit depths are not acceptable. So there. The reason for this is because you (should) want to control your palette, since it will be shared among all the images you display. Your image editor should have facilities to save a palette and apply it to all the images you want to use. Since a given tile is limited to one of the two 16-colour palettes, there is no use for any higher colour depth and by removing the possibility I remove the chance of accidentally having higher indices. If you are using an 8-bit image and you use too many colours, the program will not process it. You can define colours beyond index 15, just don't use them.

So, once you've got that all sussed, save your image to a file and then drag and drop it onto the program. (Alternatively, you can find your file the old- fashioned way with the Browse button.) Then it'll load it and process it for you. Then you have some options depending on what you want...

Source tab

This will show you your image. Isn't that nice?

Tiles tab

This tab shows the tile data. It is in a suitable format to be used with WLA DX; if you use another assembler/compiler then you might need to edit it a bit.

If "Remove duplicates" is checked then identical tiles will be removed. This can save a lot of space, and is essential for full-screen graphics on the SMS.

If "Use tile mirroring" is checked then tiles which are horizontal or vertical mirror images of others will be removed. If you design your graphics with this in mind you can save a lot of graphics space.

If "Treat as 8x16" is checked then the image is decomposed in the order

  1 3 5
  2 4 6
  7 9 b
  8 a c

This is suitable for use with 8x16 sprites, for example. However, "Remove duplicates" may make the resulting data not work as expected. You probably ought to make sure the image height is a multiple of 16.

If "Planar tile output" is checked, the resulting data is bitplane-separated - each byte contains the data for one bitplane of a row of pixels. If it's unchecked, you will get "chunky" data - each byte holds all four bits for two pixels.

Enter a number in the "Index of first tile" box to have the data generated with the assumption that the first tile is not tile zero. For the tile data, this just affects the comments, but it also applies to the tilemap data (see below). To enter a hex number, prefix it with '$'.

Click on "Save" to save the tile data to a file. The available file formats depend on the plugins (see below) - but you will always be able to save the displayed text as an "inc" file. This can either be included in your source with .include "filename.inc" or simply pasted in.

Note that the program does not enforce the SMS's limitations on the number of tiles that can be defined - the SMS is practically limited to 448 (0x1c0) tiles unless you squeeze some into unused tilemap/sprite table space, and you'll have to do that manually.

Tilemap tab

This tab shows the tilemap data. It is also in WLA DX's data format. If your tiles are sprites then you don't want this.

"Save" does much the same as before.

Palette tab

This tab reads in the palette from the bitmap and attempts to convert it to data suitable for you to use. It's tricky because there are different ways to represent the SMS's 4-bit colour with a 24-bit colour system (as used in BMP files' palettes). I've kludged it to work OK according to the colours used in Meka (both palette types) and eSMS but I recommend you use the bright Meka palette (colour values 0, 85, 170, 255) just because I prefer it.

At the top you're shown the current palette. This is extracted from your image, rather than recreated from the converted data, but that shouldn't matter.

There are a few options for the text output. If you want plain hex values then choose "Output hex (SMS)". If you choose "Output cl123 (SMS)" then you can include the "colours.inc" file in your project to define the constants used; it makes it easier to tell what colour each value represents (see colours.inc for more description).

There's also an option to "Output hex (GG)" which will output 12-bit Game Gear palette data. This one doesn't attempt to handle different palette systems, it just shifts colours to their high 4 bits so you'd better make sure white is 255, 255,255.

The option "Always emit 16 colours" toggles between emitting only as many colours as are used (possibly including unused ones in the middle, but omitting unused ones with higher indexes than any that are used in the image) and emitting a full 16 colour palette (if you want it to emit the full palette regardless of what's actually used).

"Save" works again, but there are no plugins any more.

Plugins

For saving tile and tilemap data, plugins are used. These are DLL files found in the same directory as the program, with filenames starting with "gfxcomp_".

Each plugin must define a unique file extension for its data. (Double extensions don't work.) This allows the commandline mode (see below) to infer the plugin to use. It also helps to have it define a reasonable name for itself. Plugins can be tiles-only, tilemap-only or both.

If you want to write a plugin, make a DLL with the right filename that exports these functions (with cdecl calling convention, which is the default for most C/C++ DLLs):

extern "C" __declspec(dllexport) const char* getName()

Returns a null-terminated string giving the name of the format, for display.

extern "C" __declspec(dllexport) const char* getExt()

Returns a null-terminated file extension (without any preceding dot) that is used to build filename masks and to tell which plugin to use in commandline mode.

extern "C" __declspec(dllexport) int compressTiles(const uint8_t* pSource, const uint32_t numTiles, uint8_t* pDestination, const uint32_t destinationLength)

Compresses the tile data from pSource to pDestination. Each tile is 32 bytes. If destinationLength is too small, you must return 0. If there is an error while compressing (perhaps the tile data does not conform to some restriction), return -1. Else return the number of bytes inserted into the buffer.

extern "C" __declspec(dllexport) int compressTilemap(const uint8_t* pSource, const uint32_t width, const uint32_t height, uint8_t* pDestination, const uint32_t destinationLength)

Compresses the tilemap data from pSource to pDestination. Each tilemap entry is 2 bytes in little-endian order. If destinationLength is too small, you must return 0. If there is an error (perhaps some restriction on the data), return -1. Else return the number of bytes inserted into the buffer.

You can support one or both compress* functions.

Commandline mode

Pass the following on the commandline to make the corresponding option/action choices. Defaults are marked with ⭐.

Command switch Effect
<filename> Load the specified bitmap. Note that the format restrictions are the same as before.
-removedupes ⭐ Optimise out duplicate tiles
-noremovedupes Or don't
-mirror ⭐ Use tile mirroring to further optimise duplicates
-nomirror Or don't
-8x8 ⭐ Treat tile data as 8x8
-8x16 Treat tile data as 8x16
-planar ⭐ Output planar tile data
-chunky Output chunky tile data
-tileoffset <n> The starting index of the first tile. ⭐ Default is 0.
-spritepalette Set the tilemap bit to make tiles use the sprite palette. ⭐ Default is unset.
-infrontofsprites Set the tilemap bit to make tiles appear in front of sprites. ⭐ Default is unset.
-palsms ⭐ Output the palette in SMS colour format
-palgg Output the palette in GG colour format
-palcl123 Output the palette in SMS colour format, using constants of the form cl123 (see above).
-fullpalette Output 16 colours rather than as many as are present in the image.
-savetiles <filename> Save tile data to <filename>. The format will be inferred from the extension of <filename>.
-savetilemap <filename> Save tilemap data to <filename>. The format will be inferred from the extension of <filename>.
-savepalette <filename> Save palette data to <filename>. The format will be inferred from the extension of <filename>.

Note that options are interpreted sequentially. That means you should specify any options (and the input file) before any -save* actions. It also you can chain together operations, as so:

bmp2tile.exe foo.png -savetiles "foo.tiles.zx7" -savetiles "foo.tiles.bin" -savetilemap "fool.tilemap.withmirroring.zx7" -nomirror -savetilemap "fool.tilemap.nomirroring.zx7"

Source

https://github.com/maxim-zhao/bmp2tile

BMP2Tile started life in Delphi 7, but as of version 0.5 became written in C#. Most of the plugins are written in C++.

History

0.61

  • Fixed bug in GUI regarding palette format controls

0.6

  • Support reading "raw" data as the input image (SMS/GG raw tile data, .bin extension)
  • Print time taken to console
  • Support 32-colour images (provided they fit in the dual-palette limitations of SMS/GG)
  • Avoid holding image file handles open
  • Fixed planar mode checkbox
  • Bundling tile compression DLLs
  • Show help in commandline mode

0.5

  • Rewrite to C#. Commandline mode is now much faster and operates sequentially.

0.44

  • Palette preview now shows you the result of mapping to the SMS or GG palette

0.43

  • Fixed a stupid bug which meant tilemap width and height were swapped when compressing

0.42

  • Option to always emit 16 colours

0.41

  • Fixed the broken tilemap modifications (flags and offsets) when saving as non-text

0.4

  • Rewrote the tile/tilemap code, it's much faster now
  • Added plugin support
  • Removed 1/2/3bpp output support, plugins can do that now

0.35

  • Fixed a stupid bug with 8-bit images
  • Modified demo to use more varied source images to help with testing
  • Included source that got left out of 0.34

0.34

  • Relaxed image size restrictions as far as possible
  • Added some checking of formats when saving to avoid nonsensical option combinations
  • Added more decompressor code and demos

0.33

  • The Load button is now a Browse button and gives you a normal Windows Open dialogue

0.32

  • Added support for 8-bit images (using only the first 16 palette entries)
  • Added support for more image formats (GIF, PNG, PCX)
  • Fixed some bugs when loading a second image
  • Fixed some bugs with 1-bit images

0.31

  • Added a missing commandline switch
  • Added optional output filename specification
  • Fixed a bug in the palette convertor
  • Added a demo of all the output formats

0.3

  • Added binary and Phantasy Star compressed output
  • Added commandline mode

0.22

  • Vertical mirroring above 1bpp was broken; now it isn't.

0.21

  • Fixed a few glitches

0.2

  • Added palette decoding
  • Added tile mirroring optimisation
  • Smoothed out the rough edges a bit more

0.1

  • Initial release

Dedication

To my beautiful wife :)

bmp2tile's People

Contributors

maxim-zhao avatar sverx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

sverx mguler

bmp2tile's Issues

add -h for brief help

Command line utility does not display any help. Also the only way to find out what extension you need is looking into the compressors repo readme, that is not very handy. I suggest to add -h command line switch that displays help for the tool itself, and also query each plugin for the specific options/extension lists.

swap the palettes in image

as the 'use sprite palette' checkbox is useless with images that use both palettes, why don't make it work as a 'palette swap' option so that it will map first palette to sprites on hardware (instead of standard second palette)?
Probably it's just a change from ORing the use sprite palette bit to XORing it...

Can't load plugins (in Wine)

I'm checking how this works under Linux (with Wine).
The program starts, looks good, can load images, does convert them fine.
When you press 'save' though, on Tiles or Tilemap tab, you can only choose 'Include files (*.inc)' type, which I believe means that the program didn't load any of the plugins (DLLs) are present in his directory.

Any idea how to fix that?
Thanks!

BMP2Tile 0.5 "Unsupported bitmap format Format32bppArgb"...

... but source PNG image is 16 color indexed, using 3 colors only, and I can convert it with no problem using BMP2Tile 0.44 (well, palette is kind of weird there, it is .db $00 $00 $00 $00 $00 $3F $3F $3F $3F $3F $03)

here's the image (a single 8x8 tile)
sprite

Palette image doesn't reflect what's in the saved data

Let's start saying I'm not really fond of this:
https://github.com/maxim-zhao/bmp2tile/blob/master/source/Unit1.pas#L785
but I understand why it's there.

The problem is that the colors in the palette tab are the original color from the image, not the colors that you're going to save in your data. As an example:

image

the 14th color (pink) turns white ($3f) but still appears pink up there. Probably updating the colors according to the generated data would help? I'm not really sure on how to workaround this tbh. :/

Reading Color from Image Palette instead Of from Color Usage

I've create a 4bpp image with this Palette using Grpahic Gale FreeEdition:
graphicgale
Lasts 9 colors are unused, but i need them for share with other tiles...

When I use Bitmap2Tile the palette is reading from color usage instead of Internal Image Palette:
captura
So the generated Palette isn't the same as the image have.

width and height swapped when calling the CompressTilemap plug-in function

I'm working on the plug-in for the updated STMcompr format (that would just be the same with a 1-byte header containing the width of the tilemap) and I spent a few minutes wondering why I couldn't get the correct width of the tilemap in my STM compressor plugin.
Here's why:

CompressTilemap(PByteArray(tilemap), tilemapheight, tilemapwidth, plugins[i].CompressTilemap, filename);

now I'm wondering if you're going to fix it or should I use height instead? (I bet the other compressors doesn't use this anyway so you won't break them, right?)

problem with a dual-palette image

I created two separate 16 colors images, latest BMP2Tile can process them correctly.

p1:
p1

p2:
p2

but once I create a single image joining the two parts:
p

BMP2Tile complains
Error: Image uses colors from both palettes
though the image is technically correct. ☹️

BMP2TileGUI.exe exports a SMS (6-bit RGB) palette even when GG (12-bit RGB) is selected

How to reproduce the issue:

  • Open a valid input image in BMP2TileGUI.exe
  • Go to the "Palette" tab
  • Select "GG (12-bit RGB)"
  • Notice that the text output is a 12-bit RGB palette
  • Click "Save" and save the palette as an inc file

Open the inc file and notice that the output is a 6-bit RGB palette.
This palette is sadly unusable for Game Gear homebrew.

Notes:

  • Also affects palettes saved as raw bin files.
  • This issue is not present in the command line version. Where adding the parameter -ggpalette successfully outputs a file that can be loaded as-is on Game Gear.

Export to a binary file

To make it easier to implement support in PC viewers like the RECOIL library, it would be ideal to have a standardised binary format for the SMS images and export images on this format.

It can be very a simple VRAM dump, so support can be easily implemented on emulators too. And the format allows easy binary inclusion for game development. The INCBIN would only have to skip the header and the VDP registers tail.

Here goes a humble proposal:

  1. Header (6 bytes signature):
    1.1) Signature
  • "MSBMP" string for the SMS
  • "GGBMP" string for the GG
  • "TMBMP" string for the TMS9918 (SG-1000, ColecoVision, MSX1, TI-99A, etc)
    1.2) Version (1 byte): 0 = v1.0
    1.3) File offset to the metatada area (1 byte): 9
    1.4) File offset to the data area (16bit, little endian)
  1. Metadata area (if no metadata is present, must contain only the end marker)
    2.1) Author name: ASCII text, ends with 0Dh,0Ah
    2.2) Title: ASCII text, ends with 0Dh,0Ah
    2.3) Notes: ASCII text (might be empty)
    2.4) End of the metadata marker: 1Ah (mandatory)
  2. Data area
    3.1) VDP registers dump: 10h bytes (SG-1000 uses only the first 7. Fill the unused bytes with zeroes)
    3.2) CRAM dump: 64 bytes (SMS uses only the first 32, SG-1000 uses none. Fill the unused bytes with zeroes)
    3.3) VRAM dump: 16384 bytes with a raw VRAM dump

The file extension could be .SBM, meaning "Sega Bitmap".

... a checkbox to keep 4bpp images palette untouched

As the title said, a checkbox that makes a 4bpp palette stay as it is, even if unused colors are present in the image, would be very handy.
I guess adding another 'if' after
if tilesColumn.PixelFormat=pf4bit then
which simply does
h=15
if the said checkbox is checked should be everything needed.
Thanks!

export a tilemap from an image using an existing tileset (feature request)

Since I don't think this is currently possible I marked this as a 'feature request'.
I would love if BMP2Tile could accept an image and an uncompressed binary tileset and generate the tilemap for the image using the provided tileset. Using this, one would be able to generate more images from the same shared tileset.

Support for up to 32 simultaneous colors

The Sega Master System supports up to 32 simultaneous colors for the background, but bmp2tile currently artificially restricts it to only 16.

It would be nice to have support for 32 simultaneous colors.

Plugins not recognized

I don't know why, but since today I cannot build my project because bmp2tile.exe don't recognized compressors from dll.

I get the message below :

...\bmp2tile-0.61\gfxcomp_psgaiden.dll but found no compressors

The only things I have done since the last successful build is : Update Windows 10 x)

I don't understand what's going on it seems that the loading dll is not found

"Blank" tile ignoring

If I have multiple tilesets to be used at the same time, I may want to have a "blank" tile that they all share, so I can use arbitrary layouts. Adding a blank row at the top of the images can ensure that it is the first one. An option to discard this tile would allow the tiles to avoid duplicating it; an option to substitute it with another index would allow the tilemap to be correct for any blank tiles encountered.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.