862 lines
83 KiB
C
862 lines
83 KiB
C
// MIT License
|
|
|
|
// Copyright (c) 2017 Vadim Grigoruk @nesbox // grigoruk@gmail.com
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
// SOFTWARE.
|
|
|
|
#pragma once
|
|
|
|
#include "tic.h"
|
|
#include "time.h"
|
|
|
|
// convenience macros to loop languages
|
|
#define FOR_EACH_LANG(ln) for (tic_script_config** conf = Languages ; *conf != NULL; conf++ ) { tic_script_config* ln = *conf;
|
|
#define FOR_EACH_LANG_END }
|
|
|
|
|
|
typedef struct { u8 index; tic_flip flip; tic_rotate rotate; } RemapResult;
|
|
typedef void(*RemapFunc)(void*, s32 x, s32 y, RemapResult* result);
|
|
|
|
typedef void(*TraceOutput)(void*, const char*, u8 color);
|
|
typedef void(*ErrorOutput)(void*, const char*);
|
|
typedef void(*ExitCallback)(void*);
|
|
|
|
typedef struct
|
|
{
|
|
TraceOutput trace;
|
|
ErrorOutput error;
|
|
ExitCallback exit;
|
|
|
|
clock_t start;
|
|
|
|
void* data;
|
|
} tic_tick_data;
|
|
|
|
typedef struct tic_mem tic_mem;
|
|
typedef void(*tic_tick)(tic_mem* memory);
|
|
typedef void(*tic_boot)(tic_mem* memory);
|
|
typedef void(*tic_scanline)(tic_mem* memory, s32 row, void* data);
|
|
typedef void(*tic_border)(tic_mem* memory, s32 row, void* data);
|
|
typedef void(*tic_gamemenu)(tic_mem* memory, s32 index, void* data);
|
|
|
|
typedef struct
|
|
{
|
|
const char* pos;
|
|
s32 size;
|
|
} tic_outline_item;
|
|
|
|
typedef struct
|
|
{
|
|
tic_scanline scanline;
|
|
tic_border border;
|
|
tic_gamemenu menu;
|
|
void* data;
|
|
} tic_blit_callback;
|
|
|
|
typedef struct
|
|
{
|
|
u8 id;
|
|
const char* name;
|
|
const char* fileExtension;
|
|
const char* projectComment;
|
|
struct
|
|
{
|
|
bool(*init)(tic_mem* memory, const char* code);
|
|
void(*close)(tic_mem* memory);
|
|
|
|
tic_tick tick;
|
|
tic_boot boot;
|
|
tic_blit_callback callback;
|
|
};
|
|
|
|
const tic_outline_item* (*getOutline)(const char* code, s32* size);
|
|
void (*eval)(tic_mem* tic, const char* code);
|
|
|
|
const char* blockCommentStart;
|
|
const char* blockCommentEnd;
|
|
const char* blockCommentStart2;
|
|
const char* blockCommentEnd2;
|
|
const char* blockStringStart;
|
|
const char* blockStringEnd;
|
|
const char* singleComment;
|
|
const char* blockEnd;
|
|
|
|
const char* const * keywords;
|
|
s32 keywordsCount;
|
|
} tic_script_config;
|
|
|
|
extern tic_script_config* Languages[];
|
|
|
|
typedef enum
|
|
{
|
|
tic_tiles_texture,
|
|
tic_map_texture,
|
|
tic_vbank_texture,
|
|
} tic_texture_src;
|
|
|
|
typedef struct
|
|
{
|
|
s32 x, y;
|
|
} tic_point;
|
|
|
|
typedef struct
|
|
{
|
|
s32 x, y, w, h;
|
|
} tic_rect;
|
|
|
|
// SYNC DEFINITION TABLE
|
|
// .--------------------------------- - - -
|
|
// | CART | RAM | INDEX
|
|
// |---------+---------------+------- - - -
|
|
// | | |
|
|
#define TIC_SYNC_LIST(macro) \
|
|
macro(tiles, tiles, 0) \
|
|
macro(sprites, sprites, 1) \
|
|
macro(map, map, 2) \
|
|
macro(sfx, sfx, 3) \
|
|
macro(music, music, 4) \
|
|
macro(palette, vram.palette, 5) \
|
|
macro(flags, flags, 6) \
|
|
macro(screen, vram.screen, 7)
|
|
|
|
enum
|
|
{
|
|
#define TIC_SYNC_DEF(NAME, _, INDEX) tic_sync_##NAME = 1 << INDEX,
|
|
TIC_SYNC_LIST(TIC_SYNC_DEF)
|
|
#undef TIC_SYNC_DEF
|
|
};
|
|
|
|
#define TIC_FN "TIC"
|
|
#define BOOT_FN "BOOT"
|
|
#define SCN_FN "SCN"
|
|
#define OVR_FN "OVR" // deprecated since v1.0
|
|
#define BDR_FN "BDR"
|
|
#define MENU_FN "MENU"
|
|
|
|
#define TIC_CALLBACK_LIST(macro) \
|
|
macro(TIC, TIC_FN "()", "Main function. It's called at " DEF2STR(TIC80_FRAMERATE) \
|
|
"fps (" DEF2STR(TIC80_FRAMERATE) " times every second).") \
|
|
macro(BOOT, BOOT_FN, "Startup function.") \
|
|
macro(MENU, MENU_FN "(index)", "Game Menu handler.") \
|
|
macro(SCN, SCN_FN "(row)", "Allows you to execute code between the drawing of each scanline, " \
|
|
"for example, to manipulate the palette.") \
|
|
macro(BDR, BDR_FN "(row)", "Allows you to execute code between the drawing of each fullscreen scanline, " \
|
|
"for example, to manipulate the palette.")
|
|
|
|
// API DEFINITION TABLE
|
|
// macro
|
|
// (
|
|
// definition
|
|
// help
|
|
// parameters count
|
|
// required parameters count
|
|
// callback?
|
|
// return type
|
|
// function parameters
|
|
// )
|
|
|
|
#define TIC_API_LIST(macro) \
|
|
macro(print, \
|
|
"print(text x=0 y=0 color=15 fixed=false scale=1 smallfont=false) -> width", \
|
|
\
|
|
"This will simply print text to the screen using the font defined in config.\n" \
|
|
"When set to true, the fixed width option ensures that each character " \
|
|
"will be printed in a `box` of the same size, " \
|
|
"so the character `i` will occupy the same width as the character `w` for example.\n" \
|
|
"When fixed width is false, there will be a single space between each character.\n" \
|
|
"\nTips:\n" \
|
|
"- To use a custom rastered font, check out `font()`.\n" \
|
|
"- To print to the console, check out `trace()`.", \
|
|
7, \
|
|
1, \
|
|
0, \
|
|
s32, \
|
|
tic_mem*, const char* text, s32 x, s32 y, u8 color, bool fixed, s32 scale, bool alt) \
|
|
\
|
|
\
|
|
macro(cls, \
|
|
"cls(color=0)", \
|
|
\
|
|
"Clear the screen.\n" \
|
|
"When called this function clear all the screen using the color passed as argument.\n" \
|
|
"If no parameter is passed first color (0) is used.", \
|
|
1, \
|
|
0, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, u8 color) \
|
|
\
|
|
\
|
|
macro(pix, \
|
|
"pix(x y color)\npix(x y) -> color", \
|
|
\
|
|
"This function can read or write pixel color values.\n" \
|
|
"When called with a color parameter, the pixel at the specified coordinates is set to that color.\n" \
|
|
"Calling the function without a color parameter returns the color of the pixel at the specified position.", \
|
|
3, \
|
|
2, \
|
|
0, \
|
|
u8, \
|
|
tic_mem*, s32 x, s32 y, u8 color, bool get) \
|
|
\
|
|
\
|
|
macro(line, \
|
|
"line(x0 y0 x1 y1 color)", \
|
|
\
|
|
"Draws a straight line from point (x0,y0) to point (x1,y1) in the specified color.", \
|
|
5, \
|
|
5, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, float x1, float y1, float x2, float y2, u8 color) \
|
|
\
|
|
\
|
|
macro(rect, \
|
|
"rect(x y w h color)", \
|
|
\
|
|
"This function draws a filled rectangle of the desired size and color at the specified position.\n" \
|
|
"If you only need to draw the the border or outline of a rectangle (ie not filled) see `rectb()`.", \
|
|
5, \
|
|
5, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 width, s32 height, u8 color) \
|
|
\
|
|
\
|
|
macro(rectb, \
|
|
"rectb(x y w h color)", \
|
|
\
|
|
"This function draws a one pixel thick rectangle border at the position requested.\n" \
|
|
"If you need to fill the rectangle with a color, see `rect()` instead.", \
|
|
5, \
|
|
5, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 width, s32 height, u8 color) \
|
|
\
|
|
\
|
|
macro(spr, \
|
|
"spr(id x y colorkey=-1 scale=1 flip=0 rotate=0 w=1 h=1)", \
|
|
\
|
|
"Draws the sprite number index at the x and y coordinate.\n" \
|
|
"You can specify a colorkey in the palette which will be used as the transparent color " \
|
|
"or use a value of -1 for an opaque sprite.\n" \
|
|
"The sprite can be scaled up by a desired factor. For example, " \
|
|
"a scale factor of 2 means an 8x8 pixel sprite is drawn to a 16x16 area of the screen.\n" \
|
|
"You can flip the sprite where:\n" \
|
|
"- 0 = No Flip\n" \
|
|
"- 1 = Flip horizontally\n" \
|
|
"- 2 = Flip vertically\n" \
|
|
"- 3 = Flip both vertically and horizontally\n" \
|
|
"When you rotate the sprite, it's rotated clockwise in 90 steps:\n" \
|
|
"- 0 = No rotation\n" \
|
|
"- 1 = 90 rotation\n" \
|
|
"- 2 = 180 rotation\n" \
|
|
"- 3 = 270 rotation\n" \
|
|
"You can draw a composite sprite (consisting of a rectangular region of sprites from the sprite sheet) " \
|
|
"by specifying the `w` and `h` parameters (which default to 1).", \
|
|
9, \
|
|
3, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 index, s32 x, s32 y, s32 w, s32 h, \
|
|
u8* trans_colors, u8 trans_count, s32 scale, tic_flip flip, tic_rotate rotate) \
|
|
\
|
|
\
|
|
macro(btn, \
|
|
"btn(id) -> pressed", \
|
|
\
|
|
"This function allows you to read the status of one of the buttons attached to TIC.\n" \
|
|
"The function returns true if the key with the supplied id is currently in the pressed state.\n" \
|
|
"It remains true for as long as the key is held down.\n" \
|
|
"If you want to test if a key was just pressed, use `btnp()` instead.", \
|
|
1, \
|
|
1, \
|
|
0, \
|
|
u32, \
|
|
tic_mem*, s32 id) \
|
|
\
|
|
\
|
|
macro(btnp, \
|
|
"btnp(id hold=-1 period=-1) -> pressed", \
|
|
\
|
|
"This function allows you to read the status of one of TIC's buttons.\n" \
|
|
"It returns true only if the key has been pressed since the last frame.\n" \
|
|
"You can also use the optional hold and period parameters " \
|
|
"which allow you to check if a button is being held down.\n" \
|
|
"After the time specified by hold has elapsed, " \
|
|
"btnp will return true each time period is passed if the key is still down.\n" \
|
|
"For example, to re-examine the state of button `0` after 2 seconds " \
|
|
"and continue to check its state every 1/10th of a second, you would use btnp(0, 120, 6).\n" \
|
|
"Since time is expressed in ticks and TIC runs at 60 frames per second, " \
|
|
"we use the value of 120 to wait 2 seconds and 6 ticks (ie 60/10) as the interval for re-checking.", \
|
|
3, \
|
|
1, \
|
|
0, \
|
|
u32, \
|
|
tic_mem*, s32 id, s32 hold, s32 period) \
|
|
\
|
|
\
|
|
macro(sfx, \
|
|
"sfx(id note=-1 duration=-1 channel=0 volume=15 speed=0)", \
|
|
\
|
|
"This function will play the sound with `id` created in the sfx editor.\n" \
|
|
"Calling the function with id set to -1 will stop playing the channel.\n" \
|
|
"The note can be supplied as an integer between 0 and 95 (representing 8 octaves of 12 notes each) " \
|
|
"or as a string giving the note name and octave.\n" \
|
|
"For example, a note value of `14` will play the note `D` in the second octave.\n" \
|
|
"The same note could be specified by the string `D-2`.\n" \
|
|
"Note names consist of two characters, " \
|
|
"the note itself (in upper case) followed by `-` to represent the natural note or `#` to represent a sharp.\n" \
|
|
"There is no option to indicate flat values.\n" \
|
|
"The available note names are therefore: C-, C#, D-, D#, E-, F-, F#, G-, G#, A-, A#, B-.\n" \
|
|
"The `octave` is specified using a single digit in the range 0 to 8.\n" \
|
|
"The `duration` specifies how many ticks to play the sound for since TIC-80 runs at 60 frames per second, " \
|
|
"a value of 30 represents half a second.\n" \
|
|
"A value of -1 will play the sound continuously.\n" \
|
|
"The `channel` parameter indicates which of the four channels to use. Allowed values are 0 to 3.\n" \
|
|
"The `volume` can be between 0 and 15.\n" \
|
|
"The `speed` in the range -4 to 3 can be specified and means how many `ticks+1` to play each step, " \
|
|
"so speed==0 means 1 tick per step.", \
|
|
6, \
|
|
1, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 index, s32 note, s32 octave, \
|
|
s32 duration, s32 channel, s32 left, s32 right, s32 speed) \
|
|
\
|
|
\
|
|
macro(map, \
|
|
"map(x=0 y=0 w=30 h=17 sx=0 sy=0 colorkey=-1 scale=1 remap=nil)", \
|
|
\
|
|
"The map consists of cells of 8x8 pixels, each of which can be filled with a sprite using the map editor.\n" \
|
|
"The map can be up to 240 cells wide by 136 deep.\n" \
|
|
"This function will draw the desired area of the map to a specified screen position.\n" \
|
|
"For example, map(5,5,12,10,0,0) will draw a 12x10 section of the map, " \
|
|
"starting from map co-ordinates (5,5) to screen position (0,0).\n" \
|
|
"The map function's last parameter is a powerful callback function " \
|
|
"for changing how map cells (sprites) are drawn when map is called.\n" \
|
|
"It can be used to rotate, flip and replace sprites while the game is running.\n" \
|
|
"Unlike mset, which saves changes to the map, this special function can be used to create " \
|
|
"animated tiles or replace them completely.\n" \
|
|
"Some examples include changing sprites to open doorways, " \
|
|
"hiding sprites used to spawn objects in your game and even to emit the objects themselves.\n" \
|
|
"The tilemap is laid out sequentially in RAM - writing 1 to 0x08000 " \
|
|
"will cause tile(sprite) #1 to appear at top left when map() is called.\n" \
|
|
"To set the tile immediately below this we need to write to 0x08000 + 240, ie 0x080F0.", \
|
|
9, \
|
|
0, \
|
|
1, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 width, s32 height, s32 sx, s32 sy, \
|
|
u8* trans_colors, u8 trans_count, s32 scale, RemapFunc remap, void* data) \
|
|
\
|
|
\
|
|
macro(mget, \
|
|
"mget(x y) -> tile_id", \
|
|
\
|
|
"Gets the sprite id at the given x and y map coordinate.", \
|
|
2, \
|
|
2, \
|
|
0, \
|
|
u8, \
|
|
tic_mem*, s32 x, s32 y) \
|
|
\
|
|
\
|
|
macro(mset, \
|
|
"mset(x y tile_id)", \
|
|
\
|
|
"This function will change the tile at the specified map coordinates.\n" \
|
|
"By default, changes made are only kept while the current game is running.\n" \
|
|
"To make permanent changes to the map, see `sync()`.\n" \
|
|
"Related: `map()` `mget()` `sync()`.", \
|
|
3, \
|
|
3, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, u8 value) \
|
|
\
|
|
\
|
|
macro(peek, \
|
|
"peek(addr bits=8) -> value", \
|
|
\
|
|
"This function allows to read the memory from TIC.\n" \
|
|
"It's useful to access resources created with the integrated tools like sprite, maps, sounds, " \
|
|
"cartridges data?\n" \
|
|
"Never dream to sound a sprite?\n" \
|
|
"Address are in hexadecimal format but values are decimal.\n" \
|
|
"To write to a memory address, use `poke()`.\n" \
|
|
"`bits` allowed to be 1,2,4,8.", \
|
|
2, \
|
|
1, \
|
|
0, \
|
|
u8, \
|
|
tic_mem*, s32 address, s32 bits) \
|
|
\
|
|
\
|
|
macro(poke, \
|
|
"poke(addr value bits=8)", \
|
|
\
|
|
"This function allows you to write a single byte to any address in TIC's RAM.\n" \
|
|
"The address should be specified in hexadecimal format, the value in decimal.\n" \
|
|
"`bits` allowed to be 1,2,4,8.", \
|
|
3, \
|
|
2, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 address, u8 value, s32 bits) \
|
|
\
|
|
\
|
|
macro(peek1, \
|
|
"peek1(addr) -> value", \
|
|
\
|
|
"This function enables you to read single bit values from TIC's RAM.\n" \
|
|
"The address is often specified in hexadecimal format.", \
|
|
1, \
|
|
1, \
|
|
0, \
|
|
u8, \
|
|
tic_mem*, s32 address) \
|
|
\
|
|
\
|
|
macro(poke1, \
|
|
"poke1(addr value)", \
|
|
\
|
|
"This function allows you to write single bit values directly to RAM.\n" \
|
|
"The address is often specified in hexadecimal format.", \
|
|
2, \
|
|
2, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 address, u8 value) \
|
|
\
|
|
\
|
|
macro(peek2, \
|
|
"peek2(addr) -> value", \
|
|
\
|
|
"This function enables you to read two bits values from TIC's RAM.\n" \
|
|
"The address is often specified in hexadecimal format.", \
|
|
1, \
|
|
1, \
|
|
0, \
|
|
u8, \
|
|
tic_mem*, s32 address) \
|
|
\
|
|
\
|
|
macro(poke2, \
|
|
"poke2(addr value)", \
|
|
\
|
|
"This function allows you to write two bits values directly to RAM.\n" \
|
|
"The address is often specified in hexadecimal format.", \
|
|
2, \
|
|
2, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 address, u8 value) \
|
|
\
|
|
\
|
|
macro(peek4, \
|
|
"peek4(addr) -> value", \
|
|
\
|
|
"This function enables you to read values from TIC's RAM.\n" \
|
|
"The address is often specified in hexadecimal format.\n" \
|
|
"See 'poke4()' for detailed information on how nibble addressing compares with byte addressing.", \
|
|
1, \
|
|
1, \
|
|
0, \
|
|
u8, \
|
|
tic_mem*, s32 address) \
|
|
\
|
|
\
|
|
macro(poke4, \
|
|
"poke4(addr value)", \
|
|
\
|
|
"This function allows you to write directly to RAM.\n" \
|
|
"The address is often specified in hexadecimal format.\n" \
|
|
"For both peek4 and poke4 RAM is addressed in 4 bit segments (nibbles).\n" \
|
|
"Therefore, to access the the RAM at byte address 0x4000\n" \
|
|
"you would need to access both the 0x8000 and 0x8001 nibble addresses.", \
|
|
2, \
|
|
2, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 address, u8 value) \
|
|
\
|
|
\
|
|
macro(memcpy, \
|
|
"memcpy(dest source size)", \
|
|
\
|
|
"This function allows you to copy a continuous block of TIC's 96K RAM from one address to another.\n" \
|
|
"Addresses are specified are in hexadecimal format, values are decimal.", \
|
|
3, \
|
|
3, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 dst, s32 src, s32 size) \
|
|
\
|
|
\
|
|
macro(memset, \
|
|
"memset(dest value size)", \
|
|
\
|
|
"This function allows you to set a continuous block of any part of TIC's RAM to the same value.\n" \
|
|
"The address is specified in hexadecimal format, the value in decimal.", \
|
|
3, \
|
|
3, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 dst, u8 val, s32 size) \
|
|
\
|
|
\
|
|
macro(trace, \
|
|
"trace(message color=15)", \
|
|
\
|
|
"This is a service function, useful for debugging your code.\n" \
|
|
"It prints the message parameter to the console in the (optional) color specified.\n" \
|
|
"\nTips:\n" \
|
|
"- The Lua concatenator for strings is .. (two points).\n" \
|
|
"- Use console cls command to clear the output from trace.", \
|
|
2, \
|
|
1, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, const char* text, u8 color) \
|
|
\
|
|
\
|
|
macro(pmem, \
|
|
"pmem(index value)\npmem(index) -> value", \
|
|
\
|
|
"This function allows you to save and retrieve data in one of the 256 individual 32-bit slots " \
|
|
"available in the cartridge's persistent memory.\n" \
|
|
"This is useful for saving high-scores, level advancement or achievements.\n" \
|
|
"The data is stored as unsigned 32-bit integers (from 0 to 4294967295).\n" \
|
|
"\nTips:\n" \
|
|
"- pmem depends on the cartridge hash (md5), so don't change your lua script if you want to keep the data.\n" \
|
|
"- Use `saveid:` with a personalized string in the header metadata to override the default MD5 calculation.\n" \
|
|
"This allows the user to update a cart without losing their saved data.", \
|
|
2, \
|
|
1, \
|
|
0, \
|
|
u32, \
|
|
tic_mem*, s32 index, u32 value, bool get) \
|
|
\
|
|
\
|
|
macro(time, \
|
|
"time() -> ticks", \
|
|
\
|
|
"This function returns the number of milliseconds elapsed since the cartridge began execution.\n" \
|
|
"Useful for keeping track of time, animating items and triggering events.", \
|
|
0, \
|
|
0, \
|
|
0, \
|
|
double, \
|
|
tic_mem*) \
|
|
\
|
|
\
|
|
macro(tstamp, \
|
|
"tstamp() -> timestamp", \
|
|
\
|
|
"This function returns the number of seconds elapsed since January 1st, 1970.\n" \
|
|
"Useful for creating persistent games which evolve over time between plays.", \
|
|
0, \
|
|
0, \
|
|
0, \
|
|
s32, \
|
|
tic_mem*) \
|
|
\
|
|
\
|
|
macro(exit, \
|
|
"exit()", \
|
|
\
|
|
"Interrupts program execution and returns to the console when the TIC function ends.", \
|
|
0, \
|
|
0, \
|
|
0, \
|
|
void, \
|
|
tic_mem*) \
|
|
\
|
|
\
|
|
macro(font, \
|
|
"font(text x y chromakey char_width char_height fixed=false scale=1) -> width", \
|
|
\
|
|
"Print string with font defined in foreground sprites.\n" \
|
|
"To simply print to the screen, check out `print()`.\n" \
|
|
"To print to the console, check out `trace()`.", \
|
|
8, \
|
|
6, \
|
|
0, \
|
|
s32, \
|
|
tic_mem*, const char* text, s32 x, s32 y, \
|
|
u8* trans_colors, u8 trans_count, s32 w, s32 h, bool fixed, s32 scale, bool alt) \
|
|
\
|
|
\
|
|
macro(mouse, \
|
|
"mouse() -> x y left middle right scrollx scrolly", \
|
|
\
|
|
"This function returns the mouse coordinates and a boolean value for the state of each mouse button," \
|
|
"with true indicating that a button is pressed.", \
|
|
0, \
|
|
0, \
|
|
0, \
|
|
tic_point, \
|
|
tic_mem*) \
|
|
\
|
|
\
|
|
macro(circ, \
|
|
"circ(x y radius color)", \
|
|
\
|
|
"This function draws a filled circle of the desired radius and color with its center at x, y.\n" \
|
|
"It uses the Bresenham algorithm.", \
|
|
4, \
|
|
4, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 radius, u8 color) \
|
|
\
|
|
\
|
|
macro(circb, \
|
|
"circb(x y radius color)", \
|
|
\
|
|
"Draws the circumference of a circle with its center at x, y using the radius and color requested.\n" \
|
|
"It uses the Bresenham algorithm.", \
|
|
4, \
|
|
4, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 radius, u8 color) \
|
|
\
|
|
\
|
|
macro(elli, \
|
|
"elli(x y a b color)", \
|
|
\
|
|
"This function draws a filled ellipse of the desired a, b radiuses and color with its center at x, y.\n" \
|
|
"It uses the Bresenham algorithm.", \
|
|
5, \
|
|
5, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 a, s32 b, u8 color) \
|
|
\
|
|
\
|
|
macro(ellib, \
|
|
"ellib(x y a b color)", \
|
|
\
|
|
"This function draws an ellipse border with the desired radiuses a b and color with its center at x, y.\n" \
|
|
"It uses the Bresenham algorithm.", \
|
|
5, \
|
|
5, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 a, s32 b, u8 color) \
|
|
\
|
|
\
|
|
macro(tri, \
|
|
"tri(x1 y1 x2 y2 x3 y3 color)", \
|
|
\
|
|
"This function draws a triangle filled with color, using the supplied vertices.", \
|
|
7, \
|
|
7, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, float x1, float y1, float x2, float y2, float x3, float y3, u8 color) \
|
|
\
|
|
macro(trib, \
|
|
"trib(x1 y1 x2 y2 x3 y3 color)", \
|
|
\
|
|
"This function draws a triangle border with color, using the supplied vertices.", \
|
|
7, \
|
|
7, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, float x1, float y1, float x2, float y2, float x3, float y3, u8 color) \
|
|
\
|
|
\
|
|
macro(ttri, \
|
|
"ttri(x1 y1 x2 y2 x3 y3 u1 v1 u2 v2 u3 v3 texsrc=0 chromakey=-1 z1=0 z2=0 z3=0)", \
|
|
\
|
|
"It renders a triangle filled with texture from image ram, map ram or vbank.\n" \
|
|
"Use in 3D graphics.\n" \
|
|
"In particular, if the vertices in the triangle have different 3D depth, you may see some distortion.\n" \
|
|
"These can be thought of as the window inside image ram (sprite sheet), map ram or another vbank.\n" \
|
|
"Note that the sprite sheet or map in this case is treated as a single large image, " \
|
|
"with U and V addressing its pixels directly, rather than by sprite ID.\n" \
|
|
"So for example the top left corner of sprite #2 would be located at u=16, v=0.", \
|
|
17, \
|
|
12, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, float x1, float y1, float x2, float y2, float x3, float y3, \
|
|
float u1, float v1, float u2, float v2, float u3, float v3, tic_texture_src texsrc, u8* colors, s32 count, \
|
|
float z1, float z2, float z3, bool depth) \
|
|
\
|
|
\
|
|
macro(clip, \
|
|
"clip(x y width height)\nclip()", \
|
|
\
|
|
"This function limits drawing to a clipping region or `viewport` defined by x,y,w,h.\n" \
|
|
"Things drawn outside of this area will not be visible.\n" \
|
|
"Calling clip() with no parameters will reset the drawing area to the entire screen.", \
|
|
4, \
|
|
4, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 x, s32 y, s32 width, s32 height) \
|
|
\
|
|
\
|
|
macro(music, \
|
|
"music(track=-1 frame=-1 row=-1 loop=true sustain=false tempo=-1 speed=-1)", \
|
|
\
|
|
"This function starts playing a track created in the Music Editor.\n" \
|
|
"Call without arguments to stop the music.", \
|
|
7, \
|
|
0, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 track, s32 frame, s32 row, bool loop, bool sustain, s32 tempo, s32 speed) \
|
|
\
|
|
\
|
|
macro(sync, \
|
|
"sync(mask=0 bank=0 tocart=false)", \
|
|
\
|
|
"The pro version of TIC-80 contains 8 memory banks.\n" \
|
|
"To switch between these banks, sync can be used to either load contents from a memory bank to runtime, " \
|
|
"or save contents from the active runtime to a bank.\n" \
|
|
"The function can only be called once per frame." \
|
|
"If you have manipulated the runtime memory (e.g. by using mset), " \
|
|
"you can reset the active state by calling sync(0,0,false).\n" \
|
|
"This resets the whole runtime memory to the contents of bank 0." \
|
|
"Note that sync is not used to load code from banks; this is done automatically.", \
|
|
3, \
|
|
0, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, u32 mask, s32 bank, bool toCart) \
|
|
\
|
|
\
|
|
macro(vbank, \
|
|
"vbank(bank) -> prev\nvbank() -> prev", \
|
|
\
|
|
"VRAM contains 2x16K memory chips, use vbank(0) or vbank(1) to switch between them.", \
|
|
1, \
|
|
1, \
|
|
0, \
|
|
s32, \
|
|
tic_mem*, s32 bank) \
|
|
\
|
|
\
|
|
macro(reset, \
|
|
"reset()", \
|
|
\
|
|
"Resets the cartridge. To return to the console, see the `exit()`.", \
|
|
0, \
|
|
0, \
|
|
0, \
|
|
void, \
|
|
tic_mem*) \
|
|
\
|
|
\
|
|
macro(key, \
|
|
"key(code=-1) -> pressed", \
|
|
\
|
|
"The function returns true if the key denoted by keycode is pressed.", \
|
|
1, \
|
|
0, \
|
|
0, \
|
|
bool, \
|
|
tic_mem*, tic_key key) \
|
|
\
|
|
\
|
|
macro(keyp, \
|
|
"keyp(code=-1 hold=-1 period=-1) -> pressed", \
|
|
\
|
|
"This function returns true if the given key is pressed but wasn't pressed in the previous frame.\n" \
|
|
"Refer to `btnp()` for an explanation of the optional hold and period parameters.", \
|
|
3, \
|
|
0, \
|
|
0, \
|
|
bool, \
|
|
tic_mem*, tic_key key, s32 hold, s32 period) \
|
|
\
|
|
\
|
|
macro(fget, \
|
|
"fget(sprite_id flag) -> bool", \
|
|
\
|
|
"Returns true if the specified flag of the sprite is set. See `fset()` for more details.", \
|
|
2, \
|
|
2, \
|
|
0, \
|
|
bool, \
|
|
tic_mem*, s32 index, u8 flag) \
|
|
\
|
|
\
|
|
macro(fset, \
|
|
"fset(sprite_id flag bool)", \
|
|
\
|
|
"Each sprite has eight flags which can be used to store information or signal different conditions.\n" \
|
|
"For example, flag 0 might be used to indicate that the sprite is invisible, " \
|
|
"flag 6 might indicate that the flag should be draw scaled etc.\n" \
|
|
"See algo `fget()`.", \
|
|
3, \
|
|
3, \
|
|
0, \
|
|
void, \
|
|
tic_mem*, s32 index, u8 flag, bool value)
|
|
|
|
#define TIC_API_DEF(name, _, __, ___, ____, _____, ret, ...) ret tic_api_##name(__VA_ARGS__);
|
|
TIC_API_LIST(TIC_API_DEF)
|
|
#undef TIC_API_DEF
|
|
|
|
struct tic_mem
|
|
{
|
|
tic80 product;
|
|
tic_ram* ram;
|
|
tic_cartridge cart;
|
|
|
|
tic_ram* base_ram;
|
|
|
|
char saveid[TIC_SAVEID_SIZE];
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
u8 gamepad:1;
|
|
u8 mouse:1;
|
|
u8 keyboard:1;
|
|
};
|
|
|
|
u8 data;
|
|
} input;
|
|
};
|
|
|
|
tic_mem* tic_core_create(s32 samplerate, tic80_pixel_color_format format);
|
|
void tic_core_close(tic_mem* memory);
|
|
void tic_core_pause(tic_mem* memory);
|
|
void tic_core_resume(tic_mem* memory);
|
|
void tic_core_tick_start(tic_mem* memory);
|
|
void tic_core_tick(tic_mem* memory, tic_tick_data* data);
|
|
void tic_core_tick_end(tic_mem* memory);
|
|
void tic_core_synth_sound(tic_mem* tic);
|
|
void tic_core_blit(tic_mem* tic);
|
|
void tic_core_blit_ex(tic_mem* tic, tic_blit_callback clb);
|
|
const tic_script_config* tic_core_script_config(tic_mem* memory);
|
|
|
|
#define VBANK(tic, bank) \
|
|
bool MACROVAR(_bank_) = tic_api_vbank(tic, bank); \
|
|
SCOPE(tic_api_vbank(tic, MACROVAR(_bank_)))
|