SGDK
A free and open development kit for the Sega Mega Drive
|
ResComp 3.95 (March 2025) Copyright Stephane Dallongeville https://github.com/Stephane-D/SGDK
ResComp is part of SGDK (aka Sega Genesis Dev Kit) so refer to SGDK licence for licensing. It allows to compile different type of resource and output them in assembly source form (GAS format).
rescomp input [output] [-noheader] [-dep <target_file>] input: the input resource file (.res) output: the asm output filename (if ommited then use input name with .s extension) -noheader: specify that we don't want to generate the header file (.h) -dep: generate dependencies file (.d) for make (experimental) <target_file> allow to specify the target filename in the .d file (not the destination of the .d file itself)
Example: rescomp resources.res outres.s rescomp resources.res outres.s -noheader -dep rescomp resources.res outres.s -dep out/res/gfx.o
Rescomp support custom resource using extensions. Making an extension is easy: just write your own resource type and its processor in Java and export compiled classes as 'rescomp_ext.jar'. Put the file in the same folder as the .res files you want to compile and rescomp should find it automatically ! You can look at the sgdk.rescomp.resource.Palette and sgdk.rescomp.processor.PaletteProcessor source files to get an example about how to implement a Resource and a Processor :)
Many resource types use image file as input and Rescomp now supports both RGB images and indexed color images :) Here're some important informations to know about how to use properly these 2 image formats:
Take a .pal file or an image as input and transform it into SGDK Palette structure. See the note above about how palette is retrieved from RGB or indexed color images. Palette is used as color input for Bitmap, Image and Sprite resources.
Syntax: PALETTE name file
name name of the output Bitmap structure file path of the input image file (BMP or PNG image) or PAL file (Paint Shop Pro palette) See the note about image format at the beginning of the file
Take an image as input and transform it into SGDK Bitmap structure. Bitmap image structure is used for the SGDK BMP (bitmap) engine, do not use it for tiled image.
Syntax: BITMAP name img_file [compression]
name name of the output Bitmap structure img_file path of the input image file (BMP or PNG image) See the note about image format at the beginning of the file compression compression type (use unpackBitmap(..) to unpack), accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast)
Take an image or TSX file as input and transform it into SGDK TileSet structure. TileSet is used as tiles source for Image, Tilemap, Map and Sprite resources. If you use a real 'tileset format' image as input (as a font) then you should set 'opt' parameter to 'NONE' to avoid removing duplicated tiles (which may exist).
Syntax: TILESET name file [compression [opt [ordering [export]]]]
name name of the output TileSet structure file path of the input file (BMP, PNG image file or TSX Tiled file) See the note about image format at the beginning of the file compression compression type (use unpackTileSet(..) to unpack), accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast) opt define the optimisation level, accepted values: 0 / NONE = no optimisation, each tile is unique 1 / ALL = ignore duplicated and flipped tile (default) 2 / DUPLICATE = ignore duplicated tile only ordering define the tile process order, accepted values: ROW = process per row (default) COLUMN = process per column export enable the tileset PNG export, accept values: 0 / FALSE = no PNG export (default) 1 / TRUE = optimized tileset is export to PNG format '<file>-tileset-export.png'
Tips: When using a 8bpp indexed image as input you can use the extra bits of palette to provide extra information for the TILEMAP data but you have to ensure that all pixels from a same tile (block of 8x8 pixels) use the same value otherwise rescomp will generate an error. bit 4-5: palette index (0-3) so it allows to use the 4 available palettes to draw the tilemap / MAP. bit 6: not used (ignored) bit 7: priority information (0=LOW 1=HIGH)
Take an image or a TMX file as input and transform it into SGDK TileMap structure. TileMap is used to draw in background plane, it requires a tileset which can be shared with others tilemaps. TILEMAP resource isn't meant to be used to store large background level (eat too much space), use MAP resource for that.
Syntax (image file input): TILEMAP name img_file tileset_id [compression [map_opt [map_base [ordering]]]]
name name of the output TileMap structure img_file path of the input image file (BMP or PNG image file) See the note about image format at the beginning of the file tileset_id base tileset resource to use (allow to share tileset along several tilemaps) compression compression type (use unpackTileMap(..) to unpack), accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast) map_opt define the tilemap optimisation level, accepted values: 0 / NONE = no optimisation, each tile is unique 1 / ALL = find duplicated and flipped tile (default) 2 / DUPLICATE = find duplicated tile only map_base define the base tilemap value, useful to set a default priority, palette and base tile index offset. using a base tile index offset (static tile allocation) allow to use the faster VDP_setTileMapxxx(..) functions. ordering define the tilemap process order, accepted values: ROW = process per row (default) COLUMN = process per column
Syntax (TMX tiled file input): TILEMAP name tmx_file layer_id [ts_compression [map_compression [map_base]]]
name name of the output TileMap structure tmx_file path of the input TMX file (TMX Tiled file with CSV encoded map data) layer_id layer name we want to extract map data from. ts_compression compression type for tileset, accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast) map_compression compression type for map (same accepted values than 'ts_compression') map_base define the base tilemap value, useful to set a default priority, palette and base tile index offset. using a base tile index offset (static tile allocation) allow to use the faster VDP_setTileMapxxx(..) functions. ordering define the tilemap process order, accepted values: ROW = process per row (default) COLUMN = process per column
Tips: When using a 8bpp indexed image as input you can use the extra bits of palette to provide extra information for the TILEMAP data but you have to ensure that all pixels from a same tile (block of 8x8 pixels) use the same value otherwise rescomp will generate an error. bit 4-5: palette index (0-3) so it allows to use the 4 available palettes to draw the tilemap / MAP. bit 6: not used (ignored) bit 7: priority information (0=LOW 1=HIGH) When using a TMX Tiled file you can define the priority information in different ways:
Take an image or TMX file as input and transform it into SGDK Map structure. Map is used to define a large background/plane data, it's different from the IMAGE resource as MAP uses an advanced encoding so it can encode large background while taking much less ROM space than IMAGE resource so use it to handle large level.
Syntax: MAP name img_file tileset_id [compression [map_base]]
name name of the output Map structure img_file path of the input image file (BMP or PNG image file) See the note about image format at the beginning of the file tileset_id base tileset resource to use (allow to share tileset along several tilemaps) compression compression type, accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast) map_base define the base tilemap value, useful to set a default priority, palette and base tile index offset. using a base tile index offset (static tile allocation) allow to use faster MAP decoding function internally.
MAP name tmx_file layer_id [ts_compression [map_compression [map_base [ordering]]]]
name name of the output Map structure tmx_file path of the input TMX file (TMX Tiled file with CSV encoded map data) layer_id layer name we want to extract map data from. ts_compression compression type for tileset, accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast) map_compression compression type for map (same accepted values than 'ts_compression') map_base define the base tilemap value, useful to set a default priority, palette and base tile index offset. using a base tile index offset (static tile allocation) allow to use faster MAP decoding function internally. ordering define the map process order, accepted values: ROW = process per row (default) COLUMN = process per column
Tips: When using a 8bpp indexed image as input you can use the extra bits of palette to provide extra information for the TILEMAP data but you have to ensure that all pixels from a same tile (block of 8x8 pixels) use the same value otherwise rescomp will generate an error. bit 4-5: palette index (0-3) so it allows to use the 4 available palettes to draw the tilemap / MAP. bit 6: not used (ignored) bit 7: priority information (0=LOW 1=HIGH) When using a TMX Tiled file you can define the priority information in different ways:
Take a TMX file as input and transform it into an array of Object (actually an array of object pointer). These objects can be used to define almost anything you want to attach to a specific MAP (entities, events, actions... whatever we can think of). Objects are built using the object layers of Tiled TMX file and since Tiled 1.8 you can define your own Object type letting you to build your own custom objects that you can import through rescomp.
Here's the accepted SGDK type(s) for each 'Tiled' type: Tiled SGDK bool bool color u32 float f32, f16, s32, u32, s16, u16 file NOT SUPPORTED int f32, f16, s32, u32, s16, u16, s8, u8 Object object (internally void*) string string (internally char*) Enum u8, u16, u32
As you can see, you can also use your own enumerations in which case you need to save them as number (not string) and make sure they perfectly match your C enums (be careful about the allocated type size for your enum, default is u32 with GCC).
The Tiled objects has some default attributes that you can use:
Syntax: OBJECTS name tmx_file layer_id field_defs [sortby:<field>] [decl_type [type_filter]]
name name of the output array Objects structure tmx_file path of the input TMX file (TMX Tiled file) layer_id object group/layer name we want to export object from. sortby field name to sort objects by. e.g. "sortby:x" to sort objects by x position. field_defs name and type of fields we want to export (also define the order of extraction) in <name>:<type> format. Field type can be any of the usual SGDK base type: u8, s8, u16, s16, u32, s32, f16, f32, bool, string, object Some examples of 'field_defs' declaration: "type:u16;name:string;x:f32;y:f32;tileindex:u32" "type:u16;power:s8;visible:bool" Note that not found fields are just ignored so you can extract different object types at same time easily. decl_type declaration type for objects (default is "void"). By default object array is untyped (void) but you can specify your own type if you want ("Object", "Entity", ...) type_filter define a type filter if we only want to extract Tiled objects of a specific type (see above).
Tips:
Take an image as input and transform it into SGDK Image structure. Image is used to directly draw image in background plane, it internally contains a Palette, TileSet and TileMap structure. IMAGE resource isn't meant to be used to store large background level (eat too much space), use MAP resource for that.
Syntax: IMAGE name img_file [compression [map_opt [map_base]]]
name name of the output Image structure img_file path of the input image file (BMP or PNG image) See the note about image format at the beginning of the file compression compression type (use unpackImage(..) to unpack), accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast) map_opt define the tilemap optimisation level, accepted values: 0 / NONE = no optimisation (each tile is unique) 1 / ALL = find duplicated and flipped tile (default) 2 / DUPLICATE = find duplicated tile only map_base define the base tilemap value, useful to set a default priority, palette and base tile index offset. Using a base tile index offset (static tile allocation) allow to use the faster VDP_xxxTileMapxxx(..) functions.
Tips: When using a 8bpp indexed image as input you can use the extra bits of palette to provide extra information for the TILEMAP data but you have to ensure that all pixels from a same tile (block of 8x8 pixels) use the same value otherwise rescomp will generate an error. bit 4-5: palette index (0-3) so it allows to use the 4 available palettes to draw the tilemap / MAP. bit 6: not used (ignored) bit 7: priority information (0=LOW 1=HIGH)
Take an image as input and transform it into SGDK SpriteDefinition structure. SpriteDefinition is used to draw, animate and manage sprites, it internally contains severals TileSet, Palette and Animation structures.
Syntax: SPRITE name img_file width height [compression [time [collision [opt_type [opt_level [opt_duplicate]]]]]]
name name of the output SpriteDefinition structure img_file path of the input image file (BMP or PNG image) See the note about image format at the beginning of the file width width of a single sprite frame in tile (should be < 32) height height of a single sprite frame in tile (should be < 32) compression compression type, accepted values: -1 / BEST / AUTO = use best compression 0 / NONE = no compression (default) 1 / APLIB = aplib library (good compression ratio but slow, don't use it for streamed sprite) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast, recommended for streamed sprite) time display frame time in 1/60 of second (time between each animation frame) If this value is set to 0 (default) then auto animation is disabled. It can be either set globally (single value) or independently for each frame of each animation. Example for 3 anim x 5 frame sprite sheet: [[3,3,3,4,4][4,5,5][2,3,3,4]] No space allowed ! And you can have empty value for empty frame. collision collision type: CIRCLE, BOX or NONE (NONE by default) opt_type sprite cutting optimization strategy, accepted values: 0 / BALANCED = balance between used tiles and hardware sprites (default) 1 / SPRITE = reduce the number of hardware sprite (using bigger sprite) at the expense of more used tiles 2 / TILE = reduce the number of tiles at the expense of more hardware sprite (using smaller sprite) 3 / NONE = no optimization (cover the whole sprite frame) opt_level optimization level for the sprite cutting operation: 0 / FAST = fast optimisation, good enough in general (default) 1 / MEDIUM = intermediate optimisation level, provide better results than FAST but ~10 time slower 2 / SLOW = advanced optimisation level using a genetic algorithm (80000 iterations), ~25 time slower than FAST 3 / MAX = maximum optimisation level, genetic algorithm (500000 iterations), ~150 time slower than FAST opt_duplicate enabled optimization of consecutive duplicated frames by removing them and increasing animation time to compensante. FALSE = no optimization (default) Note that duplicated frames pixel data are still removed by rescomp binary blob optimizer. TRUE = only the first instance of duplicated frames is kept and 'timer' value is increased to compensate the removed frames time. Note that it *does* change the 'animation.numFrame' information so beware of that when enabling this optimization.
Some informations about how SpriteDefinition is generated from the input image:
Tips: When the 'opt_level' is set (non empty value) then rescomp will automatically generate an image saved as <input_image>_opt.png representing the processed sprite cutting operation.
Take a VGM or XGM music file as input and transform it into binary format usable with the SGDK XGM_startPlay(..) methods. The XGM driver supports music play along 4 PCM channels mixing (100% running on Z80 cpu).
Syntax: XGM name file [timing [options]]
name XGM music variable name file path of the .vgm or .xgm music file to convert to binary data array timing define the XGM base timing -1 (default) = AUTO (NTSC or PAL depending the information in source VGM/XGM file) 0 = NTSC (XGM is generated for NTSC system) 1 = PAL (XGM is generated for PAL system) options optional(s) parameter(s) for xgmtool ex: "-dr -di" to disable some sample auto process (see xgmtool to get more info)
Take a VGM music file as input and transform it into binary format usable with the SGDK XGM2_play(..) or XGM2_playTrack(..) methods. The XGM2 driver supports music play along 3 PCM channels mixing (100% running on Z80 cpu) with adjustable volume (FM and PSG only).
Syntax for single track XGM: XGM2 name file [options]
name XGM2 music variable name file path of the .vgm music file to convert in compiled XGM2 file options optional(s) parameter(s) for xgm2Tool Should always start with '-' character otherwise it won't be recognized ex: "-dr -di" to disable some samples auto process (see xgm2tool to get more info)
Syntax for multi tracks XGM2 - allow PCM sharing: XGM2 name file1 [file2] [...] [options]
name XGM2 music variable name file(s) path(s) of the .vgm music file(s) to convert to compiled XGM2 file ex1: "music.vgm" ex2: "music1.vgm" "music2.vgm" ... ex3: "*.vgm\" options optional(s) parameter(s) for xgm2Tool Should always start with '-' character otherwise it won't be recognized ex: "-dr -di" to disable some samples auto process (see xgm2tool to get more info)
Take a .wav sound file as input and transform it into binary format usable with one of the SGDK PCM drivers.
Syntax: WAV name wav_file driver [out_rate [far]]
name variable name file path of the .wav file (will be automatically converted int the correct format) driver specify the Z80 driver to use: PCM / DEFAULT (0 value is not anymore accepted) Single PCM channel sound driver. It can play a sample (8 bit signed) from 8 Khz up to 32 Khz rate. Method to use: SND_PCM_startPlay(..) DPCM2 (2ADPCM and 1 are not anymore accepted) 2 PCM channels DPCM sound driver. It can mix up to 2 (4 bit) DCPM samples at a fixed 22050 Hz rate. Method to use: SND_DPCM2_startPlay(..) PCM4 (2 and 3 are not anymore accepted) 4 PCM channels sample sound driver with volume support. It can mix up to 4 samples (8 bit signed) at a fixed 16 Khz rate with 16 levels of volume. Method to use: SND_PCM4_startPlay(..) XGM (4 and 5 are not anymore accepted) XGM music sound driver. It can mix up to 4 samples (8 bit signed) at a fixed 14 Khz rate while playing XGM music. Methods to use: XGM_setPCM(..) and XGM_startPlayPCM(..) XGM2 XGM music sound driver. It can mix up to 3 samples (8 bit signed) at either 13.3 Khz or 6.65 Khz while playing XGM music. Methods to use: XGM2_playPCM(..) out_rate output PCM rate, this parameter is meaningful only for PCM and XGM2 driver. PCM driver accepts following values: 8000, 11025, 13400, 16000, 22050, 32000 (default is 16000 if omitted) XGM2 driver accepts only 6650 or 13300 (default is 13300 if omitted). far 'far' binary data flag to put it at the end of the ROM (useful for bank switch, default = TRUE)
Take any data file as input and transform it into binary data array accessible through SGDK.
Syntax: BIN name file [align [size_align [fill [compression [far]]]]]
name BIN data variable name file path of the data file to convert to binary data array align memory address alignment for generated data array (default is 2) size_align size alignment for the generated data array (default is 2) fill fill value for the size alignment (default is 0) compression compression type, accepted values: 0 / NONE = no compression 1 / APLIB = aplib library (good compression ratio but slow) 2 / FAST / LZ4W = custom lz4 compression (average compression ratio but fast) far 'far' binary data flag to put it at the end of the ROM (useful for bank switch, default = TRUE)
Align binary data for the whole resource file so you can have only ALIGN directive per resource (.res) file. ALIGN function is useful when using bank switch for ROM larger than 4MB, it allows to avoid having a block of data crossing 2 data banks. If you need several data alignments then you have to use several resources files. Note that if you omit [value] parameter by default data is aligned on 512KB as this is the bank size when using bank switch mechanism.
Syntax: ALIGN [value]
value specifies the minimum binary data alignment in bytes (default is 524288 = bank size)
By default rescomp will group data export by type of data, this generally allow better LZ4W compression. Using UNGROUP function allow to disable that feature, that might be useful to help in bank data separation when using the bank switch mechanism.
Syntax: UNGROUP
By default binary data are always exported as "FAR" data, that means they are located in the end of the ROM and can require bank switch mechanism if the ROM is larger than 4MB. Using NEAR function allow all binary data from the file to be located before all FAR data in the ROM.
Syntax: NEAR