Skip to content

Commit

Permalink
version 2.3, housekeeping languages
Browse files Browse the repository at this point in the history
  • Loading branch information
Philipp committed Oct 19, 2024
1 parent 9b1535f commit 81221e2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 80 deletions.
7 changes: 7 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,10 @@
* Small facelift of the viewer
* Fixed a bug regarding config-mode
* Fixed a bug regarding insertion of decoder and viewer

2024-10-19 Decca (Philipp)
* Version 2.3
* Detect if PIL is missing and show help with commands
* Reduced the languages to Lua and Javascript, the rest seems to be useless
* Default output mode is now raw, not config anymore
* Show also the palette in viewer
32 changes: 14 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Commandline tool to convert images to tiles, sprites or charsets for the [TIC-80
When developing a [game](https://en.wikipedia.org/wiki/Video_game) or a [demo](https://en.wikipedia.org/wiki/Demoscene), sooner or later you will need to add some nice [graphics](https://en.wikipedia.org/wiki/Pixel_art).

**TicMcTile** reads your imagefile(s) in a variety of [formats](https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html) and creates files from it, which can be run/loaded by the [TIC-80](https://tic80.com/) or your favorite [editor](https://en.wikipedia.org/wiki/Text_editor)/[ide](https://en.wikipedia.org/wiki/Integrated_development_environment).
Supported languages are: [Lua](https://www.lua.org) & [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) and basically also [Moonscript](https://moonscript.org), [Wren](https://wren.io), [Fennel](https://fennel-lang.org) and [Squirrel](http://www.squirrel-lang.org).
Supported languages are: [Lua](https://www.lua.org) & [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript).

Of course images can be loaded into the [sprite editor](https://github.com/nesbox/TIC-80/wiki#sprite-editor) by using the *import*-[command](https://github.com/nesbox/TIC-80/wiki/Console#available-commands).
But **TicMcTile** can stuff more tiles/sprites into your program, allowing you to import images as 4 or 2 color images instead of 16, thanks to a feature called [BPP (Bits Per Pixel)](https://github.com/nesbox/TIC-80/wiki/Bits-Per-Pixel). It is also possible to replace the systemfont with an own charset of the right size. All this data can additionally be compressed by using [RLE (Run-length encoding)](https://en.wikipedia.org/wiki/Run-length_encoding).
Expand All @@ -33,7 +33,7 @@ But **TicMcTile** comes to the rescue. It will convert your images (no matter if
You can convert a **singlepage**-image (128x128 or smaller) and assign it to one of the available pages, or you can use **multipage**-images. When using **4** colors, a **multipage** can be
**max. 256 pixels** wide & 128 pixels high. In case of **2** colors, a **multipage** can be **max. 512 pixels** wide & 128 pixels high. You can select whether the image(s) should be converted to tiles (default) or sprites.

Only images with **16 colors or less** are supported, for obvious reasons. These images should consist of [indexed colors](https://en.wikipedia.org/wiki/Indexed_color) or have a [color-palette](https://en.wikipedia.org/wiki/Palette_(computing)). Truecolor-images will be converted, but results may vary. Make sure, that images match the [color-palette](https://github.com/nesbox/TIC-80/wiki/palette) [(SWEETIE-16)](https://lospec.com/palette-list/sweetie-16) of the **TIC-80**. Or tell **TicMcTile** to keep (-k / --keep) the colors of your image by replacing the default ones.
Only images with **16 colors or less** are supported, for obvious reasons. These images should consist of [indexed colors](https://en.wikipedia.org/wiki/Indexed_color) resp. have a [color-palette](https://en.wikipedia.org/wiki/Palette_(computing)). Truecolor-images will be converted, but results may vary. Make sure, that images match the [color-palette](https://github.com/nesbox/TIC-80/wiki/palette) [(SWEETIE-16)](https://lospec.com/palette-list/sweetie-16) of the **TIC-80**. Or tell **TicMcTile** to keep (-k / --keep) the colors of your image by replacing the default ones.

### Charsets

Expand All @@ -49,24 +49,24 @@ To replace the **big** chars of the [systemfont](https://github.com/nesbox/TIC-8
Modes
=====

**TicMcTile** supports different modes to store the data of tiles/sprites, by default the *config*-mode is used.
The file will include some pseudo-code and at the end, palette & sprites/tiles within **XML-style tags**. This mode is only supported in the [PRO](https://nesbox.itch.io/tic80)-version of [TIC-80](https://tic80.com/), as shown in the table below. Charsets are **not** supported when using this mode. To run a file with *config*-mode, simply use: `"tic80 myscript.lua"`

When *raw*-mode is used, tiles/sprites or charsets and the palette will be saved into variables. To get this data written to memory at runtime, some extra **functions (decoders)** will be included to the file as well.
**TicMcTile** supports different modes to store the data of tiles/sprites, by default the *raw*-mode is used.
In this case, tiles/sprites or charsets and the palette will be saved into variables. To get this data written to memory at runtime, some extra **functions (decoders)** will be included to the file as well.
In case of *rle*-mode, all data will be compressed using [RLE (Run-length encoding)](https://en.wikipedia.org/wiki/Run-length_encoding) to save some space, before stored to the variables.
Note that you can have **multiple** sets of sprites/tiles or charsets and palettes when using these modes, because you can have several variables (eg. gfx1, gfx2 & pal1, pal2) to store and decode them.

As both modes write their data directly into the [RAM](https://github.com/nesbox/TIC-80/wiki/RAM) of the [TIC-80](https://tic80.com/), the [sprite editor](https://github.com/nesbox/TIC-80/wiki/Sprite-editor) will **NOT** display these sprites/tiles.
To still be able to debug them, a simple **viewer** will also be included to the file. The sources of the **viewers** can be found in the *Viewers*-directory. The **decoders** are located in the *Decoders*-directory, accordingly. They also contain a brief **description** of the **dataformat** for the variables. To run files with *raw* or *rle*-mode, use:
`tic80 --skip --fs=. --cmd="import code myscript.lua & run"`

When using the config-mode, the file will include some pseudo-code and at the end, palette & sprites/tiles within **XML-style tags**. This mode is only supported in the [PRO](https://nesbox.itch.io/tic80)-version of [TIC-80](https://tic80.com/), as shown in the table below. Charsets are **not** supported when using this mode. To run a file with *config*-mode, simply use: `"tic80 myscript.lua"`

The binary mode is just an admission for a close friend and NOT directly usable for the TIC-80.

| Mode | Description | TIC 80 | TIC 80 Pro |
| --- | --- | :---: | :---: |
| *config* | data saved as XML-style tagged config-block at end of sourc ecode | **_** | ✓ |
| *raw* | data saved as script-code and variable at beginning of source code | ✓ | ✓ |
| *rle* | data saved as script-code and variable at beginning of source code | ✓ | ✓ |
| *config* | data saved as XML-style tagged config-block at end of sourc ecode | **_** | ✓ |
| *binary* | data is saved in a standalone binary file for further usage | **-** | **-** |


Expand Down Expand Up @@ -107,9 +107,9 @@ Specify a different name for the output file:

Set a different scripting language for the output file:

$ ticmctile.py singlepage-2colors.png -l squirrel -o myownscript.nut
$ ticmctile.py singlepage-2colors.png -l js -o myownscript.js

Mind the correct file extension: .js, .fnl, .wren, .moon .nut or .lua
Mind the correct file extension: .js or .lua

Generate a sprite page instead of a tile page:

Expand Down Expand Up @@ -143,7 +143,7 @@ Encode the tiles or sprites as rle-compressed part of the code:

Replace the systemfont with a custom charset:

$ ticmctile.py ionic7x6-charset.png -o freshchars.lua -m raw -c
$ ticmctile.py ionicV5-charset.png -o freshchars.lua -m raw -c

This will replace the bigfont. To change the smallfont, set the page to 1 by adding "-p 1"

Expand All @@ -161,7 +161,7 @@ Commandline options

optional arguments:
-o, --output outputfile for tile/sprite or charset values (e.g.: .lua)
-l, --language output as: js, fennel, wren, moon or squirrel, default is lua
-l, --language output as: js, default is lua
-f, --force force overwrite of outputfile when it already exist
-s, --sprites export as sprites instead of tiles
-c, --charset export as charset to replace the systemfont
Expand All @@ -174,13 +174,11 @@ Commandline options

The optional arguments are only needed if the default setting does not meet the
required needs. A specific name for the output file (-o / --output) can be set.
The output can be in different scripting languages (-l / --language). Lua is
default, but the following languages are also supported: JavaScript, Squirrel,
Fennel, Wren and Moonscript. Dont expect too much, is just different formatting.
The language (-l / --language) for output can be Lua (default) or JavaScript.
The data can be saved as sprites (-s / --sprites) instead of tiles.
Tiles/sprites can start on a different page (-p / --page) instead of 0.
Mode (-m / --mode) to encode the tiles/sprites as part of the code as raw, rle,
as a binary-file (binary) or as part of the config, which is the default.
Mode (-m / --mode) to encode the tiles/sprites as part of the code as
raw (default), rle, as binary-file (binary) or as part of the config (config).
Replace the systemfont with a correct formated charset (-c / --charset).
To replace the smallfont choose (-p 1 / --page 1) instead of 0, which is default.
In the PRO version of TIC-80 there are up to 8 memory banks (-b / --bank)
Expand Down Expand Up @@ -219,10 +217,8 @@ Files
Future ideas
============

* Output of other languages than Lua, e.g. JavaScript - **Done**, implemented in version [1.1](https://github.com/PhilSwiss/ticmctile/tree/version1.1)
* keeping the color-palette of the image, instead of using the default palette - **Done**, implemented in version [1.2](https://github.com/PhilSwiss/ticmctile/tree/version1.2)
* Real compression of the values incl. a small decompressor for [Lua](https://www.lua.org/) - **Done**, implemented in version [2.0](https://github.com/PhilSwiss/ticmctile/tree/version2.0)
* Decompressors/Viewers for languages other than Lua or JS ♥ *Feel free*, to submit *your* contributions to this one ★


Disclaimer
Expand Down
80 changes: 18 additions & 62 deletions ticmctile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,18 @@
#
# TicMcTile - convert images to TIC-80 tiles or sprites
#
# Done:
# - resolution of image no longer has to be dividble by 8
# - different image sizes per color
# - export as tiles (BG) or sprites (FG)
# - optional page selection
# - convert RGB to Palette if neccessary
# - optional memory banks for the PRO version
# - export as JavaScript (.js) - replace "-- " with "// "
# - keep palette of original image
# - inline code feature
# - bonus: real compression
# - fixed bug: when calculating start address for pages, the amount of colors was not respected
# - fixed bug: error message for images too wide for pages greater 0 was improved
# - fixed bug: replace 2nd if with elif in the rle-encoder
# - fixed bug: append zero to rle enc-string to fix decoder-bug (flush last values)
# - removed palette-decoder: the palette-data is now working with the same decoder as the pixeldata
# - Charset-mode: eleminate the need for the big gaps between letters in the source image
# - Charset-mode: show error when the image has more than 2 colors
# - Charset-mode: when RLE is used, to many zeroes are stored at the end
# - include viewer and decoder NON-Path relative
# - write tests
# - doc: how to load files / import code
#
# ToDo (Version 3):
# - reduce languages to Lua and Javascript, the rest seems to be useless
# - default output should be raw nowadays, not config
# - lz-based compression

# import modules
from PIL import Image
# import core modules
import argparse
import os.path
import sys

# import optional modules
try:
from PIL import Image
except ImportError:
raise SystemExit('ERROR: PIL is not installed, try: python -m pip install pillow')


# replace argparse-error message with own, nicer help/usage
class ArgumentParser(argparse.ArgumentParser):
Expand All @@ -48,26 +26,24 @@ def error(self, message):
"\n"
"optional arguments:\n"
" -o, --output outputfile for tile/sprite or charset values (e.g.: .lua)\n"
" -l, --language output as: js, fennel, wren, moon or squirrel, default is lua\n"
" -l, --language output as: js, default is lua\n"
" -f, --force force overwrite of outputfile when it already exist\n"
" -s, --sprites export as sprites instead of tiles\n"
" -c, --charset export as charset to replace the systemfont\n"
" -p, --page start page (1-3) for tiles/sprites, default is 0\n"
" -m, --mode mode to encode as: raw, rle, binary, default is config\n"
" -m, --mode mode to encode as: rle, config, binary, default is raw\n"
" -b, --bank memory bank (1-7) for TIC-80 PRO version, default is 1\n"
" -k, --keep keep colors of imagefile to adjust the TIC-80 palette\n"
" -v, --version show version info\n"
" -h, --help show this help\n"
"\n"
"The optional arguments are only needed if the default setting does not meet the\n"
"required needs. A specific name for the output file (-o / --output) can be set.\n"
"The output can be in different scripting languages (-l / --language). Lua is\n"
"default, but the following languages are also supported: JavaScript, Squirrel,\n"
"Fennel, Wren and Moonscript. Dont expect too much, is just different formatting.\n"
"The language (-l / --language) for output can be Lua (default) or JavaScript.\n"
"The data can be saved as sprites (-s / --sprites) instead of tiles.\n"
"Tiles/sprites can start on a different page (-p / --page) instead of 0.\n"
"Mode (-m / --mode) to encode the tiles/sprites as part of the code as raw, rle,\n"
"as a binary-file (binary) or as part of the config, which is the default.\n"
"Mode (-m / --mode) to encode the tiles/sprites as part of the code as\n"
"raw (default), rle, as binary-file (binary) or as part of the config (config).\n"
"Replace the systemfont with a correct formated charset (-c / --charset).\n"
"To replace the smallfont choose (-p 1 / --page 1) instead of 0, which is default.\n"
"In the PRO version of TIC-80 there are up to 8 memory banks (-b / --bank)\n"
Expand Down Expand Up @@ -103,7 +79,7 @@ def error(self, message):
metavar='language',
const='lua',
default='lua',
choices=('js', 'fennel', 'wren', 'moon', 'squirrel', 'lua'),
choices=('js', 'lua'),
type=str,
nargs='?',
action='store',
Expand All @@ -128,9 +104,9 @@ def error(self, message):
help='export charset for systemfont')
parser.add_argument('-m', '--mode',
metavar='mode',
const='config',
default='config',
choices=('raw', 'rle', 'binary', 'config'),
const='raw',
default='raw',
choices=('raw', 'rle', 'config', 'binary'),
type=str,
nargs='?',
action='store',
Expand All @@ -148,7 +124,7 @@ def error(self, message):
help='keep original image colors')
parser.add_argument('-v', '--version',
action='version',
version='%(prog)s 2.2')
version='%(prog)s 2.3')
args = parser.parse_args()


Expand Down Expand Up @@ -345,31 +321,11 @@ def get_tile():


# set language specialties
if outputLang == "fennel":
outputExt = ".fnl"
outputCode = '(fn _G.TIC []\n (print (.. "' + outputMsg + '") 7 43)\n)'
outputCmnt = ";; "
outputVar = "let "
elif outputLang == "wren":
outputExt = ".wren"
outputCode = 'class Game is TIC {\n construct new() { TIC.print("' + outputMsg + '",7,43) }\n}'
outputCmnt = "// "
outputVar = "var "
elif outputLang == "squirrel":
outputExt = ".nut"
outputCode = 'function TIC() {\n print("' + outputMsg + '",7,43)\n}'
outputCmnt = "// "
outputVar = "local "
elif outputLang == "js":
if outputLang == "js":
outputExt = ".js"
outputCode = 'function TIC() {\n print("' + outputMsg + '",7,43)\n}'
outputCmnt = "// "
outputVar = "var "
elif outputLang == "moon":
outputExt = ".moon"
outputCode = 'export TIC=-> print("' + outputMsg + '",7,43)'
outputCmnt = "-- "
outputVar = "local "
else:
outputExt = ".lua"
outputCode = 'function TIC()\n print("' + outputMsg + '",7,43)\nend'
Expand Down

0 comments on commit 81221e2

Please sign in to comment.