TileMod v1.00b3
(c)2000 Jay
---------------

Table of content
----------------
(1) Disclaimer
(2) System requirments
(3) What's New
(4) Introduction
(5) Getting Started
(6) Extensions
 (6.1) Export functions
 (6.2) Import functions
 (6.3) Writing Extensions with DJGPP
 (6.4) Linking Extensions and Loading them

(1) Disclaimer
--------------

I am not responsible for anything that happens to your computer by using
this program. USE AT YOUR OWN RISK.

(2) System Requirments
----------------------

386 or better CPU
6MB of RAM
VGA Card
Mouse

(3) What's New
--------------
v1.00b3
* Fixed ZST palette loading bug.

v1.00b2
* This is the first released version.

v1.00b1
v0.50b
* Not released

(4) Introduction
----------------

TileMod is a SNES tile editor. The objective of this project is to
design an editor compatible with various graphics encoding formats.
Ofcourse, it is pretty much impossible to do every single format out
there. The idea is to build a base editor and allow users to program
extensions to extend the ability of the editor. So this is pretty much
not just specific to the SNES since you can extend it to view other
formats.

(5) Getting Started
-------------------

To run the editor, either double click and or drag a file onto the exe.
If you double click it, a file selector will pop up for you to select
the file.

Keys:
^^^^^
ESC	- Exit the program
1	- 1BPP Mode
2	- 2BPP Mode
3	- 4BPP Mode
4	- 8BPP Mode
5	- Mode7
6	- User extension
7	- User extension
8	- User extension
9	- User extension
0	- User extension
Up	- Scroll up one line
Down	- Scroll down one line
Left	- Scroll left one tile
Right	- Scroll right one character
PgUp	- Scroll up one page
PgDn	- Scroll down one page
+	- Increment offset
-	- Decrement offset
]	- Increment height
[	- Decrement height
'	- Rotate Palette R by 16
;	- Rotate Palette L by 16
<	- Decrement columns
>	- Increment columns

* It is possible for user extensions to install key's themselve, so
  be sure to check the help screen.

Selecting palette colour
^^^^^^^^^^^^^^^^^^^^^^^^
You may select a palette colour by left or right clicking on the
palette to select the forground or background colour. Then you may
edit the pixels in the canvas.

Selecting Data
^^^^^^^^^^^^^^
Click on a tile and it'll get selected to the canvas. To copy the tile
in the canvas back to the rom, click on the 'Edit' button to store it
to the last place clicked (highlighted with a box).

Jumping to a new offset
^^^^^^^^^^^^^^^^^^^^^^^
Click on the 1st button in the bottom left hand corner. A dialog will
prompt you to enter the address of the new location (in hex) to goto.

Save changes
^^^^^^^^^^^^
Click on the 2 button, to save changes. You'll be prompted to save
changes.

Palettes
^^^^^^^^
You can import and export palettes in the program. Instead of creating
a new palette format, I made this program allow importing of 5
different palette formats, and exporting 4 formats. The 5 import
formats are as follows:

15-bit BGR SNES CG-Palette format (extension *.cg)
24-bit RGB RAW format (*.pal)
MsRIFF RGB Format (*.pal)
TLayer 16-colour 18-Bit RGB Format (*.pal)
ZSNES Save State (*.zsX)

Alright, this program can only detect these formats by their extensions.
So if you got a *.cg extension, the program assumes 15-bit BGR format.
As for *.pal extensions, the program determines which to load as follows:
1) If there is a RIFF header, load as MS-RIFF format
2) If the file size is 48 bytes, load as TLayer palette
3) otherwise, load as 24-bit RGB RAW

Exporting palette can be in the above formats except for zsnes saves.
It is highly suggested that future tile editors use the 15-bit BGR SNES
CG-Palette format, since it IS the SNES internal format.

(6) Extensions
--------------

This is pretty much the only section that really requires documenting!
Anyways, an extension is very much like a DLL except it is more specific
to TileMod. Extensions can only be created with COFF object generating
compilers such as DJGPP. (BTW, this is not the MS-COFF object files).
So what do extensions do? It just extends the capabilites of the editor.

(6.1) Export functions
----------------------
Anyways, every TileMod extensions contain a set of functions that must
be exported to the editor itself. The exported functions must be listed
in a structure defined in ext.h
The structure is listed as follows:

typedef struct __external_EXPORTSTRUC
{
	void (*Entry)(); 
	void (*Update)();
	void (*GetEdit)(int ,int ,unsigned char *);
	void (*SetEdit)(unsigned char *);

	int  (*GetWidth)();
	int  (*GetHeight)();
	int  (*GetColumns)();
	int  (*GetRows)();

	int  (*GetCharSize)();
	int  (*GetRowSize)();
	int  (*GetPageSize)();

	void (*SetWidth)(int);
	void (*SetHeight)(int);
	void (*SetColumns)(int);
	void (*SetRows)(int);

	int  BytesPerPixel;
	int  MaxPaletteIndex;
	const char *modestring;
	const char **help;

	int  (*GetEditWidth)();
	int  (*GetEditHeight)();

	unsigned char key1;
	unsigned char key2;
	unsigned char key3;
	unsigned char key4;
	void (*KeyHandler1)();
	void (*KeyHandler2)();
	void (*KeyHandler3)();
	void (*KeyHandler4)();
} EXPORTSTRUC;

You must define a function for each of the fields above and store them in
a struct named '_export'. The description of each field is as follows:

void (*Entry)(); 
^^^^^^^^^^^^^^^^
This is the entry point of your program. You should place startup
code here since it is called when your extension is loaded.

void (*Update)();
^^^^^^^^^^^^^^^^^
This is the most important function. This function gets called every
frame. You should write the main code for drawing the tiles here.

void (*GetEdit)(int x,int y,unsigned char *buffer);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This function is called when the user clicks the mouse over a tile.
The mouse coordinates of x and y are passed. You should process
the click by grabbing the data of the tile that was clicked,
converting it to pixels and store it to the edit canvas buffer which is
passed in the 3rd parameter. The edit canvas buffer is a 16x16 buffer
ranging in 256 bytes in length. To compute the coordinates of a pixel
in the buffer, you should use the formula: y * 16 + x.
The user should also store the location of where the user clicked in this
function in preparation to process the SetEdit function.

void (*SetEdit)(unsigned char *buffer);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This function is called when the user clicks on the 'EDIT' button. You
should process this function by translating the content of the edit
canvas buffer into tile data.

int  (*GetWidth)();
int  (*GetHeight)();
^^^^^^^^^^^^^^^^^^^^
These function should return the width or height of the current tile mode.
TileMod uses these functions to perform a few calculations. Do NOT return
0! Return aleast 1.

int  (*GetColumns)();
int  (*GetRows)();
^^^^^^^^^^^^^^^^^^^^^
These functions should return how many columns and rows are there
currently in your mode.

int  (*GetCharSize)();
int  (*GetRowSize)();
int  (*GetPageSize)();
^^^^^^^^^^^^^^^^^^^^^^
These functions should return a character, row, or page size in bytes.
GetCharSize() should return the size of one tile. Usually computed by
BitsPerPixel * tileheight. GetRowSize should return the size of one
row of tiles. Usually computed by BitsPerPixel * tileheight * columns.
GetPageSize() returns the size of one page of tiles usually computed
with BitsPerPixel * tileheight * columns * rows.
These function are called during scrolling to check how many bytes to
increment the offset.

void (*SetWidth)(int);
void (*SetHeight)(int);
void (*SetColumns)(int);
void (*SetRows)(int);
^^^^^^^^^^^^^^^^^^^^^^^^
These functions sets the width, height, columns, and rows of the current
mode. The processing of these functions are optional. If you choose not
to process these function, then make sure you store a proceedure that
does nothing in this field.

int  BitsPerPixel;
^^^^^^^^^^^^^^^^^^^
This variable is not used by TileMod. But you should store the numbers
of bits per pixel here anyways for future use.

int  MaxPaletteIndex;
^^^^^^^^^^^^^^^^^^^^^
This variable specifies the maximum palette index the user can select in
this mode. Eg. specifing 15 will allow the user to choose a colour from
0 - 15.

const char *modestring;
^^^^^^^^^^^^^^^^^^^^^^^
This variable stores the string of a short description of the current
mode.

const char **help;
^^^^^^^^^^^^^^^^^^
Pointer to an array pointing to help pages. To create a help page which
will be displayed when the user clicks on the help button, you must
create an array of strings where each string points to one page of help.
The array must contain NumberOfPages + 1 entries where the last entry
must be terminated with a NULL.
For eg.
const char *HelpPage[] =
{
	/* page 1 */

	"Jay's help manual\n"
	"-----------------\n"
	"Press 1 to select 1BPP mode\n"
	"Press right to go to next page",

	/* page 2 */

	"Press left to go to prev page\n",

	/* Terminate with NULL */

	NULL
};

int  (*GetEditWidth)();
int  (*GetEditHeight)();
^^^^^^^^^^^^^^^^^^^^^^^^
These functions returns the edit canvas width and height. Called by the
editor to determine the width and height of the canvas.

unsigned char key1;
unsigned char key2;
unsigned char key3;
unsigned char key4;
void (*KeyHandler1)();
void (*KeyHandler2)();
void (*KeyHandler3)();
void (*KeyHandler4)();
^^^^^^^^^^^^^^^^^^^^^^
Thes are KeyHook functions. That means, it allows you to install up to
4 handlers for 4 keys. Specify in the key1, key2, key3, and key4 fields
the keys you want to trap. KeyHandler1, 2, 3, or 4 will be called if that
key is pressed. Check key.h for a list of scan codes for the keys.
Store NULL in these fields if you do not process them.

(6.2) Import functions
----------------------
There is one problem with writing extensions. Unfortunaltly, since DJGPP
isn't really built for dynamic link support, linking with the C library
does cause some problems. Until I figure out all the internal details,
NO C LIBRARY LINKAGE! Due to this, all extensions imports a few useful
functions and variables that you can use instead.
The imports are as follows:

unsigned char *__rom;
^^^^^^^^^^^^^^^^^^^^^
This is a pointer to the ROM data in memory. Hey, if you're gonna make
changes to the rom, then you'll need to use this.

unsigned char *__video;
^^^^^^^^^^^^^^^^^^^^^^^
Direct access to TileMod's double buffer. This buffer is 64000 bytes
long. To place a pixel directly to the screen, use the formula:
y * 320 + x
Programmers should only draw in the regions of (0,0,128,160).
 
unsigned char *__scratch;
^^^^^^^^^^^^^^^^^^^^^^^^^
64000 bytes of temporary memory. You may use this buffer for temporary
data storage. DO NOT USE THIS BUFFER FOR LONG TERM STORAGE. The contents
of the buffer will be destroyed through TileMod function calls. This
buffer will be valid within your function given that you don't make any
calls to TileMod import functions.

int __offset; 
^^^^^^^^^^^^^^
The current offset in the rom.

const char *__help;
^^^^^^^^^^^^^^^^^^^
Points to the default help page of the program. Only used for chaining
the default page with a custom page of your own.

void * AllocMemory(unsigned size);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Allocates memory of a given size from the heap and returns a pointer to
the memory. The user does not need to check for NULL in case there isn't
enough memory since the editor will crash if that ever happens.

void * ReAllocMemory(void *ptr,unsigned size);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Resizes a memory block given by 'ptr' to size 'size'. The resized block
is returned. Again, there is no need to check for NULL.

void FreeMemory(void *ptr);
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Free's a block of memory. Always free an allocated block of memory when
not needed.

void * MemoryCopy(void *dest,const void *src,unsigned int len);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the same as memcpy(). It copies data from 'src' to 'dest' for
'len' bytes.

void * MemoryFill(void *src,int c,unsigned int len);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the same as memset(). It fills the buffer 'src' with 'c' for
'len' bytes.

char * StringCopy(char *dest,const char *src);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the same as strcpy(). This function copys the string from 'src'
to 'dest'.

int    StringCompare(const char *a,const char *b);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the same as strcmp(). It compares the string 'a' and 'b'.
Returns 0 if the 2 strings are equal, a negative number if 'a' < 'b',
or positive if 'a' > 'b'.

int sprintf(char *buf,const char *format,...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Prints to a string with formating. See *libc docs for more info on this
function.

void WriteString(const char *text,int x,int y);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Writes a string to the screen with the coordinates (x,y).

void WriteStringF(const char *format,int x,int y,...);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The same as WriteString() but allows printf like formating.
eg.
int value;
WriteStringF("value = %d",0,0,value);

void Pixel(int x,int y);
^^^^^^^^^^^^^^^^^^^^^^^^
Draws a pixel to the screen. The colour is determined by SetColor().

void Line(int x1,int y1,int x2,int y2);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Draws a line from (x1,y1) -> (x2,y2).

void Rect(int x,int y,int width,int height);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Draws a rectangle.

void FillRect(int x,int y,int width,int height);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Draws a filled rectangle.

void SetColor(int R,int G,int B);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sets the current colour for the drawing functions. You must specify a
8-bit RGB value. Due to the fact that the editor runs in a 256-color
mode, the colour you specify is infact matched with the closest colour in
the palette.

(6.3) Writing Extensions with DJGPP
-----------------------------------

Well, can't describe much in this section except that you must include
"ext.h" in your header file and nothing more. Declare all your variables
and functions with 'static'. Please see ext16x16.c for an example and
template.c to get you started.
To compile:
gcc -c yourfile.c

(6.4) Linking Extensions and Loading them
-----------------------------------------

Warning: This extension engine is quite in it's early stages of
development. Don't be surprised if your extension crashes! But report
bug anyways.
Warning: Since the extension engine is still being worked on, do not
expect BACKWARDS compatibility for future versions of this engine.

The program ldex.exe takes in a COFF-Object file and converts it into
an *.ext file. To run it type:
ldex output.ext input.o

The extlist.txt is a list of extensions. Up to 5 extensions can be
installed at one time. The first filename in the list is loaded to slot
6 (by pressing 6 while in the editor will run this extension).
The next in 7, 8, 9, and 0 repectively.