This commit is contained in:
Graham Clemo
2018-10-14 13:10:28 +01:00
113 changed files with 2479 additions and 6276 deletions
+91 -71
View File
@@ -27,19 +27,16 @@
#define TEXT_CURSOR_DELAY (TIC_FRAMERATE / 2)
#define TEXT_CURSOR_BLINK_PERIOD TIC_FRAMERATE
static inline s32 TextBufferHeight(const tic_mem* tic)
{
return ((TIC80_HEIGHT - TOOLBAR_SIZE - TextHeight(tic)) / TextHeight(tic));
}
#define TEXT_BUFFER_WIDTH STUDIO_TEXT_BUFFER_WIDTH
#define TEXT_BUFFER_HEIGHT ((TIC80_HEIGHT - TOOLBAR_SIZE - STUDIO_TEXT_HEIGHT) / STUDIO_TEXT_HEIGHT)
struct OutlineItem
{
char name[TIC80_WIDTH];
char name[TEXT_BUFFER_WIDTH];
char* pos;
};
#define OUTLINE_SIZE (TIC80_HEIGHT)
#define OUTLINE_SIZE ((TIC80_HEIGHT - TOOLBAR_SIZE*2)/TIC_FONT_HEIGHT)
#define OUTLINE_ITEMS_SIZE (OUTLINE_SIZE * sizeof(OutlineItem))
static void history(Code* code)
@@ -50,35 +47,34 @@ static void history(Code* code)
static void drawStatus(Code* code)
{
tic_mem* tic = code->tic;
const s32 Height = tic->font.height + 1;
const s32 Height = TIC_FONT_HEIGHT + 1;
code->tic->api.rect(code->tic, 0, TIC80_HEIGHT - Height, TIC80_WIDTH, Height, (tic_color_white));
code->tic->api.fixed_text(code->tic, code->status, 0, TIC80_HEIGHT - TIC_FONT_HEIGHT, getConfig()->theme.code.bg, false);
}
tic->api.rect(tic, 0, TIC80_HEIGHT - Height, TIC80_WIDTH, Height, (tic_color_white));
tic->api.fixed_text(tic, code->status.left, 0, TIC80_HEIGHT - tic->font.height, getConfig()->theme.code.bg);
tic->api.fixed_text(tic, code->status.right, TIC80_WIDTH - (strlen(code->status.right) * tic->font.width),
TIC80_HEIGHT - tic->font.height, getConfig()->theme.code.bg);
static inline s32 getFontWidth(Code* code)
{
return code->altFont ? TIC_ALTFONT_WIDTH : TIC_FONT_WIDTH;
}
static void drawCursor(Code* code, s32 x, s32 y, char symbol)
{
tic_mem* tic = code->tic;
bool inverse = code->cursor.delay || code->tickCounter % TEXT_CURSOR_BLINK_PERIOD < TEXT_CURSOR_BLINK_PERIOD / 2;
if(inverse)
{
code->tic->api.rect(code->tic, x-1, y-1, tic->font.width+1, tic->font.height+1, getConfig()->theme.code.cursor);
code->tic->api.rect(code->tic, x-1, y-1, (getFontWidth(code))+1, TIC_FONT_HEIGHT+1, getConfig()->theme.code.cursor);
if(symbol)
code->tic->api.draw_char(code->tic, symbol, x, y, getConfig()->theme.code.bg);
code->tic->api.draw_char(code->tic, symbol, x, y, getConfig()->theme.code.bg, code->altFont);
}
}
static void drawCode(Code* code, bool withCursor)
{
tic_mem* tic = code->tic;
s32 xStart = code->rect.x - code->scroll.x * TextWidth(tic);
s32 xStart = code->rect.x - code->scroll.x * (getFontWidth(code));
s32 x = xStart;
s32 y = code->rect.y - code->scroll.y * TextHeight(tic);
s32 y = code->rect.y - code->scroll.y * STUDIO_TEXT_HEIGHT;
char* pointer = code->src;
u8* colorPointer = code->colorBuffer;
@@ -92,16 +88,16 @@ static void drawCode(Code* code, bool withCursor)
{
char symbol = *pointer;
if(x >= -tic->font.width && x < TIC80_WIDTH && y >= -tic->font.height && y < TIC80_HEIGHT )
if(x >= -TIC_FONT_WIDTH && x < TIC80_WIDTH && y >= -TIC_FONT_HEIGHT && y < TIC80_HEIGHT )
{
if(code->cursor.selection && pointer >= selection.start && pointer < selection.end)
code->tic->api.rect(code->tic, x-1, y-1, tic->font.width+1, tic->font.height+1, getConfig()->theme.code.select);
code->tic->api.rect(code->tic, x-1, y-1, TIC_FONT_WIDTH+1, TIC_FONT_HEIGHT+1, getConfig()->theme.code.select);
else if(getConfig()->theme.code.shadow)
{
code->tic->api.draw_char(code->tic, symbol, x+1, y+1, 0);
code->tic->api.draw_char(code->tic, symbol, x+1, y+1, 0, code->altFont);
}
code->tic->api.draw_char(code->tic, symbol, x, y, *colorPointer);
code->tic->api.draw_char(code->tic, symbol, x, y, *colorPointer, code->altFont);
}
if(code->cursor.position == pointer)
@@ -110,9 +106,9 @@ static void drawCode(Code* code, bool withCursor)
if(symbol == '\n')
{
x = xStart;
y += TextHeight(tic);
y += STUDIO_TEXT_HEIGHT;
}
else x += TextWidth(tic);
else x += (getFontWidth(code));
pointer++;
colorPointer++;
@@ -168,31 +164,36 @@ static void removeInvalidChars(char* code)
static void updateEditor(Code* code)
{
tic_mem* tic = code->tic;
s32 column = 0;
s32 line = 0;
getCursorPosition(code, &column, &line);
const s32 BufferWidth = TIC80_WIDTH / getFontWidth(code);
if(column < code->scroll.x) code->scroll.x = column;
else if(column >= code->scroll.x + BufferWidth(tic))
code->scroll.x = column - BufferWidth(tic) + 1;
else if(column >= code->scroll.x + BufferWidth)
code->scroll.x = column - BufferWidth + 1;
if(line < code->scroll.y) code->scroll.y = line;
else if(line >= code->scroll.y + TextBufferHeight(tic))
code->scroll.y = line - TextBufferHeight(tic) + 1;
else if(line >= code->scroll.y + TEXT_BUFFER_HEIGHT)
code->scroll.y = line - TEXT_BUFFER_HEIGHT + 1;
code->cursor.delay = TEXT_CURSOR_DELAY;
// update status
{
memset(code->status, ' ', sizeof code->status - 1);
char status[TEXT_BUFFER_WIDTH];
s32 count = getLinesCount(code);
sprintf(code->status.left, "line %i/%i col %i", line + 1, count + 1, column + 1);
sprintf(status, "line %i/%i col %i", line + 1, count + 1, column + 1);
memcpy(code->status, status, strlen(status));
size_t codeLen = strlen(code->src);
sprintf(code->status.right, "%i/%i", (u32)codeLen, TIC_CODE_SIZE);
sprintf(status, "%i/%i", (u32)codeLen, TIC_CODE_SIZE);
memset(code->src + codeLen, '\0', TIC_CODE_SIZE - codeLen);
memcpy(code->status + sizeof code->status - strlen(status) - 1, status, strlen(status));
}
}
@@ -409,21 +410,19 @@ static void goCodeEnd(Code *code)
static void pageUp(Code* code)
{
tic_mem* tic = code->tic;
s32 column = 0;
s32 line = 0;
getCursorPosition(code, &column, &line);
setCursorPosition(code, column, line > TextBufferHeight(tic) ? line - TextBufferHeight(tic) : 0);
setCursorPosition(code, column, line > TEXT_BUFFER_HEIGHT ? line - TEXT_BUFFER_HEIGHT : 0);
}
static void pageDown(Code* code)
{
tic_mem* tic = code->tic;
s32 column = 0;
s32 line = 0;
getCursorPosition(code, &column, &line);
s32 lines = getLinesCount(code);
setCursorPosition(code, column, line < lines - TextBufferHeight(tic) ? line + TextBufferHeight(tic) : lines);
setCursorPosition(code, column, line < lines - TEXT_BUFFER_HEIGHT ? line + TEXT_BUFFER_HEIGHT : lines);
}
static bool replaceSelection(Code* code)
@@ -734,12 +733,10 @@ static void normalizeScroll(Code* code)
static void centerScroll(Code* code)
{
tic_mem* tic = code->tic;
s32 col, line;
getCursorPosition(code, &col, &line);
code->scroll.x = col - BufferWidth(tic) / 2;
code->scroll.y = line - TextBufferHeight(tic) / 2;
code->scroll.x = col - TIC80_WIDTH / getFontWidth(code) / 2;
code->scroll.y = line - TEXT_BUFFER_HEIGHT / 2;
normalizeScroll(code);
}
@@ -782,8 +779,8 @@ static void initOutlineMode(Code* code)
tic_mem* tic = code->tic;
char buffer[TIC80_WIDTH] = {0};
char filter[TIC80_WIDTH] = {0};
char buffer[TEXT_BUFFER_WIDTH] = {0};
char filter[TEXT_BUFFER_WIDTH] = {0};
strncpy(filter, code->popup.text, sizeof(filter));
ticStrlwr(filter);
@@ -802,8 +799,8 @@ static void initOutlineMode(Code* code)
if(out < end)
{
out->pos = code->src + item->pos;
memset(out->name, 0, TIC80_WIDTH);
memcpy(out->name, out->pos, MIN(item->size, TIC80_WIDTH-1));
memset(out->name, 0, TEXT_BUFFER_WIDTH);
memcpy(out->name, out->pos, MIN(item->size, TEXT_BUFFER_WIDTH-1));
if(*filter)
{
@@ -976,8 +973,8 @@ static void processMouse(Code* code)
{
if(checkMouseDown(&code->rect, tic_mouse_right))
{
code->scroll.x = (code->scroll.start.x - getMouseX()) / TextWidth(tic);
code->scroll.y = (code->scroll.start.y - getMouseY()) / TextHeight(tic);
code->scroll.x = (code->scroll.start.x - getMouseX()) / (getFontWidth(code));
code->scroll.y = (code->scroll.start.y - getMouseY()) / STUDIO_TEXT_HEIGHT;
normalizeScroll(code);
}
@@ -990,8 +987,8 @@ static void processMouse(Code* code)
s32 mx = getMouseX();
s32 my = getMouseY();
s32 x = (mx - code->rect.x) / TextWidth(tic);
s32 y = (my - code->rect.y) / TextHeight(tic);
s32 x = (mx - code->rect.x) / (getFontWidth(code));
s32 y = (my - code->rect.y) / STUDIO_TEXT_HEIGHT;
char* position = code->cursor.position;
setCursorPosition(code, x + code->scroll.x, y + code->scroll.y);
@@ -1019,8 +1016,8 @@ static void processMouse(Code* code)
{
code->scroll.active = true;
code->scroll.start.x = getMouseX() + code->scroll.x * TextWidth(tic);
code->scroll.start.y = getMouseY() + code->scroll.y * TextHeight(tic);
code->scroll.start.x = getMouseX() + code->scroll.x * (getFontWidth(code));
code->scroll.start.y = getMouseY() + code->scroll.y * STUDIO_TEXT_HEIGHT;
}
}
@@ -1068,16 +1065,14 @@ static void textEditTick(Code* code)
static void drawPopupBar(Code* code, const char* title)
{
tic_mem* tic = code->tic;
enum {TextY = TOOLBAR_SIZE + 1};
code->tic->api.rect(code->tic, 0, TOOLBAR_SIZE, TIC80_WIDTH, tic->font.height + 1, (tic_color_blue));
code->tic->api.fixed_text(code->tic, title, 0, TextY, (tic_color_white));
code->tic->api.rect(code->tic, 0, TOOLBAR_SIZE, TIC80_WIDTH, TIC_FONT_HEIGHT + 1, (tic_color_blue));
code->tic->api.fixed_text(code->tic, title, 0, TextY, (tic_color_white), false);
code->tic->api.fixed_text(code->tic, code->popup.text, (s32)strlen(title)*tic->font.width, TextY, (tic_color_white));
code->tic->api.fixed_text(code->tic, code->popup.text, (s32)strlen(title)*TIC_FONT_WIDTH, TextY, (tic_color_white), false);
drawCursor(code, (s32)(strlen(title) + strlen(code->popup.text)) * tic->font.width, TextY, ' ');
drawCursor(code, (s32)(strlen(title) + strlen(code->popup.text)) * TIC_FONT_WIDTH, TextY, ' ');
}
static void updateFindCode(Code* code, char* pos)
@@ -1215,8 +1210,8 @@ static void textGoToTick(Code* code)
tic->api.clear(tic, getConfig()->theme.code.bg);
if(code->jump.line >= 0)
tic->api.rect(tic, 0, (code->jump.line - code->scroll.y) * (tic->font.height+1) + TOOLBAR_SIZE,
TIC80_WIDTH, tic->font.height+2, getConfig()->theme.code.select);
tic->api.rect(tic, 0, (code->jump.line - code->scroll.y) * (TIC_FONT_HEIGHT+1) + TOOLBAR_SIZE,
TIC80_WIDTH, TIC_FONT_HEIGHT+2, getConfig()->theme.code.select);
drawCode(code, false);
drawPopupBar(code, " GOTO:");
@@ -1225,14 +1220,12 @@ static void textGoToTick(Code* code)
static void drawOutlineBar(Code* code, s32 x, s32 y)
{
tic_mem* tic = code->tic;
tic_rect rect = {x, y, TIC80_WIDTH - x, TIC80_HEIGHT - y};
if(checkMousePos(&rect))
{
s32 mx = getMouseY() - rect.y;
mx /= TextHeight(tic);
mx /= STUDIO_TEXT_HEIGHT;
if(mx < OUTLINE_SIZE && code->outline.items[mx].pos)
{
@@ -1258,22 +1251,20 @@ static void drawOutlineBar(Code* code, s32 x, s32 y)
if(ptr->pos)
{
code->tic->api.rect(code->tic, rect.x - 1, rect.y + code->outline.index*TextHeight(tic),
rect.w + 1, tic->font.height + 1, (tic_color_red));
code->tic->api.rect(code->tic, rect.x - 1, rect.y + code->outline.index*STUDIO_TEXT_HEIGHT,
rect.w + 1, TIC_FONT_HEIGHT + 1, (tic_color_red));
while(ptr->pos)
{
code->tic->api.fixed_text(code->tic, ptr->name, x, y, (tic_color_white));
code->tic->api.fixed_text(code->tic, ptr->name, x, y, (tic_color_white), false);
ptr++;
y += TextHeight(tic);
y += STUDIO_TEXT_HEIGHT;
}
}
else code->tic->api.fixed_text(code->tic, "(empty)", x, y, (tic_color_white));
else code->tic->api.fixed_text(code->tic, "(empty)", x, y, (tic_color_white), false);
}
static void textOutlineTick(Code* code)
{
tic_mem* tic = code->tic;
if(keyWasPressed(tic_key_up))
{
if(code->outline.index > 0)
@@ -1321,7 +1312,33 @@ static void textOutlineTick(Code* code)
drawCode(code, false);
drawPopupBar(code, " FUNC:");
drawStatus(code);
drawOutlineBar(code, TIC80_WIDTH - 12 * tic->font.width, 2*(tic->font.height+1));
drawOutlineBar(code, TIC80_WIDTH - 12 * TIC_FONT_WIDTH, 2*(TIC_FONT_HEIGHT+1));
}
static void drawFontButton(Code* code, s32 x, s32 y)
{
tic_mem* tic = code->tic;
enum {Size = TIC_FONT_WIDTH};
tic_rect rect = {x, y, Size, Size};
bool over = false;
if(checkMousePos(&rect))
{
setCursor(tic_cursor_hand);
showTooltip("SWITCH FONT");
over = true;
if(checkMouseClick(&rect, tic_mouse_left))
{
code->altFont = !code->altFont;
}
}
tic->api.draw_char(tic, 'F', x, y, over ? tic_color_dark_gray : tic_color_light_blue, code->altFont);
}
static void drawCodeToolbar(Code* code)
@@ -1408,6 +1425,8 @@ static void drawCodeToolbar(Code* code)
drawBitIcon(rect.x, rect.y, Icons + i*BITS_IN_BYTE, active ? (tic_color_white) : (over ? (tic_color_dark_gray) : (tic_color_light_blue)));
}
drawFontButton(code, TIC80_WIDTH - (Count+2) * Size, 1);
drawToolbar(code->tic, getConfig()->theme.code.bg, false);
}
@@ -1471,7 +1490,7 @@ void initCode(Code* code, tic_mem* tic, tic_code* src)
.tick = tick,
.escape = escape,
.cursor = {{src->data, NULL, 0}, NULL, 0},
.rect = {0, TOOLBAR_SIZE + 1, TIC80_WIDTH, TIC80_HEIGHT - TOOLBAR_SIZE - tic->font.height - 1},
.rect = {0, TOOLBAR_SIZE + 1, TIC80_WIDTH, TIC80_HEIGHT - TOOLBAR_SIZE - TIC_FONT_HEIGHT - 1},
.scroll = {0, 0, {0, 0}, false},
.tickCounter = 0,
.history = NULL,
@@ -1488,6 +1507,7 @@ void initCode(Code* code, tic_mem* tic, tic_code* src)
.items = code->outline.items,
.index = 0,
},
.altFont = getConfig()->theme.code.altFont,
.event = onStudioEvent,
.update = update,
};
+4 -6
View File
@@ -62,11 +62,7 @@ struct Code
u8 colorBuffer[TIC_CODE_SIZE];
struct
{
char left[TIC80_WIDTH];
char right[TIC80_WIDTH];
} status;
char status[STUDIO_TEXT_BUFFER_WIDTH+1];
u32 tickCounter;
@@ -84,7 +80,7 @@ struct Code
struct
{
char text[TIC80_WIDTH];
char text[STUDIO_TEXT_BUFFER_WIDTH - sizeof "FIND:"];
char* prevPos;
char* prevSel;
@@ -102,6 +98,8 @@ struct Code
s32 index;
} outline;
bool altFont;
void(*tick)(Code*);
void(*escape)(Code*);
void(*event)(Code*, StudioEvent);
+4 -28
View File
@@ -201,31 +201,12 @@ static void readCodeTheme(Config* config, lua_State* lua)
lua_pop(lua, 1);
}
}
lua_pop(lua, 1);
}
static void readFontTheme(Config* config, lua_State* lua)
{
lua_getfield(lua, -1, "FONT");
if(lua_type(lua, -1) == LUA_TTABLE)
{
{
lua_getfield(lua, -1, "WIDTH");
if(lua_isinteger(lua, -1))
config->data.theme.font.width = lua_tointeger(lua, -1);
lua_pop(lua, 1);
}
{
lua_getfield(lua, -1, "HEIGHT");
lua_getfield(lua, -1, "ALT_FONT");
if(lua_isinteger(lua, -1))
config->data.theme.font.height = lua_tointeger(lua, -1);
if(lua_isboolean(lua, -1))
config->data.theme.code.altFont = lua_toboolean(lua, -1);
lua_pop(lua, 1);
}
@@ -267,7 +248,6 @@ static void readTheme(Config* config, lua_State* lua)
readCursorTheme(config, lua);
readCodeTheme(config, lua);
readGamepadTheme(config, lua);
readFontTheme(config, lua);
}
lua_pop(lua, 1);
@@ -279,7 +259,7 @@ static void readConfig(Config* config)
if(lua)
{
if(luaL_loadstring(lua, config->cart.bank0.code.data) == LUA_OK && lua_pcall(lua, 0, LUA_MULTRET, 0) == LUA_OK)
if(luaL_loadstring(lua, config->cart.code.data) == LUA_OK && lua_pcall(lua, 0, LUA_MULTRET, 0) == LUA_OK)
{
readConfigVideoLength(config, lua);
readConfigVideoScale(config, lua);
@@ -289,10 +269,6 @@ static void readConfig(Config* config)
readConfigCrtMonitor(config, lua);
readConfigUiScale(config, lua);
readTheme(config, lua);
}
if(luaL_loadstring(lua, config->cart.bank1.code.data) == LUA_OK && lua_pcall(lua, 0, LUA_MULTRET, 0) == LUA_OK)
{
readConfigCrtShader(config, lua);
}
+2 -7
View File
@@ -70,10 +70,6 @@ typedef enum
WrenScript,
#endif
#if defined(TIC_BUILD_WITH_SQUIRREL)
Squirrel,
#endif
} ScriptLang;
#if defined(__TIC_WINDOWS__) || defined(__TIC_LINUX__) || defined(__TIC_MACOSX__)
@@ -498,10 +494,11 @@ static void* getDemoCart(Console* console, ScriptLang script, s32* size)
#if defined(TIC_BUILD_WITH_WREN)
case WrenScript: strcpy(path, DefaultWrenTicPath); break;
#endif
#endif
#if defined(TIC_BUILD_WITH_SQUIRREL)
case Squirrel: strcpy(path, DefaultSquirrelTicPath); break;
#endif
}
void* data = fsLoadRootFile(console->fs, path, size);
@@ -556,7 +553,6 @@ static void* getDemoCart(Console* console, ScriptLang script, s32* size)
break;
# endif
#endif /* defined(TIC_BUILD_WITH_LUA) */
#if defined(TIC_BUILD_WITH_SQUIRREL)
@@ -1546,7 +1542,6 @@ static void onConsoleConfigCommand(Console* console, const char* param)
}
# endif
#endif /* defined(TIC_BUILD_WITH_LUA) */
#if defined(TIC_BUILD_WITH_JS)
+2 -2
View File
@@ -78,7 +78,7 @@ struct Console
char* buffer;
u8* colorBuffer;
char inputBuffer[TIC80_WIDTH];
char inputBuffer[STUDIO_TEXT_BUFFER_WIDTH * STUDIO_TEXT_BUFFER_HEIGHT];
size_t inputPosition;
tic_mem* tic;
@@ -103,7 +103,7 @@ struct Console
bool crtMonitor;
};
void(*load)(Console*, const char* name);
void(*load)(Console*, const char* path, const char* hash);
bool(*loadProject)(Console*, const char* name, const char* data, s32 size, tic_cartridge* dst);
void(*updateProject)(Console*);
void(*error)(Console*, const char*);
+8 -8
View File
@@ -57,8 +57,8 @@ static void drawButton(Dialog* dlg, const char* label, s32 x, s32 y, u8 color, u
tic->api.rect(tic, rect.x, rect.y, rect.w, rect.h, (tic_color_white));
}
s32 size = tic->api.text(tic, label, 0, -tic->font.height, 0);
tic->api.text(tic, label, rect.x + (BtnWidth - size+1)/2, rect.y + (down?3:2), over ? overColor : color);
s32 size = tic->api.text(tic, label, 0, -TIC_FONT_HEIGHT, 0, false);
tic->api.text(tic, label, rect.x + (BtnWidth - size+1)/2, rect.y + (down?3:2), over ? overColor : color, false);
if(dlg->focus == id)
{
@@ -162,8 +162,8 @@ static void drawDialog(Dialog* dlg)
{
static const char Label[] = "WARNING!";
s32 size = tic->api.text(tic, Label, 0, -tic->font.height, 0);
tic->api.text(tic, Label, rect.x + (Width - size)/2, rect.y-(TOOLBAR_SIZE-2), (tic_color_gray));
s32 size = tic->api.text(tic, Label, 0, -TIC_FONT_HEIGHT, 0, false);
tic->api.text(tic, Label, rect.x + (Width - size)/2, rect.y-(TOOLBAR_SIZE-2), (tic_color_gray), false);
}
{
@@ -174,12 +174,12 @@ static void drawDialog(Dialog* dlg)
{
for(s32 i = 0; i < dlg->rows; i++)
{
s32 size = tic->api.text(tic, dlg->text[i], 0, -tic->font.height, 0);
s32 size = tic->api.text(tic, dlg->text[i], 0, -TIC_FONT_HEIGHT, 0, false);
s32 x = rect.x + (Width - size)/2;
s32 y = rect.y + (tic->font.height+1)*(i+1);
tic->api.text(tic, dlg->text[i], x, y+1, (tic_color_black));
tic->api.text(tic, dlg->text[i], x, y, (tic_color_white));
s32 y = rect.y + (TIC_FONT_HEIGHT+1)*(i+1);
tic->api.text(tic, dlg->text[i], x, y+1, (tic_color_black), false);
tic->api.text(tic, dlg->text[i], x, y, (tic_color_white), false);
}
}
-1
View File
@@ -30,7 +30,6 @@
#include <commdlg.h>
#include <stdio.h>
FILE* _wfopen(const wchar_t *, const wchar_t *);
wchar_t* wcsrchr(const wchar_t *, wchar_t);
wchar_t* wcscpy(wchar_t *, const wchar_t *);
+65 -70
View File
@@ -115,7 +115,7 @@ static const fsString* utf8ToString(const char* str)
{
fsString* wstr = malloc(FILENAME_MAX * sizeof(fsString));
mbstowcs(wstr, str, FILENAME_MAX);
MultiByteToWideChar(CP_UTF8, 0, str, FILENAME_MAX, wstr, FILENAME_MAX);
return wstr;
}
@@ -124,15 +124,13 @@ static const char* stringToUtf8(const fsString* wstr)
{
char* str = malloc(FILENAME_MAX * sizeof(char));
wcstombs(str, wstr, FILENAME_MAX);
WideCharToMultiByte(CP_UTF8, 0, wstr, FILENAME_MAX, str, FILENAME_MAX, 0, 0);
return str;
}
#define freeString(S) free((void*)S)
FILE* _wfopen(const fsString *, const fsString *);
int _wremove(const fsString *);
#define TIC_DIR _WDIR
#define tic_dirent _wdirent
@@ -146,6 +144,8 @@ int _wremove(const fsString *);
#define tic_remove _wremove
#define tic_fopen _wfopen
#define tic_mkdir(name) _wmkdir(name)
#define tic_strcpy wcscpy
#define tic_strcat wcscat
#else
@@ -170,6 +170,8 @@ typedef char fsString;
#define tic_remove remove
#define tic_fopen fopen
#define tic_mkdir(name) mkdir(name, 0700)
#define tic_strcpy strcpy
#define tic_strcat strcat
#endif
@@ -298,6 +300,42 @@ static void netDirRequest(const char* path, ListCallback callback, void* data)
#endif
static void enumFiles(FileSystem* fs, const char* path, ListCallback callback, void* data, bool folder)
{
TIC_DIR *dir = NULL;
struct tic_dirent* ent = NULL;
const fsString* pathString = utf8ToString(path);
if ((dir = tic_opendir(pathString)) != NULL)
{
fsString fullPath[FILENAME_MAX];
struct tic_stat_struct s;
while ((ent = tic_readdir(dir)) != NULL)
{
if(*ent->d_name != _S('.'))
{
tic_strcpy(fullPath, pathString);
tic_strcat(fullPath, ent->d_name);
if(tic_stat(fullPath, &s) == 0 && folder ? S_ISDIR(s.st_mode) : S_ISREG(s.st_mode))
{
const char* name = stringToUtf8(ent->d_name);
bool result = callback(name, NULL, 0, data, folder);
freeString(name);
if(!result) break;
}
}
}
tic_closedir(dir);
}
freeString(pathString);
}
void fsEnumFiles(FileSystem* fs, ListCallback callback, void* data)
{
#if !defined(__EMSCRIPTEN__)
@@ -312,56 +350,10 @@ void fsEnumFiles(FileSystem* fs, ListCallback callback, void* data)
#endif
TIC_DIR *dir = NULL;
struct tic_dirent* ent = NULL;
const char* path = getFilePath(fs, "");
{
const fsString* pathString = utf8ToString(path);
if ((dir = tic_opendir(pathString)) != NULL)
{
while ((ent = tic_readdir(dir)) != NULL)
{
if (ent->d_type == DT_DIR && *ent->d_name != _S('.'))
{
const char* name = stringToUtf8(ent->d_name);
bool result = callback(name, NULL, 0, data, true);
freeString(name);
if(!result) break;
}
}
tic_closedir(dir);
}
freeString(pathString);
}
{
const fsString* pathString = utf8ToString(path);
if ((dir = tic_opendir(pathString)) != NULL)
{
while ((ent = tic_readdir(dir)) != NULL)
{
if (ent->d_type == DT_REG)
{
const char* name = stringToUtf8(ent->d_name);
bool result = callback(name, NULL, 0, data, false);
freeString(name);
if (!result)break;
}
}
tic_closedir(dir);
}
freeString(pathString);
}
enumFiles(fs, path, callback, data, true);
enumFiles(fs, path, callback, data, false);
}
bool fsDeleteDir(FileSystem* fs, const char* name)
@@ -899,6 +891,26 @@ static bool onLoadPublicCart(const char* name, const char* info, s32 id, void* d
return true;
}
void* fsLoadFileByHash(FileSystem* fs, const char* hash, s32* size)
{
char cachePath[FILENAME_MAX] = {0};
sprintf(cachePath, TIC_CACHE "%s.tic", hash);
{
void* data = fsLoadRootFile(fs, cachePath, size);
if(data) return data;
}
char path[FILENAME_MAX] = {0};
sprintf(path, "/cart/%s/cart.tic", hash);
void* data = getSystem()->getUrlRequest(path, size);
if(data)
fsSaveRootFile(fs, cachePath, data, *size, false);
return data;
}
void* fsLoadFile(FileSystem* fs, const char* name, s32* size)
{
if(isPublic(fs))
@@ -912,24 +924,7 @@ void* fsLoadFile(FileSystem* fs, const char* name, s32* size)
fsEnumFiles(fs, onLoadPublicCart, &loadPublicCartData);
if(strlen(loadPublicCartData.hash))
{
char cachePath[FILENAME_MAX] = {0};
sprintf(cachePath, TIC_CACHE "%s.tic", loadPublicCartData.hash);
{
void* data = fsLoadRootFile(fs, cachePath, size);
if(data) return data;
}
char path[FILENAME_MAX] = {0};
sprintf(path, "/cart/%s/cart.tic", loadPublicCartData.hash);
void* data = getSystem()->getUrlRequest(path, size);
if(data)
fsSaveRootFile(fs, cachePath, data, *size, false);
return data;
}
return fsLoadFileByHash(fs, loadPublicCartData.hash, size);
}
else
{
+1 -2
View File
@@ -25,8 +25,6 @@
#include <tic80_types.h>
#include <string.h>
typedef struct FileSystem FileSystem;
typedef enum
{
FS_FILE_NOT_ADDED,
@@ -57,6 +55,7 @@ bool fsDeleteDir(FileSystem* fs, const char* name);
bool fsSaveFile(FileSystem* fs, const char* name, const void* data, size_t size, bool overwrite);
bool fsSaveRootFile(FileSystem* fs, const char* name, const void* data, size_t size, bool overwrite);
void* fsLoadFile(FileSystem* fs, const char* name, s32* size);
void* fsLoadFileByHash(FileSystem* fs, const char* hash, s32* size);
void* fsLoadRootFile(FileSystem* fs, const char* name, s32* size);
void fsMakeDir(FileSystem* fs, const char* name);
bool fsExistsFile(FileSystem* fs, const char* name);
-37
View File
@@ -1,37 +0,0 @@
// 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.
#include <tic80_types.h>
const u8 EmbedIndexZip[] =
{
#include "../bin/assets/index.html.dat"
};
const s32 EmbedIndexZipSize = sizeof EmbedIndexZip;
const u8 EmbedTicJsZip[] =
{
#include "../bin/assets/tic.js.dat"
};
const s32 EmbedTicJsZipSize = sizeof EmbedTicJsZip;
+5 -3
View File
@@ -63,8 +63,9 @@ static duk_ret_t duk_print(duk_context* duk)
s32 color = duk_is_null_or_undefined(duk, 3) ? (TIC_PALETTE_SIZE-1) : duk_to_int(duk, 3);
bool fixed = duk_is_null_or_undefined(duk, 4) ? false : duk_to_boolean(duk, 4);
s32 scale = duk_is_null_or_undefined(duk, 5) ? 1 : duk_to_int(duk, 5);
bool alt = duk_is_null_or_undefined(duk, 6) ? false : duk_to_boolean(duk, 6);
s32 size = memory->api.text_ex(memory, text ? text : "nil", x, y, color, fixed, scale);
s32 size = memory->api.text_ex(memory, text ? text : "nil", x, y, color, fixed, scale, alt);
duk_push_uint(duk, size);
@@ -611,6 +612,7 @@ static duk_ret_t duk_font(duk_context* duk)
s32 height = duk_is_null_or_undefined(duk, 5) ? TIC_SPRITESIZE : duk_to_int(duk, 5);
bool fixed = duk_is_null_or_undefined(duk, 6) ? false : duk_to_boolean(duk, 6);
s32 scale = duk_is_null_or_undefined(duk, 7) ? 1 : duk_to_int(duk, 7);
bool alt = duk_is_null_or_undefined(duk, 8) ? false : duk_to_boolean(duk, 8);
if(scale == 0)
{
@@ -618,7 +620,7 @@ static duk_ret_t duk_font(duk_context* duk)
return 1;
}
s32 size = drawText(memory, text, x, y, width, height, chromakey, scale, fixed ? drawSpriteFont : drawFixedSpriteFont);
s32 size = drawText(memory, text, x, y, width, height, chromakey, scale, fixed ? drawSpriteFont : drawFixedSpriteFont, alt);
duk_push_int(duk, size);
@@ -781,7 +783,7 @@ static const struct{duk_c_function func; s32 params;} ApiFunc[] =
{NULL, 0},
{NULL, 1},
{NULL, 0},
{duk_print, 6},
{duk_print, 7},
{duk_cls, 1},
{duk_pix, 3},
{duk_line, 5},
+72
View File
@@ -0,0 +1,72 @@
{"ESC", 0*8+3, 0*8+3, true},
{"F1", 2*8+4, 0*8+3, true},
{"F2", 4*8+4, 0*8+3, true},
{"F3", 6*8+4, 0*8+3, true},
{"F4", 8*8+4, 0*8+3, true},
{"F5", 10*8+4, 0*8+3, true},
{"F6", 12*8+4, 0*8+3, true},
{"F7", 14*8+4, 0*8+3, true},
{"F8", 16*8+4, 0*8+3, true},
{"F9", 18*8+4, 0*8+3, true},
{"F10", 20*8+3, 0*8+3, true},
{"TAB", 0*8+3, 2*8+4, true},
{"`", 2*8+3, 2*8+3, false, "~"},
{"[", 4*8+3, 2*8+3, false, "{"},
{"]", 6*8+3, 2*8+3, false, "}"},
{";", 8*8+3, 2*8+3, false, ":"},
{"'", 10*8+3, 2*8+3, false, "\""},
{"-", 12*8+3, 2*8+3, false, "_"},
{"=", 14*8+3, 2*8+3, false, "+"},
{"/", 16*8+3, 2*8+3, false, "?"},
{"F11", 18*8+3, 2*8+3, true},
{"F12", 20*8+3, 2*8+3, true},
{"1", 0*8+3, 4*8+3, false, "!"},
{"2", 2*8+3, 4*8+3, false, "@"},
{"3", 4*8+3, 4*8+3, false, "#"},
{"4", 6*8+3, 4*8+3, false, "$"},
{"5", 8*8+3, 4*8+3, false, "%"},
{"6", 10*8+3, 4*8+3, false, "^"},
{"7", 12*8+3, 4*8+3, false, "&"},
{"8", 14*8+3, 4*8+3, false, "*"},
{"9", 16*8+3, 4*8+3, false, "("},
{"0", 18*8+3, 4*8+3, false, ")"},
{"BAC", 20*8+3, 4*8+4, true},
{"Q", 0*8+3, 6*8+3},
{"W", 2*8+3, 6*8+3},
{"E", 4*8+3, 6*8+3},
{"R", 6*8+3, 6*8+3},
{"T", 8*8+3, 6*8+3},
{"Y", 10*8+3, 6*8+3},
{"U", 12*8+3, 6*8+3},
{"I", 14*8+3, 6*8+3},
{"O", 16*8+3, 6*8+3},
{"P", 18*8+3, 6*8+3},
{"\\", 20*8+3, 6*8+3, false, "|"},
{"A", 1*8+3, 8*8+3},
{"S", 3*8+3, 8*8+3},
{"D", 5*8+3, 8*8+3},
{"F", 7*8+3, 8*8+3},
{"G", 9*8+3, 8*8+3},
{"H", 11*8+3, 8*8+3},
{"J", 13*8+3, 8*8+3},
{"K", 15*8+3, 8*8+3},
{"L", 17*8+3, 8*8+3},
{"ENTER", 19*8+3, 8*8+4, true},
{"Z", 2*8+3, 10*8+3},
{"X", 4*8+3, 10*8+3},
{"C", 6*8+3, 10*8+3},
{"V", 8*8+3, 10*8+3},
{"B", 10*8+3, 10*8+3},
{"N", 12*8+3, 10*8+3},
{"M", 14*8+3, 10*8+3},
{",", 16*8+3, 10*8+3, false, "<"},
{".", 18*8+3, 10*8+3, false, ">"},
{"CTRL", 0*8+5, 12*8+4, true},
{"ALT", 3*8+6, 12*8+4, true},
+407
View File
@@ -0,0 +1,407 @@
//0
tic_key_escape,
tic_key_escape,
tic_key_f1,
tic_key_f1,
tic_key_f2,
tic_key_f2,
tic_key_f3,
tic_key_f3,
tic_key_f4,
tic_key_f4,
tic_key_f5,
tic_key_f5,
tic_key_f6,
tic_key_f6,
tic_key_f7,
tic_key_f7,
tic_key_f8,
tic_key_f8,
tic_key_f9,
tic_key_f9,
tic_key_f10,
tic_key_f10,
//1
tic_key_escape,
tic_key_escape,
tic_key_f1,
tic_key_f1,
tic_key_f2,
tic_key_f2,
tic_key_f3,
tic_key_f3,
tic_key_f4,
tic_key_f4,
tic_key_f5,
tic_key_f5,
tic_key_f6,
tic_key_f6,
tic_key_f7,
tic_key_f7,
tic_key_f8,
tic_key_f8,
tic_key_f9,
tic_key_f9,
tic_key_f10,
tic_key_f10,
//2
tic_key_tab,
tic_key_tab,
tic_key_grave,
tic_key_grave,
tic_key_leftbracket,
tic_key_leftbracket,
tic_key_rightbracket,
tic_key_rightbracket,
tic_key_semicolon,
tic_key_semicolon,
tic_key_apostrophe,
tic_key_apostrophe,
tic_key_minus,
tic_key_minus,
tic_key_equals,
tic_key_equals,
tic_key_slash,
tic_key_slash,
tic_key_f11,
tic_key_f11,
tic_key_f12,
tic_key_f12,
//3
tic_key_tab,
tic_key_tab,
tic_key_grave,
tic_key_grave,
tic_key_leftbracket,
tic_key_leftbracket,
tic_key_rightbracket,
tic_key_rightbracket,
tic_key_semicolon,
tic_key_semicolon,
tic_key_apostrophe,
tic_key_apostrophe,
tic_key_minus,
tic_key_minus,
tic_key_equals,
tic_key_equals,
tic_key_slash,
tic_key_slash,
tic_key_f11,
tic_key_f11,
tic_key_f12,
tic_key_f12,
//4
tic_key_1,
tic_key_1,
tic_key_2,
tic_key_2,
tic_key_3,
tic_key_3,
tic_key_4,
tic_key_4,
tic_key_5,
tic_key_5,
tic_key_6,
tic_key_6,
tic_key_7,
tic_key_7,
tic_key_8,
tic_key_8,
tic_key_9,
tic_key_9,
tic_key_0,
tic_key_0,
tic_key_backspace,
tic_key_backspace,
//5
tic_key_1,
tic_key_1,
tic_key_2,
tic_key_2,
tic_key_3,
tic_key_3,
tic_key_4,
tic_key_4,
tic_key_5,
tic_key_5,
tic_key_6,
tic_key_6,
tic_key_7,
tic_key_7,
tic_key_8,
tic_key_8,
tic_key_9,
tic_key_9,
tic_key_0,
tic_key_0,
tic_key_backspace,
tic_key_backspace,
//6
tic_key_q,
tic_key_q,
tic_key_w,
tic_key_w,
tic_key_e,
tic_key_e,
tic_key_r,
tic_key_r,
tic_key_t,
tic_key_t,
tic_key_y,
tic_key_y,
tic_key_u,
tic_key_u,
tic_key_i,
tic_key_i,
tic_key_o,
tic_key_o,
tic_key_p,
tic_key_p,
tic_key_backslash,
tic_key_backslash,
//7
tic_key_q,
tic_key_q,
tic_key_w,
tic_key_w,
tic_key_e,
tic_key_e,
tic_key_r,
tic_key_r,
tic_key_t,
tic_key_t,
tic_key_y,
tic_key_y,
tic_key_u,
tic_key_u,
tic_key_i,
tic_key_i,
tic_key_o,
tic_key_o,
tic_key_p,
tic_key_p,
tic_key_backslash,
tic_key_backslash,
//8
tic_key_unknown,
tic_key_a,
tic_key_a,
tic_key_s,
tic_key_s,
tic_key_d,
tic_key_d,
tic_key_f,
tic_key_f,
tic_key_g,
tic_key_g,
tic_key_h,
tic_key_h,
tic_key_j,
tic_key_j,
tic_key_k,
tic_key_k,
tic_key_l,
tic_key_l,
tic_key_return,
tic_key_return,
tic_key_return,
//9
tic_key_unknown,
tic_key_a,
tic_key_a,
tic_key_s,
tic_key_s,
tic_key_d,
tic_key_d,
tic_key_f,
tic_key_f,
tic_key_g,
tic_key_g,
tic_key_h,
tic_key_h,
tic_key_j,
tic_key_j,
tic_key_k,
tic_key_k,
tic_key_l,
tic_key_l,
tic_key_return,
tic_key_return,
tic_key_return,
//10
tic_key_shift,
tic_key_shift,
tic_key_z,
tic_key_z,
tic_key_x,
tic_key_x,
tic_key_c,
tic_key_c,
tic_key_v,
tic_key_v,
tic_key_b,
tic_key_b,
tic_key_n,
tic_key_n,
tic_key_m,
tic_key_m,
tic_key_comma,
tic_key_comma,
tic_key_period,
tic_key_period,
tic_key_return,
tic_key_return,
//11
tic_key_shift,
tic_key_shift,
tic_key_z,
tic_key_z,
tic_key_x,
tic_key_x,
tic_key_c,
tic_key_c,
tic_key_v,
tic_key_v,
tic_key_b,
tic_key_b,
tic_key_n,
tic_key_n,
tic_key_m,
tic_key_m,
tic_key_comma,
tic_key_comma,
tic_key_period,
tic_key_period,
tic_key_return,
tic_key_return,
//12
tic_key_ctrl,
tic_key_ctrl,
tic_key_ctrl,
tic_key_alt,
tic_key_alt,
tic_key_alt,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
//13
tic_key_ctrl,
tic_key_ctrl,
tic_key_ctrl,
tic_key_alt,
tic_key_alt,
tic_key_alt,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_space,
tic_key_unknown,
tic_key_unknown,
tic_key_up,
tic_key_up,
tic_key_unknown,
tic_key_unknown,
//14
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_up,
tic_key_up,
tic_key_unknown,
tic_key_unknown,
//15
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_left,
tic_key_left,
tic_key_down,
tic_key_down,
tic_key_right,
tic_key_right,
//16
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_unknown,
tic_key_left,
tic_key_left,
tic_key_down,
tic_key_down,
tic_key_right,
tic_key_right,
-232
View File
@@ -1,232 +0,0 @@
[0] = tic_key_unknown,
[1] = tic_key_unknown,
[2] = tic_key_unknown,
[3] = tic_key_unknown,
[SDL_SCANCODE_A] = tic_key_a,
[SDL_SCANCODE_B] = tic_key_b,
[SDL_SCANCODE_C] = tic_key_c,
[SDL_SCANCODE_D] = tic_key_d,
[SDL_SCANCODE_E] = tic_key_e,
[SDL_SCANCODE_F] = tic_key_f,
[SDL_SCANCODE_G] = tic_key_g,
[SDL_SCANCODE_H] = tic_key_h,
[SDL_SCANCODE_I] = tic_key_i,
[SDL_SCANCODE_J] = tic_key_j,
[SDL_SCANCODE_K] = tic_key_k,
[SDL_SCANCODE_L] = tic_key_l,
[SDL_SCANCODE_M] = tic_key_m,
[SDL_SCANCODE_N] = tic_key_n,
[SDL_SCANCODE_O] = tic_key_o,
[SDL_SCANCODE_P] = tic_key_p,
[SDL_SCANCODE_Q] = tic_key_q,
[SDL_SCANCODE_R] = tic_key_r,
[SDL_SCANCODE_S] = tic_key_s,
[SDL_SCANCODE_T] = tic_key_t,
[SDL_SCANCODE_U] = tic_key_u,
[SDL_SCANCODE_V] = tic_key_v,
[SDL_SCANCODE_W] = tic_key_w,
[SDL_SCANCODE_X] = tic_key_x,
[SDL_SCANCODE_Y] = tic_key_y,
[SDL_SCANCODE_Z] = tic_key_z,
[SDL_SCANCODE_1] = tic_key_1,
[SDL_SCANCODE_2] = tic_key_2,
[SDL_SCANCODE_3] = tic_key_3,
[SDL_SCANCODE_4] = tic_key_4,
[SDL_SCANCODE_5] = tic_key_5,
[SDL_SCANCODE_6] = tic_key_6,
[SDL_SCANCODE_7] = tic_key_7,
[SDL_SCANCODE_8] = tic_key_8,
[SDL_SCANCODE_9] = tic_key_9,
[SDL_SCANCODE_0] = tic_key_0,
[SDL_SCANCODE_RETURN] = tic_key_return,
[SDL_SCANCODE_ESCAPE] = tic_key_escape,
[SDL_SCANCODE_BACKSPACE] = tic_key_backspace,
[SDL_SCANCODE_TAB] = tic_key_tab,
[SDL_SCANCODE_SPACE] = tic_key_space,
[SDL_SCANCODE_MINUS] = tic_key_minus,
[SDL_SCANCODE_EQUALS] = tic_key_equals,
[SDL_SCANCODE_LEFTBRACKET] = tic_key_leftbracket,
[SDL_SCANCODE_RIGHTBRACKET] = tic_key_rightbracket,
[SDL_SCANCODE_BACKSLASH] = tic_key_backslash,
[50] = tic_key_unknown,
[SDL_SCANCODE_SEMICOLON] = tic_key_semicolon,
[SDL_SCANCODE_APOSTROPHE] = tic_key_apostrophe,
[SDL_SCANCODE_GRAVE] = tic_key_grave,
[SDL_SCANCODE_COMMA] = tic_key_comma,
[SDL_SCANCODE_PERIOD] = tic_key_period,
[SDL_SCANCODE_SLASH] = tic_key_slash,
[SDL_SCANCODE_CAPSLOCK] = tic_key_capslock,
[SDL_SCANCODE_F1] = tic_key_f1,
[SDL_SCANCODE_F2] = tic_key_f2,
[SDL_SCANCODE_F3] = tic_key_f3,
[SDL_SCANCODE_F4] = tic_key_f4,
[SDL_SCANCODE_F5] = tic_key_f5,
[SDL_SCANCODE_F6] = tic_key_f6,
[SDL_SCANCODE_F7] = tic_key_f7,
[SDL_SCANCODE_F8] = tic_key_f8,
[SDL_SCANCODE_F9] = tic_key_f9,
[SDL_SCANCODE_F10] = tic_key_f10,
[SDL_SCANCODE_F11] = tic_key_f11,
[SDL_SCANCODE_F12] = tic_key_f12,
[70] = tic_key_unknown,
[71] = tic_key_unknown,
[72] = tic_key_unknown,
[SDL_SCANCODE_INSERT] = tic_key_insert,
[SDL_SCANCODE_HOME] = tic_key_home,
[SDL_SCANCODE_PAGEUP] = tic_key_pageup,
[SDL_SCANCODE_DELETE] = tic_key_delete,
[SDL_SCANCODE_END] = tic_key_end,
[SDL_SCANCODE_PAGEDOWN] = tic_key_pagedown,
[SDL_SCANCODE_RIGHT] = tic_key_right,
[SDL_SCANCODE_LEFT] = tic_key_left,
[SDL_SCANCODE_DOWN] = tic_key_down,
[SDL_SCANCODE_UP] = tic_key_up,
[83] = tic_key_unknown,
[84] = tic_key_unknown,
[85] = tic_key_unknown,
[86] = tic_key_unknown,
[87] = tic_key_unknown,
[88] = tic_key_unknown,
[89] = tic_key_unknown,
[90] = tic_key_unknown,
[91] = tic_key_unknown,
[92] = tic_key_unknown,
[93] = tic_key_unknown,
[94] = tic_key_unknown,
[95] = tic_key_unknown,
[96] = tic_key_unknown,
[97] = tic_key_unknown,
[98] = tic_key_unknown,
[99] = tic_key_unknown,
[100] = tic_key_unknown,
[101] = tic_key_unknown,
[102] = tic_key_unknown,
[103] = tic_key_unknown,
[104] = tic_key_unknown,
[105] = tic_key_unknown,
[106] = tic_key_unknown,
[107] = tic_key_unknown,
[108] = tic_key_unknown,
[109] = tic_key_unknown,
[110] = tic_key_unknown,
[111] = tic_key_unknown,
[112] = tic_key_unknown,
[113] = tic_key_unknown,
[114] = tic_key_unknown,
[115] = tic_key_unknown,
[116] = tic_key_unknown,
[117] = tic_key_unknown,
[118] = tic_key_unknown,
[119] = tic_key_unknown,
[120] = tic_key_unknown,
[121] = tic_key_unknown,
[122] = tic_key_unknown,
[123] = tic_key_unknown,
[124] = tic_key_unknown,
[125] = tic_key_unknown,
[126] = tic_key_unknown,
[127] = tic_key_unknown,
[128] = tic_key_unknown,
[129] = tic_key_unknown,
[130] = tic_key_unknown,
[131] = tic_key_unknown,
[132] = tic_key_unknown,
[133] = tic_key_unknown,
[134] = tic_key_unknown,
[135] = tic_key_unknown,
[136] = tic_key_unknown,
[137] = tic_key_unknown,
[138] = tic_key_unknown,
[139] = tic_key_unknown,
[140] = tic_key_unknown,
[141] = tic_key_unknown,
[142] = tic_key_unknown,
[143] = tic_key_unknown,
[144] = tic_key_unknown,
[145] = tic_key_unknown,
[146] = tic_key_unknown,
[147] = tic_key_unknown,
[148] = tic_key_unknown,
[149] = tic_key_unknown,
[150] = tic_key_unknown,
[151] = tic_key_unknown,
[152] = tic_key_unknown,
[153] = tic_key_unknown,
[154] = tic_key_unknown,
[155] = tic_key_unknown,
[156] = tic_key_unknown,
[157] = tic_key_unknown,
[158] = tic_key_unknown,
[159] = tic_key_unknown,
[160] = tic_key_unknown,
[161] = tic_key_unknown,
[162] = tic_key_unknown,
[163] = tic_key_unknown,
[164] = tic_key_unknown,
[165] = tic_key_unknown,
[166] = tic_key_unknown,
[167] = tic_key_unknown,
[168] = tic_key_unknown,
[169] = tic_key_unknown,
[170] = tic_key_unknown,
[171] = tic_key_unknown,
[172] = tic_key_unknown,
[173] = tic_key_unknown,
[174] = tic_key_unknown,
[175] = tic_key_unknown,
[176] = tic_key_unknown,
[177] = tic_key_unknown,
[178] = tic_key_unknown,
[179] = tic_key_unknown,
[180] = tic_key_unknown,
[181] = tic_key_unknown,
[182] = tic_key_unknown,
[183] = tic_key_unknown,
[184] = tic_key_unknown,
[185] = tic_key_unknown,
[186] = tic_key_unknown,
[187] = tic_key_unknown,
[188] = tic_key_unknown,
[189] = tic_key_unknown,
[190] = tic_key_unknown,
[191] = tic_key_unknown,
[192] = tic_key_unknown,
[193] = tic_key_unknown,
[194] = tic_key_unknown,
[195] = tic_key_unknown,
[196] = tic_key_unknown,
[197] = tic_key_unknown,
[198] = tic_key_unknown,
[199] = tic_key_unknown,
[200] = tic_key_unknown,
[201] = tic_key_unknown,
[202] = tic_key_unknown,
[203] = tic_key_unknown,
[204] = tic_key_unknown,
[205] = tic_key_unknown,
[206] = tic_key_unknown,
[207] = tic_key_unknown,
[208] = tic_key_unknown,
[209] = tic_key_unknown,
[210] = tic_key_unknown,
[211] = tic_key_unknown,
[212] = tic_key_unknown,
[213] = tic_key_unknown,
[214] = tic_key_unknown,
[215] = tic_key_unknown,
[216] = tic_key_unknown,
[217] = tic_key_unknown,
[218] = tic_key_unknown,
[219] = tic_key_unknown,
[220] = tic_key_unknown,
[221] = tic_key_unknown,
[222] = tic_key_unknown,
[223] = tic_key_unknown,
[SDL_SCANCODE_LCTRL] = tic_key_ctrl,
[SDL_SCANCODE_LSHIFT] = tic_key_shift,
[SDL_SCANCODE_LALT] = tic_key_alt,
[SDL_SCANCODE_LGUI] = tic_key_ctrl,
[SDL_SCANCODE_RCTRL] = tic_key_ctrl,
[SDL_SCANCODE_RSHIFT] = tic_key_shift,
[SDL_SCANCODE_RALT] = tic_key_alt,
[SDL_SCANCODE_RGUI] = tic_key_ctrl,
+82
View File
@@ -0,0 +1,82 @@
[tic_key_unknown] = SDLK_UNKNOWN,
[tic_key_a] = SDLK_a,
[tic_key_b] = SDLK_b,
[tic_key_c] = SDLK_c,
[tic_key_d] = SDLK_d,
[tic_key_e] = SDLK_e,
[tic_key_f] = SDLK_f,
[tic_key_g] = SDLK_g,
[tic_key_h] = SDLK_h,
[tic_key_i] = SDLK_i,
[tic_key_j] = SDLK_j,
[tic_key_k] = SDLK_k,
[tic_key_l] = SDLK_l,
[tic_key_m] = SDLK_m,
[tic_key_n] = SDLK_n,
[tic_key_o] = SDLK_o,
[tic_key_p] = SDLK_p,
[tic_key_q] = SDLK_q,
[tic_key_r] = SDLK_r,
[tic_key_s] = SDLK_s,
[tic_key_t] = SDLK_t,
[tic_key_u] = SDLK_u,
[tic_key_v] = SDLK_v,
[tic_key_w] = SDLK_w,
[tic_key_x] = SDLK_x,
[tic_key_y] = SDLK_y,
[tic_key_z] = SDLK_z,
[tic_key_0] = SDLK_0,
[tic_key_1] = SDLK_1,
[tic_key_2] = SDLK_2,
[tic_key_3] = SDLK_3,
[tic_key_4] = SDLK_4,
[tic_key_5] = SDLK_5,
[tic_key_6] = SDLK_6,
[tic_key_7] = SDLK_7,
[tic_key_8] = SDLK_8,
[tic_key_9] = SDLK_9,
[tic_key_minus] = SDLK_MINUS,
[tic_key_equals] = SDLK_EQUALS,
[tic_key_leftbracket] = SDLK_LEFTBRACKET,
[tic_key_rightbracket] = SDLK_RIGHTBRACKET,
[tic_key_backslash] = SDLK_BACKSLASH,
[tic_key_semicolon] = SDLK_SEMICOLON,
[tic_key_apostrophe] = SDLK_QUOTE,
[tic_key_grave] = SDLK_BACKQUOTE,
[tic_key_comma] = SDLK_COMMA,
[tic_key_period] = SDLK_PERIOD,
[tic_key_slash] = SDLK_SLASH,
[tic_key_space] = SDLK_SPACE,
[tic_key_tab] = SDLK_TAB,
[tic_key_return] = SDLK_RETURN,
[tic_key_backspace] = SDLK_BACKSPACE,
[tic_key_delete] = SDLK_DELETE,
[tic_key_insert] = SDLK_INSERT,
[tic_key_pageup] = SDLK_PAGEUP,
[tic_key_pagedown] = SDLK_PAGEDOWN,
[tic_key_home] = SDLK_HOME,
[tic_key_end] = SDLK_END,
[tic_key_up] = SDLK_UP,
[tic_key_down] = SDLK_DOWN,
[tic_key_left] = SDLK_LEFT,
[tic_key_right] = SDLK_RIGHT,
[tic_key_capslock] = SDLK_CAPSLOCK,
[tic_key_ctrl] = SDLK_LCTRL,
[tic_key_shift] = SDLK_LSHIFT,
[tic_key_alt] = SDLK_LALT,
[tic_key_escape] = SDLK_ESCAPE,
[tic_key_f1] = SDLK_F1,
[tic_key_f2] = SDLK_F2,
[tic_key_f3] = SDLK_F3,
[tic_key_f4] = SDLK_F4,
[tic_key_f5] = SDLK_F5,
[tic_key_f6] = SDLK_F6,
[tic_key_f7] = SDLK_F7,
[tic_key_f8] = SDLK_F8,
[tic_key_f9] = SDLK_F9,
[tic_key_f10] = SDLK_F10,
[tic_key_f11] = SDLK_F11,
[tic_key_f12] = SDLK_F12,
+19 -9
View File
@@ -933,6 +933,7 @@ static s32 lua_font(lua_State* lua)
u8 chromakey = 0;
bool fixed = false;
s32 scale = 1;
bool alt = false;
if(top >= 3)
{
@@ -955,6 +956,11 @@ static s32 lua_font(lua_State* lua)
if(top >= 8)
{
scale = getLuaNumber(lua, 8);
if(top >= 9)
{
alt = lua_toboolean(lua, 9);
}
}
}
}
@@ -967,7 +973,7 @@ static s32 lua_font(lua_State* lua)
return 1;
}
s32 size = drawText(memory, text, x, y, width, height, chromakey, scale, fixed ? drawSpriteFont : drawFixedSpriteFont);
s32 size = drawText(memory, text, x, y, width, height, chromakey, scale, fixed ? drawSpriteFont : drawFixedSpriteFont, alt);
lua_pushinteger(lua, size);
@@ -991,6 +997,7 @@ static s32 lua_print(lua_State* lua)
s32 color = TIC_PALETTE_SIZE-1;
bool fixed = false;
s32 scale = 1;
bool alt = false;
const char* text = printString(lua, 1);
@@ -1010,6 +1017,11 @@ static s32 lua_print(lua_State* lua)
if(top >= 6)
{
scale = getLuaNumber(lua, 6);
if(top >= 7)
{
alt = lua_toboolean(lua, 7);
}
}
}
}
@@ -1021,7 +1033,7 @@ static s32 lua_print(lua_State* lua)
return 1;
}
s32 size = memory->api.text_ex(memory, text ? text : "nil", x, y, color, fixed, scale);
s32 size = memory->api.text_ex(memory, text ? text : "nil", x, y, color, fixed, scale, alt);
lua_pushinteger(lua, size);
@@ -1402,10 +1414,12 @@ static const tic_outline_item* getLuaOutline(const char* code, s32* size)
return items;
}
void evalLua(tic_mem* tic, const char* code) {
static void evalLua(tic_mem* tic, const char* code) {
tic_machine* machine = (tic_machine*)tic;
lua_State* lua = machine->lua;
if (!lua) return;
lua_settop(lua, 0);
if(luaL_loadstring(lua, code) != LUA_OK || lua_pcall(lua, 0, LUA_MULTRET, 0) != LUA_OK)
@@ -1414,10 +1428,6 @@ void evalLua(tic_mem* tic, const char* code) {
}
}
void evalPlaceholder(tic_mem* tic, const char* code) {
printf("TODO: not yet implemented\n.");
}
static const tic_script_config LuaSyntaxConfig =
{
.init = initLua,
@@ -1597,7 +1607,7 @@ static const tic_script_config MoonSyntaxConfig =
.getOutline = getMoonOutline,
.parse = parseCode,
.eval = evalPlaceholder,
.eval = NULL,
.blockCommentStart = NULL,
.blockCommentEnd = NULL,
@@ -1738,7 +1748,7 @@ static const tic_outline_item* getFennelOutline(const char* code, s32* size)
return items;
}
void evalFennel(tic_mem* tic, const char* code) {
static void evalFennel(tic_mem* tic, const char* code) {
tic_machine* machine = (tic_machine*)tic;
lua_State* fennel = machine->lua;
+16 -14
View File
@@ -82,19 +82,16 @@ typedef struct
Clip clip;
tic_sound_register_data registers[TIC_SOUND_CHANNELS];
struct
{
tic_sound_register_data left[TIC_SOUND_CHANNELS];
tic_sound_register_data right[TIC_SOUND_CHANNELS];
} registers;
Channel channels[TIC_SOUND_CHANNELS];
struct
{
enum
{
MusicStop = 0,
MusicPlayFrame,
MusicPlay,
} play;
s32 ticks;
Channel channels[TIC_SOUND_CHANNELS];
} music;
@@ -141,7 +138,12 @@ typedef struct
};
blip_buffer_t* blip;
struct
{
blip_buffer_t* left;
blip_buffer_t* right;
} blip;
s32 samplerate;
struct
@@ -168,10 +170,10 @@ typedef struct
} tic_machine;
typedef s32(DrawCharFunc)(tic_mem* memory, u8 symbol, s32 x, s32 y, s32 width, s32 height, u8 color, s32 scale);
s32 drawText(tic_mem* memory, const char* text, s32 x, s32 y, s32 width, s32 height, u8 color, s32 scale, DrawCharFunc* func);
s32 drawSpriteFont(tic_mem* memory, u8 symbol, s32 x, s32 y, s32 width, s32 height, u8 chromakey, s32 scale);
s32 drawFixedSpriteFont(tic_mem* memory, u8 index, s32 x, s32 y, s32 width, s32 height, u8 chromakey, s32 scale);
typedef s32(DrawCharFunc)(tic_mem* memory, u8 symbol, s32 x, s32 y, s32 width, s32 height, u8 color, s32 scale, bool alt);
s32 drawText(tic_mem* memory, const char* text, s32 x, s32 y, s32 width, s32 height, u8 color, s32 scale, DrawCharFunc* func, bool alt);
s32 drawSpriteFont(tic_mem* memory, u8 symbol, s32 x, s32 y, s32 width, s32 height, u8 chromakey, s32 scale, bool alt);
s32 drawFixedSpriteFont(tic_mem* memory, u8 index, s32 x, s32 y, s32 width, s32 height, u8 chromakey, s32 scale, bool alt);
void parseCode(const tic_script_config* config, const char* start, u8* color, const tic_code_theme* theme);
#if defined(TIC_BUILD_WITH_SQUIRREL)
+7 -12
View File
@@ -328,17 +328,15 @@ static void drawTileIndex(Map* map, s32 x, s32 y)
{
char buf[] = "#999";
sprintf(buf, "#%03i", index);
map->tic->api.text(map->tic, buf, x, y, (tic_color_light_blue));
map->tic->api.text(map->tic, buf, x, y, (tic_color_light_blue), false);
}
}
static void drawMapToolbar(Map* map, s32 x, s32 y)
{
tic_mem* tic = map->tic;
map->tic->api.rect(map->tic, 0, 0, TIC80_WIDTH, TOOLBAR_SIZE, (tic_color_white));
drawTileIndex(map, TIC80_WIDTH/2 - tic->font.width, y);
drawTileIndex(map, TIC80_WIDTH/2 - TIC_FONT_WIDTH, y);
x = drawSheetButton(map, TIC80_WIDTH, 0);
x = drawFillButton(map, x, 0);
@@ -419,8 +417,6 @@ static void drawSheetOvr(Map* map, s32 x, s32 y)
static void drawCursorPos(Map* map, s32 x, s32 y)
{
tic_mem* tic = map->tic;
char pos[] = "999:999";
s32 tx = 0, ty = 0;
@@ -428,16 +424,16 @@ static void drawCursorPos(Map* map, s32 x, s32 y)
sprintf(pos, "%03i:%03i", tx, ty);
s32 width = map->tic->api.text(map->tic, pos, TIC80_WIDTH, 0, (tic_color_gray));
s32 width = map->tic->api.text(map->tic, pos, TIC80_WIDTH, 0, (tic_color_gray), false);
s32 px = x + (TIC_SPRITESIZE + 3);
if(px + width >= TIC80_WIDTH) px = x - (width + 2);
s32 py = y - (tic->font.height + 2);
s32 py = y - (TIC_FONT_HEIGHT + 2);
if(py <= TOOLBAR_SIZE) py = y + (TIC_SPRITESIZE + 3);
map->tic->api.rect(map->tic, px - 1, py - 1, width + 1, tic->font.height + 1, (tic_color_white));
map->tic->api.text(map->tic, pos, px, py, (tic_color_light_blue));
map->tic->api.rect(map->tic, px - 1, py - 1, width + 1, TIC_FONT_HEIGHT + 1, (tic_color_white));
map->tic->api.text(map->tic, pos, px, py, (tic_color_light_blue), false);
}
static void setMapSprite(Map* map, s32 x, s32 y)
@@ -1064,14 +1060,13 @@ static void processKeyboard(Map* map)
static void tick(Map* map)
{
tic_mem* tic = map->tic;
map->tickCounter++;
processKeyboard(map);
map->tic->api.clear(map->tic, TIC_COLOR_BG);
drawSheet(map, TIC80_WIDTH - TIC_SPRITESHEET_SIZE - 1, TOOLBAR_SIZE);
drawMapToolbar(map, TIC80_WIDTH - 9*tic->font.width, 1);
drawMapToolbar(map, TIC80_WIDTH - 9*TIC_FONT_WIDTH, 1);
drawToolbar(map->tic, TIC_COLOR_BG, false);
}
+13 -13
View File
@@ -119,8 +119,8 @@ static void drawDialog(Menu* menu)
{
static const char Label[] = "GAME MENU";
s32 size = tic->api.text(tic, Label, 0, -tic->font.height, 0);
tic->api.text(tic, Label, rect.x + (DIALOG_WIDTH - size)/2, rect.y-(TOOLBAR_SIZE-2), (tic_color_gray));
s32 size = tic->api.text(tic, Label, 0, -TIC_FONT_HEIGHT, 0, false);
tic->api.text(tic, Label, rect.x + (DIALOG_WIDTH - size)/2, rect.y-(TOOLBAR_SIZE-2), (tic_color_gray), false);
}
{
@@ -157,7 +157,7 @@ static void drawTabDisabled(Menu* menu, s32 x, s32 y, s32 id)
{
char buf[] = "#1";
sprintf(buf, "#%i", id+1);
tic->api.fixed_text(tic, buf, x+2, y, (over ? tic_color_light_blue : tic_color_gray));
tic->api.fixed_text(tic, buf, x+2, y, (over ? tic_color_light_blue : tic_color_gray), false);
}
}
@@ -174,7 +174,7 @@ static void drawTab(Menu* menu, s32 x, s32 y, s32 id)
{
char buf[] = "#1";
sprintf(buf, "#%i", id+1);
tic->api.fixed_text(tic, buf, x+2, y, (tic_color_gray));
tic->api.fixed_text(tic, buf, x+2, y, (tic_color_gray), false);
}
}
@@ -221,7 +221,7 @@ static void drawPlayerButtons(Menu* menu, s32 x, s32 y)
if(strlen(label) > MaxChars)
label[MaxChars] = '\0';
tic->api.text(tic, label, rect.x+10, rect.y+2, (over ? tic_color_gray : tic_color_black));
tic->api.text(tic, label, rect.x+10, rect.y+2, (over ? tic_color_gray : tic_color_black), false);
}
}
@@ -253,7 +253,7 @@ static void drawGamepadMenu(Menu* menu)
static const char Label[] = "BACK";
tic_rect rect = {dlgRect.x + 25, dlgRect.y + 56, (sizeof(Label)-1)*tic->font.width, tic->font.height};
tic_rect rect = {dlgRect.x + 25, dlgRect.y + 56, (sizeof(Label)-1)*TIC_FONT_WIDTH, TIC_FONT_HEIGHT};
bool over = false;
bool down = false;
@@ -280,12 +280,12 @@ static void drawGamepadMenu(Menu* menu)
if(down)
{
tic->api.text(tic, Label, rect.x, rect.y+1, (tic_color_light_blue));
tic->api.text(tic, Label, rect.x, rect.y+1, (tic_color_light_blue), false);
}
else
{
tic->api.text(tic, Label, rect.x, rect.y+1, (tic_color_black));
tic->api.text(tic, Label, rect.x, rect.y, (over ? tic_color_light_blue : tic_color_white));
tic->api.text(tic, Label, rect.x, rect.y+1, (tic_color_black), false);
tic->api.text(tic, Label, rect.x, rect.y, (over ? tic_color_light_blue : tic_color_white), false);
}
{
@@ -321,7 +321,7 @@ static void drawMainMenu(Menu* menu)
{
if(!*Rows[i])continue;
tic_rect label = {rect.x + 22, rect.y + (tic->font.height+1)*i + 16, 86, tic->font.height+1};
tic_rect label = {rect.x + 22, rect.y + (TIC_FONT_HEIGHT+1)*i + 16, 86, TIC_FONT_HEIGHT+1};
bool over = false;
bool down = false;
@@ -346,12 +346,12 @@ static void drawMainMenu(Menu* menu)
if(down)
{
tic->api.text(tic, Rows[i], label.x, label.y+1, (tic_color_light_blue));
tic->api.text(tic, Rows[i], label.x, label.y+1, (tic_color_light_blue), false);
}
else
{
tic->api.text(tic, Rows[i], label.x, label.y+1, (tic_color_black));
tic->api.text(tic, Rows[i], label.x, label.y, (over ? tic_color_light_blue : tic_color_white));
tic->api.text(tic, Rows[i], label.x, label.y+1, (tic_color_black), false);
tic->api.text(tic, Rows[i], label.x, label.y, (over ? tic_color_light_blue : tic_color_white), false);
}
if(i == menu->main.focus)
+84 -98
View File
@@ -49,9 +49,9 @@ static void redo(Music* music)
history_redo(music->history);
}
const tic_music_pos* getMusicPos(Music* music)
static const tic_sound_state* getMusicPos(Music* music)
{
return &music->tic->ram.music_pos;
return &music->tic->ram.sound_state;
}
static void drawDownBorder(Music* music, s32 x, s32 y, s32 w, s32 h)
@@ -66,7 +66,6 @@ static void drawDownBorder(Music* music, s32 x, s32 y, s32 w, s32 h)
static void drawEditbox(Music* music, s32 x, s32 y, s32 value, void(*set)(Music*, s32, s32 channel), s32 channel)
{
tic_mem* tic = music->tic;
static const u8 LeftArrow[] =
{
0b00100000,
@@ -91,12 +90,8 @@ static void drawEditbox(Music* music, s32 x, s32 y, s32 value, void(*set)(Music*
0b00000000,
};
enum{ArrowWidth = 4, ArrowHeight = 6};
x -= ArrowWidth + 2;
{
tic_rect rect = { x, y, ArrowWidth, ArrowHeight };
tic_rect rect = { x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT };
bool over = false;
bool down = false;
@@ -116,9 +111,9 @@ static void drawEditbox(Music* music, s32 x, s32 y, s32 value, void(*set)(Music*
}
{
x += ArrowWidth + 2;
x += TIC_FONT_WIDTH;
tic_rect rect = { x-1, y-1, tic->font.width*2+1, tic->font.height+1 };
tic_rect rect = { x-1, y-1, TIC_FONT_WIDTH*2+1, TIC_FONT_HEIGHT+1 };
if (checkMousePos(&rect))
{
@@ -130,7 +125,7 @@ static void drawEditbox(Music* music, s32 x, s32 y, s32 value, void(*set)(Music*
music->tracker.col = channel * CHANNEL_COLS;
s32 mx = getMouseX() - rect.x;
music->tracker.patternCol = mx / tic->font.width;
music->tracker.patternCol = mx / TIC_FONT_WIDTH;
}
}
@@ -139,18 +134,18 @@ static void drawEditbox(Music* music, s32 x, s32 y, s32 value, void(*set)(Music*
if(music->tracker.row == -1 && music->tracker.col / CHANNEL_COLS == channel)
{
music->tic->api.rect(music->tic, x - 1 + music->tracker.patternCol * tic->font.width, y - 1, tic->font.width + 1, tic->font.height + 1, (tic_color_red));
music->tic->api.rect(music->tic, x - 1 + music->tracker.patternCol * TIC_FONT_WIDTH, y - 1, TIC_FONT_WIDTH + 1, TIC_FONT_HEIGHT + 1, (tic_color_red));
}
char val[] = "99";
sprintf(val, "%02i", value);
music->tic->api.fixed_text(music->tic, val, x, y, (tic_color_white));
music->tic->api.fixed_text(music->tic, val, x, y, (tic_color_white), false);
}
{
x += 2*tic->font.width;
x += 2*TIC_FONT_WIDTH;
tic_rect rect = { x, y, ArrowWidth, ArrowHeight };
tic_rect rect = { x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT };
bool over = false;
bool down = false;
@@ -172,14 +167,13 @@ static void drawEditbox(Music* music, s32 x, s32 y, s32 value, void(*set)(Music*
static void drawSwitch(Music* music, s32 x, s32 y, const char* label, s32 value, void(*set)(Music*, s32, void* data), void* data)
{
tic_mem* tic = music->tic;
static const u8 LeftArrow[] =
{
0b00100000,
0b01100000,
0b11100000,
0b01100000,
0b00100000,
0b00010000,
0b00110000,
0b01110000,
0b00110000,
0b00010000,
0b00000000,
0b00000000,
0b00000000,
@@ -187,25 +181,23 @@ static void drawSwitch(Music* music, s32 x, s32 y, const char* label, s32 value,
static const u8 RightArrow[] =
{
0b10000000,
0b11000000,
0b11100000,
0b11000000,
0b10000000,
0b01000000,
0b01100000,
0b01110000,
0b01100000,
0b01000000,
0b00000000,
0b00000000,
0b00000000,
};
enum{ArrowWidth = 4, ArrowHeight = 6};
music->tic->api.text(music->tic, label, x, y+1, (tic_color_black));
music->tic->api.text(music->tic, label, x, y, (tic_color_white));
music->tic->api.text(music->tic, label, x, y+1, (tic_color_black), false);
music->tic->api.text(music->tic, label, x, y, (tic_color_white), false);
{
x += (s32)strlen(label)*tic->font.width + 1;
x += (s32)strlen(label)*TIC_FONT_WIDTH;
tic_rect rect = { x, y, ArrowWidth, ArrowHeight};
tic_rect rect = { x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT };
bool over = false;
bool down = false;
@@ -226,17 +218,16 @@ static void drawSwitch(Music* music, s32 x, s32 y, const char* label, s32 value,
}
{
x += ArrowWidth;
char val[] = "999";
sprintf(val, "%02i", value);
music->tic->api.fixed_text(music->tic, val, x, y+1, (tic_color_black));
music->tic->api.fixed_text(music->tic, val, x, y, (tic_color_white));
music->tic->api.fixed_text(music->tic, val, x + TIC_FONT_WIDTH, y+1, (tic_color_black), false);
music->tic->api.fixed_text(music->tic, val, x += TIC_FONT_WIDTH, y, (tic_color_white), false);
}
{
x += (value > 99 ? 3 : 2)*tic->font.width;
x += (value > 99 ? 3 : 2)*TIC_FONT_WIDTH;
tic_rect rect = { x, y, ArrowWidth, ArrowHeight};
tic_rect rect = { x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT };
bool over = false;
bool down = false;
@@ -307,8 +298,8 @@ static void upRow(Music* music)
static void downRow(Music* music)
{
const tic_music_pos* pos = getMusicPos(music);
if(pos->track == music->track && music->tracker.follow) return;
const tic_sound_state* pos = getMusicPos(music);
if(pos->music.track == music->track && music->tracker.follow) return;
if (music->tracker.row < getRows(music) - 1)
{
@@ -395,17 +386,17 @@ static void downFrame(Music* music)
static bool checkPlayFrame(Music* music, s32 frame)
{
const tic_music_pos* pos = getMusicPos(music);
const tic_sound_state* pos = getMusicPos(music);
return pos->track == music->track &&
pos->frame == frame;
return pos->music.track == music->track &&
pos->music.frame == frame;
}
static bool checkPlayRow(Music* music, s32 row)
{
const tic_music_pos* pos = getMusicPos(music);
const tic_sound_state* pos = getMusicPos(music);
return checkPlayFrame(music, music->tracker.frame) && pos->row == row;
return checkPlayFrame(music, music->tracker.frame) && pos->music.row == row;
}
static tic_track_pattern* getPattern(Music* music, s32 channel)
@@ -759,6 +750,9 @@ static void processTrackerKeyboard(Music* music)
return;
}
if(tic->api.key(tic, tic_key_ctrl) || tic->api.key(tic, tic_key_alt))
return;
bool shift = tic->api.key(tic, tic_key_shift);
if(shift)
@@ -795,8 +789,8 @@ static void processTrackerKeyboard(Music* music)
else if(keyWasPressed(tic_key_space)) playNote(music);
else if(keyWasPressed(tic_key_return))
{
const tic_music_pos* pos = getMusicPos(music);
pos->track < 0
const tic_sound_state* pos = getMusicPos(music);
pos->music.track < 0
? (shift ? playFrameRow(music) : playFrame(music))
: stopTrack(music);
}
@@ -958,10 +952,14 @@ static void processTrackerKeyboard(Music* music)
static void processPatternKeyboard(Music* music)
{
tic_mem* tic = music->tic;
s32 channel = music->tracker.col / CHANNEL_COLS;
if(tic->api.key(tic, tic_key_ctrl) || tic->api.key(tic, tic_key_alt))
return;
if(keyWasPressed(tic_key_delete)) setChannelPatternValue(music, 0, channel);
else if(keyWasPressed(tic_key_tab)) nextPattern(music);
else if(keyWasPressed(tic_key_tab)) nextPattern(music);
else if(keyWasPressed(tic_key_left)) patternColLeft(music);
else if(keyWasPressed(tic_key_right)) patternColRight(music);
else if(keyWasPressed(tic_key_down)
@@ -1012,8 +1010,6 @@ static void processKeyboard(Music* music)
{
tic_mem* tic = music->tic;
if(tic->ram.input.keyboard.data == 0) return;
switch(getClipboardEvent())
{
case TIC_CLIPBOARD_CUT: copyToClipboard(music, true); break;
@@ -1114,28 +1110,24 @@ static void setRows(Music* music, s32 delta, void* data)
static void drawTopPanel(Music* music, s32 x, s32 y)
{
tic_mem* tic = music->tic;
tic_track* track = getTrack(music);
drawSwitch(music, x, y, "TRACK", music->track, setIndex, NULL);
drawSwitch(music, x += tic->font.width * 10, y, "TEMPO", track->tempo + DEFAULT_TEMPO, setTempo, NULL);
drawSwitch(music, x += tic->font.width * 11, y, "SPD", track->speed + DEFAULT_SPEED, setSpeed, NULL);
drawSwitch(music, x += tic->font.width * 8, y, "ROWS", MUSIC_PATTERN_ROWS - track->rows, setRows, NULL);
drawSwitch(music, x += TIC_FONT_WIDTH * 10, y, "TEMPO", track->tempo + DEFAULT_TEMPO, setTempo, NULL);
drawSwitch(music, x += TIC_FONT_WIDTH * 11, y, "SPD", track->speed + DEFAULT_SPEED, setSpeed, NULL);
drawSwitch(music, x += TIC_FONT_WIDTH * 8, y, "ROWS", MUSIC_PATTERN_ROWS - track->rows, setRows, NULL);
}
static void drawTrackerFrames(Music* music, s32 x, s32 y)
{
tic_mem* tic = music->tic;
enum
{
Border = 1,
Width = TIC_FONT_WIDTH * 2 + Border,
};
s32 width = tic->font.width * 2 + Border;
{
tic_rect rect = { x - Border, y - Border, width, MUSIC_FRAMES * tic->font.height + Border };
tic_rect rect = { x - Border, y - Border, Width, MUSIC_FRAMES * TIC_FONT_HEIGHT + Border };
if (checkMousePos(&rect))
{
@@ -1144,7 +1136,7 @@ static void drawTrackerFrames(Music* music, s32 x, s32 y)
if (checkMouseDown(&rect, tic_mouse_left))
{
s32 my = getMouseY() - rect.y - Border;
music->tracker.frame = my / tic->font.height;
music->tracker.frame = my / TIC_FONT_HEIGHT;
}
}
@@ -1168,26 +1160,26 @@ static void drawTrackerFrames(Music* music, s32 x, s32 y)
0b00000000,
};
drawBitIcon(x - 7, y + i*tic->font.height, Icon, tic_color_black);
drawBitIcon(x - 7, y - 1 + i*tic->font.height, Icon, tic_color_white);
drawBitIcon(x - TIC_FONT_WIDTH-1, y + i*TIC_FONT_HEIGHT, Icon, tic_color_black);
drawBitIcon(x - TIC_FONT_WIDTH-1, y - 1 + i*TIC_FONT_HEIGHT, Icon, tic_color_white);
}
if (i == music->tracker.frame)
{
music->tic->api.rect(music->tic, x - 1, y - 1 + i*tic->font.height, width, tic->font.height + 1, (tic_color_white));
music->tic->api.rect(music->tic, x - 1, y - 1 + i*TIC_FONT_HEIGHT, Width, TIC_FONT_HEIGHT + 1, (tic_color_white));
}
char buf[] = "99";
sprintf(buf, "%02i", i);
music->tic->api.fixed_text(music->tic, buf, x, y + i*tic->font.height, (tic_color_dark_gray));
music->tic->api.fixed_text(music->tic, buf, x, y + i*TIC_FONT_HEIGHT, (tic_color_dark_gray), false);
}
if(music->tracker.row >= 0)
{
char buf[] = "99";
sprintf(buf, "%02i", music->tracker.row);
music->tic->api.fixed_text(music->tic, buf, x, y - 10, (tic_color_black));
music->tic->api.fixed_text(music->tic, buf, x, y - 11, (tic_color_white));
music->tic->api.fixed_text(music->tic, buf, x, y - 10, (tic_color_black), false);
music->tic->api.fixed_text(music->tic, buf, x, y - 11, (tic_color_white), false);
}
}
@@ -1213,12 +1205,11 @@ static void drawTrackerChannel(Music* music, s32 x, s32 y, s32 channel)
enum
{
Border = 1,
Rows = TRACKER_ROWS,
Rows = TRACKER_ROWS,
Width = TIC_FONT_WIDTH * 8 + Border,
};
s32 width = tic->font.width * 8 + Border;
tic_rect rect = {x - Border, y - Border, width, Rows*tic->font.height + Border};
tic_rect rect = {x - Border, y - Border, Width, Rows*TIC_FONT_HEIGHT + Border};
if(checkMousePos(&rect))
{
@@ -1229,8 +1220,8 @@ static void drawTrackerChannel(Music* music, s32 x, s32 y, s32 channel)
s32 mx = getMouseX() - rect.x - Border;
s32 my = getMouseY() - rect.y - Border;
s32 col = music->tracker.col = channel * CHANNEL_COLS + mx / tic->font.width;
s32 row = music->tracker.row = my / tic->font.height + music->tracker.scroll;
s32 col = music->tracker.col = channel * CHANNEL_COLS + mx / TIC_FONT_WIDTH;
s32 row = music->tracker.row = my / TIC_FONT_HEIGHT + music->tracker.scroll;
if(music->tracker.select.drag)
{
@@ -1266,11 +1257,11 @@ static void drawTrackerChannel(Music* music, s32 x, s32 y, s32 channel)
for (s32 i = start, pos = 0; i < end; i++, pos++)
{
s32 rowy = y + pos*tic->font.height;
s32 rowy = y + pos*TIC_FONT_HEIGHT;
if (i == music->tracker.row)
{
music->tic->api.rect(music->tic, x - 1, rowy - 1, width, tic->font.height + 1, (tic_color_dark_red));
music->tic->api.rect(music->tic, x - 1, rowy - 1, Width, TIC_FONT_HEIGHT + 1, (tic_color_dark_red));
}
// draw selection
@@ -1280,13 +1271,13 @@ static void drawTrackerChannel(Music* music, s32 x, s32 y, s32 channel)
if (rect.h > 1 && i >= rect.y && i < rect.y + rect.h)
{
s32 sx = x - 1;
tic->api.rect(tic, sx, rowy - 1, CHANNEL_COLS * tic->font.width + 1, tic->font.height + 1, (tic_color_yellow));
tic->api.rect(tic, sx, rowy - 1, CHANNEL_COLS * TIC_FONT_WIDTH + 1, TIC_FONT_HEIGHT + 1, (tic_color_yellow));
}
}
if (checkPlayRow(music, i))
{
music->tic->api.rect(music->tic, x - 1, rowy - 1, width, tic->font.height + 1, (tic_color_white));
music->tic->api.rect(music->tic, x - 1, rowy - 1, Width, TIC_FONT_HEIGHT + 1, (tic_color_white));
}
char rowStr[] = "--------";
@@ -1315,30 +1306,30 @@ static void drawTrackerChannel(Music* music, s32 x, s32 y, s32 channel)
bool beetRow = i % NOTES_PER_BEET == 0;
for (s32 c = 0, colx = x; c < sizeof rowStr - 1; c++, colx += tic->font.width)
for (s32 c = 0, colx = x; c < sizeof rowStr - 1; c++, colx += TIC_FONT_WIDTH)
{
char sym = rowStr[c];
const u8* colors = beetRow || sym != '-' ? Colors : DarkColors;
music->tic->api.draw_char(music->tic, sym, colx, rowy, colors[ColorIndexes[c]]);
music->tic->api.draw_char(music->tic, sym, colx, rowy, colors[ColorIndexes[c]], false);
}
}
}
else music->tic->api.fixed_text(music->tic, rowStr, x, rowy, (tic_color_dark_gray));
else music->tic->api.fixed_text(music->tic, rowStr, x, rowy, (tic_color_dark_gray), false);
if (i == music->tracker.row)
{
if (music->tracker.col / CHANNEL_COLS == channel)
{
s32 col = music->tracker.col % CHANNEL_COLS;
s32 colx = x - 1 + col * tic->font.width;
music->tic->api.rect(music->tic, colx, rowy - 1, tic->font.width + 1, tic->font.height + 1, (tic_color_red));
music->tic->api.draw_char(music->tic, rowStr[col], colx + 1, rowy, (tic_color_black));
s32 colx = x - 1 + col * TIC_FONT_WIDTH;
music->tic->api.rect(music->tic, colx, rowy - 1, TIC_FONT_WIDTH + 1, TIC_FONT_HEIGHT + 1, (tic_color_red));
music->tic->api.draw_char(music->tic, rowStr[col], colx + 1, rowy, (tic_color_black), false);
}
}
if (i % NOTES_PER_BEET == 0)
music->tic->api.pixel(music->tic, x - 4, y + pos*tic->font.height + 2, (tic_color_black));
music->tic->api.pixel(music->tic, x - 4, y + pos*TIC_FONT_HEIGHT + 2, (tic_color_black));
}
}
@@ -1373,25 +1364,21 @@ static void drawTumbler(Music* music, s32 x, s32 y, s32 index)
static void drawTracker(Music* music, s32 x, s32 y)
{
tic_mem* tic = music->tic;
drawTrackerFrames(music, x, y);
enum{Gap = 6, Cols = 8};
x += TIC_FONT_WIDTH * 3;
x += tic->font.width * 2 + Gap;
s32 channelWidth = tic->font.width * Cols + Gap;
enum{ChannelWidth = TIC_FONT_WIDTH * 9};
for (s32 i = 0; i < TIC_SOUND_CHANNELS; i++)
{
s32 patternId = tic_tool_get_pattern_id(getTrack(music), music->tracker.frame, i);
drawEditbox(music, x + channelWidth * i + 3*tic->font.width, y - 11, patternId, setChannelPattern, i);
drawTumbler(music, x + channelWidth * (i+1) - 4 - Gap, y - 11, i);
drawEditbox(music, x + ChannelWidth * i + 2*TIC_FONT_WIDTH, y - 11, patternId, setChannelPattern, i);
drawTumbler(music, x + ChannelWidth * i + 7*TIC_FONT_WIDTH, y - 11, i);
}
for (s32 i = 0; i < TIC_SOUND_CHANNELS; i++)
drawTrackerChannel(music, x + channelWidth * i, y, i);
drawTrackerChannel(music, x + ChannelWidth * i, y, i);
}
static void enableFollowMode(Music* music)
@@ -1535,11 +1522,10 @@ static void drawMusicToolbar(Music* music)
static void drawPianoLayout(Music* music)
{
tic_mem* tic = music->tic;
music->tic->api.clear(music->tic, (tic_color_gray));
static const char Wip[] = "PIANO MODE - WORK IN PROGRESS...";
music->tic->api.fixed_text(music->tic, Wip, (TIC80_WIDTH - (sizeof Wip - 1) * tic->font.width) / 2, TIC80_HEIGHT / 2, (tic_color_white));
music->tic->api.fixed_text(music->tic, Wip, (TIC80_WIDTH - (sizeof Wip - 1) * TIC_FONT_WIDTH) / 2, TIC80_HEIGHT / 2, (tic_color_white), false);
}
static void scrollNotes(Music* music, s32 delta)
@@ -1603,14 +1589,14 @@ static void drawTrackerLayout(Music* music)
if(music->tracker.follow)
{
const tic_music_pos* pos = getMusicPos(music);
const tic_sound_state* pos = getMusicPos(music);
if(pos->track == music->track &&
if(pos->music.track == music->track &&
music->tracker.row >= 0 &&
pos->row >= 0)
pos->music.row >= 0)
{
music->tracker.frame = pos->frame;
music->tracker.row = pos->row;
music->tracker.frame = pos->music.frame;
music->tracker.row = pos->music.row;
updateTracker(music);
}
}
+9 -8
View File
@@ -48,7 +48,7 @@ static void onExit(void* data)
run->exit = true;
}
static char* data2md5(const void* data, s32 length)
static const char* data2md5(const void* data, s32 length)
{
const char *str = data;
MD5_CTX c;
@@ -66,11 +66,12 @@ static char* data2md5(const void* data, s32 length)
}
{
u8 digest[16];
enum{Size = 16};
u8 digest[Size];
MD5_Final(digest, &c);
for (s32 n = 0; n < 16; ++n)
snprintf(&(out[n*2]), 16*2, "%02x", (u32)digest[n]);
for (s32 n = 0; n < Size; ++n)
snprintf(out + n*2, sizeof("ff"), "%02x", digest[n]);
}
return out;
@@ -78,8 +79,8 @@ static char* data2md5(const void* data, s32 length)
static void initPMemName(Run* run)
{
const char* data = strlen(run->tic->saveid) ? run->tic->saveid : run->tic->cart.bank0.code.data;
char* md5 = data2md5(data, (s32)strlen(data));
const char* data = strlen(run->tic->saveid) ? run->tic->saveid : run->tic->cart.code.data;
const char* md5 = data2md5(data, strlen(data));
strcpy(run->saveid, TIC_LOCAL);
strcat(run->saveid, md5);
}
@@ -112,9 +113,9 @@ static void processDoFile(void* data, char* dst)
static const char DoFileTag[] = "dofile(";
enum {Size = sizeof DoFileTag - 1};
if (memcmp(tic->cart.bank0.code.data, DoFileTag, Size) == 0)
if (memcmp(tic->cart.code.data, DoFileTag, Size) == 0)
{
const char* start = tic->cart.bank0.code.data + Size;
const char* start = tic->cart.code.data + Size;
const char* end = strchr(start, ')');
if(end && *start == *(end-1) && (*start == '"' || *start == '\''))
+84 -55
View File
@@ -39,15 +39,13 @@
static void drawSwitch(Sfx* sfx, s32 x, s32 y, const char* label, s32 value, void(*set)(Sfx*, s32))
{
tic_mem* tic = sfx->tic;
static const u8 LeftArrow[] =
{
0b00100000,
0b01100000,
0b11100000,
0b01100000,
0b00100000,
0b00010000,
0b00110000,
0b01110000,
0b00110000,
0b00010000,
0b00000000,
0b00000000,
0b00000000,
@@ -55,24 +53,22 @@ static void drawSwitch(Sfx* sfx, s32 x, s32 y, const char* label, s32 value, voi
static const u8 RightArrow[] =
{
0b10000000,
0b11000000,
0b11100000,
0b11000000,
0b10000000,
0b01000000,
0b01100000,
0b01110000,
0b01100000,
0b01000000,
0b00000000,
0b00000000,
0b00000000,
};
enum{ArrowWidth = 4, ArrowHeight = 6};
sfx->tic->api.text(sfx->tic, label, x, y, (tic_color_white));
sfx->tic->api.text(sfx->tic, label, x, y, (tic_color_white), false);
{
x += (s32)strlen(label)*tic->font.width;
x += (s32)strlen(label)*TIC_FONT_WIDTH;
tic_rect rect = {x, y, ArrowWidth, ArrowHeight};
tic_rect rect = {x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
@@ -88,13 +84,13 @@ static void drawSwitch(Sfx* sfx, s32 x, s32 y, const char* label, s32 value, voi
{
char val[] = "99";
sprintf(val, "%02i", value);
sfx->tic->api.fixed_text(sfx->tic, val, x += ArrowWidth, y, (tic_color_white));
sfx->tic->api.fixed_text(sfx->tic, val, x += TIC_FONT_WIDTH, y, (tic_color_white), false);
}
{
x += 2*tic->font.width;
x += 2*TIC_FONT_WIDTH;
tic_rect rect = {x, y, ArrowWidth, ArrowHeight};
tic_rect rect = {x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
@@ -127,16 +123,54 @@ static void setSpeed(Sfx* sfx, s32 delta)
history_add(sfx->history);
}
static void drawStereoSwitch(Sfx* sfx, s32 x, s32 y)
{
tic_sample* effect = getEffect(sfx);
{
tic_rect rect = {x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
setCursor(tic_cursor_hand);
showTooltip("left stereo");
if(checkMouseClick(&rect, tic_mouse_left))
effect->stereo_left = !effect->stereo_left;
}
sfx->tic->api.text(sfx->tic, "L", x, y, effect->stereo_left ? tic_color_dark_gray : tic_color_white, false);
}
{
tic_rect rect = {x += TIC_FONT_WIDTH, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
setCursor(tic_cursor_hand);
showTooltip("right stereo");
if(checkMouseClick(&rect, tic_mouse_left))
effect->stereo_right = !effect->stereo_right;
}
sfx->tic->api.text(sfx->tic, "R", x, y, effect->stereo_right ? tic_color_dark_gray : tic_color_white, false);
}
}
static void drawTopPanel(Sfx* sfx, s32 x, s32 y)
{
tic_mem* tic = sfx->tic;
const s32 Gap = 8*tic->font.width;
const s32 Gap = 8*TIC_FONT_WIDTH;
drawSwitch(sfx, x, y, "IDX", sfx->index, setIndex);
tic_sample* effect = getEffect(sfx);
drawSwitch(sfx, x += Gap, y, "SPD", effect->speed, setSpeed);
drawStereoSwitch(sfx, x += Gap, y);
}
static void setLoopStart(Sfx* sfx, s32 delta)
@@ -161,16 +195,15 @@ static void setLoopSize(Sfx* sfx, s32 delta)
static void drawLoopPanel(Sfx* sfx, s32 x, s32 y)
{
tic_mem* tic = sfx->tic;
sfx->tic->api.text(sfx->tic, "LOOP:", x, y, (tic_color_dark_gray));
sfx->tic->api.text(sfx->tic, "LOOP:", x, y, (tic_color_dark_gray), false);
enum {Gap = 2};
tic_sample* effect = getEffect(sfx);
tic_sound_loop* loop = effect->loops + sfx->canvasTab;
drawSwitch(sfx, x, y += Gap + tic->font.height, "", loop->size, setLoopSize);
drawSwitch(sfx, x, y += Gap + tic->font.height, "", loop->start, setLoopStart);
drawSwitch(sfx, x, y += Gap + TIC_FONT_HEIGHT, "", loop->size, setLoopSize);
drawSwitch(sfx, x, y += Gap + TIC_FONT_HEIGHT, "", loop->start, setLoopStart);
}
static tic_waveform* getWaveformById(Sfx* sfx, s32 i)
@@ -293,16 +326,15 @@ static void drawWaveButtons(Sfx* sfx, s32 x, s32 y)
static void drawCanvasTabs(Sfx* sfx, s32 x, s32 y)
{
tic_mem* tic = sfx->tic;
static const char* Labels[] = {"WAVE", "VOLUME", "ARPEGG", "PITCH"};
s32 height = tic->font.height+2;
enum {Height = TIC_FONT_HEIGHT+2};
for(s32 i = 0, sy = y; i < COUNT_OF(Labels); sy += height, i++)
for(s32 i = 0, sy = y; i < COUNT_OF(Labels); sy += Height, i++)
{
s32 size = sfx->tic->api.text(sfx->tic, Labels[i], 0, -tic->font.height, (tic_color_black));
s32 size = sfx->tic->api.text(sfx->tic, Labels[i], 0, -TIC_FONT_HEIGHT, (tic_color_black), false);
tic_rect rect = {x - size, sy, size, tic->font.height};
tic_rect rect = {x - size, sy, size, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
@@ -314,7 +346,7 @@ static void drawCanvasTabs(Sfx* sfx, s32 x, s32 y)
}
}
sfx->tic->api.text(sfx->tic, Labels[i], rect.x, rect.y, i == sfx->canvasTab ? (tic_color_white) : (tic_color_dark_gray));
sfx->tic->api.text(sfx->tic, Labels[i], rect.x, rect.y, i == sfx->canvasTab ? (tic_color_white) : (tic_color_dark_gray), false);
}
tic_sample* effect = getEffect(sfx);
@@ -324,8 +356,8 @@ static void drawCanvasTabs(Sfx* sfx, s32 x, s32 y)
case SFX_PITCH_TAB:
{
static const char Label[] = "x16";
s32 width = (sizeof Label - 1) * tic->font.width;
tic_rect rect = {(x - width)/2, y + height * 6, width, tic->font.height};
enum{Width = (sizeof Label - 1) * TIC_FONT_WIDTH};
tic_rect rect = {(x - Width)/2, y + Height * 6, Width, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
@@ -335,14 +367,14 @@ static void drawCanvasTabs(Sfx* sfx, s32 x, s32 y)
effect->pitch16x++;
}
sfx->tic->api.fixed_text(sfx->tic, Label, rect.x, rect.y, (effect->pitch16x ? tic_color_white : tic_color_dark_gray));
sfx->tic->api.fixed_text(sfx->tic, Label, rect.x, rect.y, (effect->pitch16x ? tic_color_white : tic_color_dark_gray), false);
}
break;
case SFX_ARPEGGIO_TAB:
{
static const char Label[] = "DOWN";
s32 width = (sizeof Label - 1) * tic->font.width;
tic_rect rect = {(x - width)/2, y + height * 6, width, tic->font.height};
enum{Width = (sizeof Label - 1) * TIC_FONT_WIDTH};
tic_rect rect = {(x - Width)/2, y + Height * 6, Width, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
@@ -352,7 +384,7 @@ static void drawCanvasTabs(Sfx* sfx, s32 x, s32 y)
effect->reverse++;
}
sfx->tic->api.text(sfx->tic, Label, rect.x, rect.y, (effect->reverse ? tic_color_white : tic_color_dark_gray));
sfx->tic->api.text(sfx->tic, Label, rect.x, rect.y, (effect->reverse ? tic_color_white : tic_color_dark_gray), false);
}
break;
default: break;
@@ -521,19 +553,18 @@ static void drawPiano(Sfx* sfx, s32 x, s32 y)
static void drawOctavePanel(Sfx* sfx, s32 x, s32 y)
{
tic_mem* tic = sfx->tic;
tic_sample* effect = getEffect(sfx);
static const char Label[] = "OCT";
sfx->tic->api.text(sfx->tic, Label, x, y, (tic_color_white));
sfx->tic->api.text(sfx->tic, Label, x, y, (tic_color_white), false);
x += sizeof(Label)*tic->font.width;
x += sizeof(Label)*TIC_FONT_WIDTH;
enum {Gap = 5};
for(s32 i = 0; i < OCTAVES; i++)
{
tic_rect rect = {x + i * (tic->font.width + Gap), y, tic->font.width, tic->font.height};
tic_rect rect = {x + i * (TIC_FONT_WIDTH + Gap), y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT};
if(checkMousePos(&rect))
{
@@ -545,7 +576,7 @@ static void drawOctavePanel(Sfx* sfx, s32 x, s32 y)
}
}
sfx->tic->api.draw_char(sfx->tic, i + '1', rect.x, rect.y, (i == effect->octave ? tic_color_white : tic_color_dark_gray));
sfx->tic->api.draw_char(sfx->tic, i + '1', rect.x, rect.y, (i == effect->octave ? tic_color_white : tic_color_dark_gray), false);
}
}
@@ -789,14 +820,13 @@ static void drawModeTabs(Sfx* sfx)
static void drawSfxToolbar(Sfx* sfx)
{
tic_mem* tic = sfx->tic;
sfx->tic->api.rect(sfx->tic, 0, 0, TIC80_WIDTH, TOOLBAR_SIZE, (tic_color_white));
s32 width = 3 * tic->font.width;
s32 x = TIC80_WIDTH - width - TIC_SPRITESIZE*3;
enum{Width = 3 * TIC_FONT_WIDTH};
s32 x = TIC80_WIDTH - Width - TIC_SPRITESIZE*3;
s32 y = 1;
tic_rect rect = {x, y, width, tic->font.height};
tic_rect rect = {x, y, Width, TIC_FONT_HEIGHT};
bool over = false;
if(checkMousePos(&rect))
@@ -819,7 +849,7 @@ static void drawSfxToolbar(Sfx* sfx)
char buf[] = "C#4";
sprintf(buf, "%s%i", Notes[effect->note], effect->octave+1);
sfx->tic->api.fixed_text(sfx->tic, buf, x, y, (over ? tic_color_dark_gray : tic_color_light_blue));
sfx->tic->api.fixed_text(sfx->tic, buf, x, y, (over ? tic_color_dark_gray : tic_color_light_blue), false);
}
drawModeTabs(sfx);
@@ -827,7 +857,6 @@ static void drawSfxToolbar(Sfx* sfx)
static void envelopesTick(Sfx* sfx)
{
tic_mem* tic = sfx->tic;
processKeyboard(sfx);
processEnvelopesKeyboard(sfx);
@@ -835,18 +864,18 @@ static void envelopesTick(Sfx* sfx)
enum{ Gap = 3, Start = 40};
drawPiano(sfx, Start, TIC80_HEIGHT - PIANO_HEIGHT - Gap);
drawTopPanel(sfx, Start, TOOLBAR_SIZE + Gap);
drawSfxToolbar(sfx);
drawToolbar(sfx->tic, TIC_COLOR_BG, false);
drawTopPanel(sfx, Start, TOOLBAR_SIZE + Gap);
drawCanvasTabs(sfx, Start-Gap, TOOLBAR_SIZE + Gap + tic->font.height+2);
drawCanvasTabs(sfx, Start-Gap, TOOLBAR_SIZE + Gap + TIC_FONT_HEIGHT+2);
if(sfx->canvasTab == SFX_WAVE_TAB)
drawWaveButtons(sfx, Start + CANVAS_WIDTH + Gap-1, TOOLBAR_SIZE + Gap + tic->font.height+2);
drawWaveButtons(sfx, Start + CANVAS_WIDTH + Gap-1, TOOLBAR_SIZE + Gap + TIC_FONT_HEIGHT+2);
drawLoopPanel(sfx, Gap, TOOLBAR_SIZE + Gap + tic->font.height+92);
drawCanvas(sfx, Start-1, TOOLBAR_SIZE + Gap + tic->font.height + 1);
drawOctavePanel(sfx, Start + Gap + PIANO_WIDTH + Gap-1, TIC80_HEIGHT - tic->font.height - (PIANO_HEIGHT - tic->font.height)/2 - Gap);
drawLoopPanel(sfx, Gap, TOOLBAR_SIZE + Gap + TIC_FONT_HEIGHT+92);
drawCanvas(sfx, Start-1, TOOLBAR_SIZE + Gap + TIC_FONT_HEIGHT + 1);
drawOctavePanel(sfx, Start + Gap + PIANO_WIDTH + Gap-1, TIC80_HEIGHT - TIC_FONT_HEIGHT - (PIANO_HEIGHT - TIC_FONT_HEIGHT)/2 - Gap);
}
static void drawWaveformBar(Sfx* sfx, s32 x, s32 y)
+8 -11
View File
@@ -359,17 +359,15 @@ static void drawBrushSlider(Sprite* sprite, s32 x, s32 y)
static void drawCanvas(Sprite* sprite, s32 x, s32 y)
{
tic_mem* tic = sprite->tic;
if(!hasCanvasSelection(sprite))
{
char buf[] = "#255";
sprintf(buf, "#%03i", sprite->index);
s32 ix = x + (CANVAS_SIZE - 4*tic->font.width)/2;
s32 ix = x + (CANVAS_SIZE - 4*TIC_FONT_WIDTH)/2;
s32 iy = TIC_SPRITESIZE + 2;
sprite->tic->api.text(sprite->tic, buf, ix, iy+1, (tic_color_black));
sprite->tic->api.text(sprite->tic, buf, ix, iy, (tic_color_white));
sprite->tic->api.text(sprite->tic, buf, ix, iy+1, (tic_color_black), false);
sprite->tic->api.text(sprite->tic, buf, ix, iy, (tic_color_white), false);
}
sprite->tic->api.rect_border(sprite->tic, x-1, y-1, CANVAS_SIZE+2, CANVAS_SIZE+2, (tic_color_white));
@@ -694,7 +692,7 @@ static void drawRGBSlider(Sprite* sprite, s32 x, s32 y, u8* value)
{
char buf[] = "FF";
sprintf(buf, "%02X", *value);
sprite->tic->api.text(sprite->tic, buf, x - 18, y - 2, (tic_color_dark_gray));
sprite->tic->api.text(sprite->tic, buf, x - 18, y - 2, (tic_color_dark_gray), false);
}
}
@@ -1494,7 +1492,6 @@ static void processKeyboard(Sprite* sprite)
static void drawSpriteToolbar(Sprite* sprite)
{
tic_mem* tic = sprite->tic;
sprite->tic->api.rect(sprite->tic, 0, 0, TIC80_WIDTH, TOOLBAR_SIZE, (tic_color_white));
// draw sprite size control
@@ -1536,9 +1533,9 @@ static void drawSpriteToolbar(Sprite* sprite)
{
static const char Label[] = "BG";
tic_rect rect = {TIC80_WIDTH - 2 * tic->font.width - 2, 0, 2 * tic->font.width + 1, TIC_SPRITESIZE-1};
tic_rect rect = {TIC80_WIDTH - 2 * TIC_FONT_WIDTH - 2, 0, 2 * TIC_FONT_WIDTH + 1, TIC_SPRITESIZE-1};
sprite->tic->api.rect(sprite->tic, rect.x, rect.y, rect.w, rect.h, bg ? (tic_color_black) : (tic_color_gray));
sprite->tic->api.fixed_text(sprite->tic, Label, rect.x+1, rect.y+1, (tic_color_white));
sprite->tic->api.fixed_text(sprite->tic, Label, rect.x+1, rect.y+1, (tic_color_white), false);
if(checkMousePos(&rect))
{
@@ -1556,9 +1553,9 @@ static void drawSpriteToolbar(Sprite* sprite)
{
static const char Label[] = "FG";
tic_rect rect = {TIC80_WIDTH - 4 * tic->font.width - 4, 0, 2 * tic->font.width + 1, TIC_SPRITESIZE-1};
tic_rect rect = {TIC80_WIDTH - 4 * TIC_FONT_WIDTH - 4, 0, 2 * TIC_FONT_WIDTH + 1, TIC_SPRITESIZE-1};
sprite->tic->api.rect(sprite->tic, rect.x, rect.y, rect.w, rect.h, bg ? (tic_color_gray) : (tic_color_black));
sprite->tic->api.fixed_text(sprite->tic, Label, rect.x+1, rect.y+1, (tic_color_white));
sprite->tic->api.fixed_text(sprite->tic, Label, rect.x+1, rect.y+1, (tic_color_white), false);
if(checkMousePos(&rect))
{
+8 -13
View File
@@ -24,25 +24,23 @@
static void reset(Start* start)
{
tic_mem* tic = start->tic;
u8* tile = (u8*)tic->ram.tiles.data;
u8* tile = (u8*)start->tic->ram.tiles.data;
tic->api.clear(tic, (tic_color_black));
start->tic->api.clear(start->tic, (tic_color_black));
static const u8 Reset[] = {0x00, 0x06, 0x96, 0x00};
u8 val = Reset[sizeof(Reset) * (start->ticks % TIC_FRAMERATE) / TIC_FRAMERATE];
for(s32 i = 0; i < sizeof(tic_tile); i++) tile[i] = val;
tic->api.map(tic, &tic->ram.map, &tic->ram.tiles, 0, 0, TIC_MAP_SCREEN_WIDTH, TIC_MAP_SCREEN_HEIGHT + (TIC80_HEIGHT % TIC_SPRITESIZE ? 1 : 0), 0, 0, -1, 1);
start->tic->api.map(start->tic, &start->tic->ram.map, &start->tic->ram.tiles, 0, 0, TIC_MAP_SCREEN_WIDTH, TIC_MAP_SCREEN_HEIGHT + (TIC80_HEIGHT % TIC_SPRITESIZE ? 1 : 0), 0, 0, -1, 1);
}
static void drawHeader(Start* start)
{
tic_mem* tic = start->tic;
tic->api.fixed_text(tic, TIC_NAME_FULL, TextWidth(tic), TextHeight(tic), (tic_color_white));
tic->api.fixed_text(tic, TIC_VERSION_LABEL, (sizeof(TIC_NAME_FULL) + 1) * TextWidth(tic), TextHeight(tic), (tic_color_dark_gray));
tic->api.fixed_text(tic, TIC_COPYRIGHT, TextWidth(tic), TextHeight(tic)*2, (tic_color_dark_gray));
start->tic->api.fixed_text(start->tic, TIC_NAME_FULL, STUDIO_TEXT_WIDTH, STUDIO_TEXT_HEIGHT, (tic_color_white), false);
start->tic->api.fixed_text(start->tic, TIC_VERSION_LABEL, (sizeof(TIC_NAME_FULL) + 1) * STUDIO_TEXT_WIDTH, STUDIO_TEXT_HEIGHT, (tic_color_dark_gray), false);
start->tic->api.fixed_text(start->tic, TIC_COPYRIGHT, STUDIO_TEXT_WIDTH, STUDIO_TEXT_HEIGHT*2, (tic_color_dark_gray), false);
}
static void header(Start* start)
@@ -59,10 +57,9 @@ static void header(Start* start)
static void end(Start* start)
{
tic_mem* tic = start->tic;
if(start->play)
{
tic->api.sfx_stop(tic, 0);
start->tic->api.sfx_stop(start->tic, 0);
start->play = false;
}
@@ -73,8 +70,6 @@ static void end(Start* start)
static void tick(Start* start)
{
tic_mem* tic = start->tic;
if(!start->initialized)
{
start->phase = 1;
@@ -83,7 +78,7 @@ static void tick(Start* start)
start->initialized = true;
}
tic->api.clear(tic, TIC_COLOR_BG);
start->tic->api.clear(start->tic, TIC_COLOR_BG);
static void(*const steps[])(Start*) = {reset, header, end};
+44 -40
View File
@@ -52,9 +52,6 @@
#define FRAME_SIZE (TIC80_FULLWIDTH * TIC80_FULLHEIGHT * sizeof(u32))
#define POPUP_DUR (TIC_FRAMERATE*2)
#define KEYBOARD_HOLD 20
#define KEYBOARD_PERIOD 3
#if defined(TIC80_PRO)
#define TIC_EDITOR_BANKS (TIC_BANKS)
#else
@@ -133,12 +130,12 @@ static struct
struct
{
s32 counter;
char message[TIC80_WIDTH];
char message[STUDIO_TEXT_BUFFER_WIDTH];
} popup;
struct
{
char text[TIC80_WIDTH];
char text[STUDIO_TEXT_BUFFER_WIDTH];
} tooltip;
struct
@@ -237,22 +234,31 @@ static struct
char getKeyboardText()
{
tic_mem* tic = impl.studio.tic;
tic_mem* tic = impl.studio.tic;
static const char Symbols[] = "abcdefghijklmnopqrstuvwxyz0123456789-=[]\\;'`,./ ";
static const char Shift[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ)!@#$%^&*(_+{}|:\"~<>? ";
static const char Symbols[] = " abcdefghijklmnopqrstuvwxyz0123456789-=[]\\;'`,./ ";
static const char Shift[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ)!@#$%^&*(_+{}|:\"~<>? ";
enum{Count = sizeof Symbols};
enum{Count = sizeof Symbols};
for(s32 i = 0; i < TIC80_KEY_BUFFER; i++)
{
tic_key key = tic->ram.input.keyboard.keys[i];
for(s32 i = 0; i < TIC80_KEY_BUFFER; i++)
{
tic_key key = tic->ram.input.keyboard.keys[i];
if(key > 0 && key < Count && tic->api.keyp(tic, key, KEYBOARD_HOLD, KEYBOARD_PERIOD))
return tic->api.key(tic, tic_key_shift) ? Shift[key-1] : Symbols[key-1];
}
if(key > 0 && key < Count && tic->api.keyp(tic, key, KEYBOARD_HOLD, KEYBOARD_PERIOD))
{
bool caps = tic->api.key(tic, tic_key_capslock);
bool shift = tic->api.key(tic, tic_key_shift);
return 0;
return caps
? key >= tic_key_a && key <= tic_key_z
? shift ? Symbols[key] : Shift[key]
: shift ? Shift[key] : Symbols[key]
: shift ? Shift[key] : Symbols[key];
}
}
return 0;
}
bool keyWasPressed(tic_key key)
@@ -436,7 +442,7 @@ static void drawExtrabar(tic_mem* tic)
{
enum {Size = 7};
s32 x = (COUNT_OF(Modes) + 1) * Size + 102;
s32 x = (COUNT_OF(Modes) + 1) * Size + 17 * TIC_FONT_WIDTH;
s32 y = 0;
static const u8 Icons[] =
@@ -526,13 +532,20 @@ const StudioConfig* getConfig()
return &impl.config->data;
}
static bool isGamepadMode()
{
return impl.mode == TIC_RUN_MODE
|| impl.mode == TIC_SURF_MODE
|| impl.mode == TIC_MENU_MODE;
}
#if defined (TIC80_PRO)
static void drawBankIcon(s32 x, s32 y)
{
tic_mem* tic = impl.studio.tic;
tic_rect rect = {x, y, tic->font.width, tic->font.height};
tic_rect rect = {x, y, TIC_FONT_WIDTH, TIC_FONT_HEIGHT};
static const u8 Icon[] =
{
@@ -574,11 +587,9 @@ static void drawBankIcon(s32 x, s32 y)
enum{Size = TOOLBAR_SIZE};
x += Size+2;
for(s32 i = 0; i < TIC_EDITOR_BANKS; i++)
{
tic_rect rect = {x + i*Size, 0, Size, Size};
tic_rect rect = {x + 2 + (i+1)*Size, 0, Size, Size};
bool over = false;
if(checkMousePos(&rect))
@@ -597,7 +608,7 @@ static void drawBankIcon(s32 x, s32 y)
if(i == impl.bank.indexes[mode])
tic->api.rect(tic, rect.x, rect.y, rect.w, rect.h, tic_color_red);
tic->api.draw_char(tic, '0' + i, rect.x+(Size-tic->font.width+1)/2, rect.y+1, i == impl.bank.indexes[mode] ? tic_color_white : over ? tic_color_red : tic_color_peach);
tic->api.draw_char(tic, '0' + i, rect.x+1, rect.y+1, i == impl.bank.indexes[mode] ? tic_color_white : over ? tic_color_red : tic_color_peach, false);
}
@@ -614,7 +625,7 @@ static void drawBankIcon(s32 x, s32 y)
0b00000000,
};
tic_rect rect = {x + 2 + TIC_EDITOR_BANKS*Size, 0, Size, Size};
tic_rect rect = {x + 4 + (TIC_EDITOR_BANKS+1)*Size, 0, Size, Size};
bool over = false;
@@ -766,11 +777,11 @@ void drawToolbar(tic_mem* tic, u8 color, bool bg)
{
if(strlen(impl.tooltip.text))
{
impl.studio.tic->api.text(tic, impl.tooltip.text, TextOffset, 1, (tic_color_black));
impl.studio.tic->api.text(tic, impl.tooltip.text, TextOffset, 1, (tic_color_black), false);
}
else
{
impl.studio.tic->api.text(tic, Names[mode], TextOffset, 1, (tic_color_dark_gray));
impl.studio.tic->api.text(tic, Names[mode], TextOffset, 1, (tic_color_dark_gray), false);
}
}
}
@@ -1088,7 +1099,7 @@ static void initModules()
for(s32 i = 0; i < TIC_EDITOR_BANKS; i++)
{
initCode(impl.editor[i].code, impl.studio.tic, &tic->cart.banks[i].code);
initCode(impl.editor[i].code, impl.studio.tic, &tic->cart.code);
initSprite(impl.editor[i].sprite, impl.studio.tic, &tic->cart.banks[i].tiles);
initMap(impl.editor[i].map, impl.studio.tic, &tic->cart.banks[i].map);
initSfx(impl.editor[i].sfx, impl.studio.tic, &tic->cart.banks[i].sfx);
@@ -1329,7 +1340,6 @@ static void processShortcuts()
if(keyWasPressedOnce(tic_key_escape))
{
impl.mode == TIC_MENU_MODE ? hideGameMenu() : showGameMenu();
// impl.gamepad.backProcessed = true;
}
else if(keyWasPressedOnce(tic_key_f11)) goFullscreen();
else if(keyWasPressedOnce(tic_key_return))
@@ -1524,8 +1534,6 @@ static void recordFrame(u32* pixels)
static void drawPopup()
{
tic_mem* tic = impl.studio.tic;
if(impl.popup.counter > 0)
{
impl.popup.counter--;
@@ -1535,14 +1543,14 @@ static void drawPopup()
enum{Dur = TIC_FRAMERATE/2};
if(impl.popup.counter < Dur)
anim = -((Dur - impl.popup.counter) * (tic->font.height+1) / Dur);
anim = -((Dur - impl.popup.counter) * (TIC_FONT_HEIGHT+1) / Dur);
else if(impl.popup.counter >= (POPUP_DUR - Dur))
anim = (((POPUP_DUR - Dur) - impl.popup.counter) * (tic->font.height+1) / Dur);
anim = (((POPUP_DUR - Dur) - impl.popup.counter) * (TIC_FONT_HEIGHT+1) / Dur);
impl.studio.tic->api.rect(impl.studio.tic, 0, anim, TIC80_WIDTH, tic->font.height+1, (tic_color_red));
impl.studio.tic->api.rect(impl.studio.tic, 0, anim, TIC80_WIDTH, TIC_FONT_HEIGHT+1, (tic_color_red));
impl.studio.tic->api.text(impl.studio.tic, impl.popup.message,
(s32)(TIC80_WIDTH - strlen(impl.popup.message)*tic->font.width)/2,
anim + 1, (tic_color_white));
(s32)(TIC80_WIDTH - strlen(impl.popup.message)*TIC_FONT_WIDTH)/2,
anim + 1, (tic_color_white), false);
}
}
@@ -1630,12 +1638,7 @@ static void renderStudio()
static void updateSystemFont()
{
tic_mem* tic = impl.studio.tic;
memset(tic->font.data, 0, sizeof tic->font.data);
tic->font.width = impl.config->data.theme.font.width;
tic->font.height = impl.config->data.theme.font.height;
memset(impl.studio.tic->font.data, 0, sizeof(tic_font));
for(s32 i = 0; i < TIC_FONT_CHARS; i++)
for(s32 y = 0; y < TIC_SPRITESIZE; y++)
@@ -1882,6 +1885,7 @@ Studio* studioInit(s32 argc, char **argv, s32 samplerate, const char* folder, Sy
impl.studio.updateProject = updateStudioProject;
impl.studio.exit = exitStudio;
impl.studio.config = getConfig;
impl.studio.isGamepadMode = isGamepadMode;
return &impl.studio;
}
+4 -6
View File
@@ -38,7 +38,10 @@
#define TIC_CACHE TIC_LOCAL "cache/"
#define TOOLBAR_SIZE 7
#define TEXT_LINE_SPACE 1
#define STUDIO_TEXT_WIDTH (TIC_FONT_WIDTH)
#define STUDIO_TEXT_HEIGHT (TIC_FONT_HEIGHT+1)
#define STUDIO_TEXT_BUFFER_WIDTH (TIC80_WIDTH / STUDIO_TEXT_WIDTH)
#define STUDIO_TEXT_BUFFER_HEIGHT (TIC80_HEIGHT / STUDIO_TEXT_HEIGHT)
#define TIC_COLOR_BG (tic_color_black)
#define DEFAULT_CHMOD 0755
@@ -161,8 +164,3 @@ bool anyKeyWasPressed();
const StudioConfig* getConfig();
System* getSystem();
inline s32 TextWidth(const tic_mem* tic) { return tic->font.width; }
inline s32 TextHeight(const tic_mem* tic) { return tic->font.height + TEXT_LINE_SPACE; }
inline s32 BufferWidth(const tic_mem* tic) { return TIC80_WIDTH/TextWidth(tic); }
inline s32 BufferHeight(const tic_mem* tic) { return TIC80_HEIGHT/TextHeight(tic); }
+20 -20
View File
@@ -193,9 +193,9 @@ static void drawTopToolbar(Surf* surf, s32 x, s32 y)
sprintf(label, "%s", "TIC-80 SURF");
s32 xl = x + MAIN_OFFSET;
s32 yl = y + (Height - tic->font.height)/2;
tic->api.text(tic, label, xl, yl+1, tic_color_black);
tic->api.text(tic, label, xl, yl, tic_color_white);
s32 yl = y + (Height - TIC_FONT_HEIGHT)/2;
tic->api.text(tic, label, xl, yl+1, tic_color_black, false);
tic->api.text(tic, label, xl, yl, tic_color_white, false);
}
enum{Gap = 10, TipX = 150, SelectWidth = 54};
@@ -204,15 +204,15 @@ static void drawTopToolbar(Surf* surf, s32 x, s32 y)
tic->api.sprite_ex(tic, &getConfig()->cart->bank0.tiles, 12, TipX, y+1, 1, 1, &colorkey, 1, 1, tic_no_flip, tic_no_rotate);
{
static const char Label[] = "SELECT";
tic->api.text(tic, Label, TipX + Gap, y+3, tic_color_black);
tic->api.text(tic, Label, TipX + Gap, y+2, tic_color_white);
tic->api.text(tic, Label, TipX + Gap, y+3, tic_color_black, false);
tic->api.text(tic, Label, TipX + Gap, y+2, tic_color_white, false);
}
tic->api.sprite_ex(tic, &getConfig()->cart->bank0.tiles, 13, TipX + SelectWidth, y + 1, 1, 1, &colorkey, 1, 1, tic_no_flip, tic_no_rotate);
{
static const char Label[] = "BACK";
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +3, tic_color_black);
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +2, tic_color_white);
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +3, tic_color_black, false);
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +2, tic_color_white, false);
}
}
@@ -231,9 +231,9 @@ static void drawBottomToolbar(Surf* surf, s32 x, s32 y)
sprintf(label, "/%s", dir);
s32 xl = x + MAIN_OFFSET;
s32 yl = y + (Height - tic->font.height)/2;
tic->api.text(tic, label, xl, yl+1, tic_color_black);
tic->api.text(tic, label, xl, yl, tic_color_white);
s32 yl = y + (Height - TIC_FONT_HEIGHT)/2;
tic->api.text(tic, label, xl, yl+1, tic_color_black, false);
tic->api.text(tic, label, xl, yl, tic_color_white, false);
}
#ifdef CAN_OPEN_URL
@@ -247,8 +247,8 @@ static void drawBottomToolbar(Surf* surf, s32 x, s32 y)
tic->api.sprite_ex(tic, &getConfig()->cart->bank0.tiles, 15, TipX + SelectWidth, y + 1, 1, 1, &colorkey, 1, 1, tic_no_flip, tic_no_rotate);
{
static const char Label[] = "WEBSITE";
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +3, tic_color_black);
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +2, tic_color_white);
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +3, tic_color_black, false);
tic->api.text(tic, Label, TipX + Gap + SelectWidth, y +2, tic_color_white, false);
}
}
#endif
@@ -327,18 +327,18 @@ static void drawMenu(Surf* surf, s32 x, s32 y, bool bg)
{
const char* name = surf->menu.items[i].label;
s32 ym = Height * i + y - surf->menu.pos*MENU_HEIGHT - surf->menu.anim + (MENU_HEIGHT - tic->font.height)/2;
s32 ym = Height * i + y - surf->menu.pos*MENU_HEIGHT - surf->menu.anim + (MENU_HEIGHT - TIC_FONT_HEIGHT)/2;
if(bg)
{
s32 size = tic->api.text(tic, name, 0, -tic->font.height, 0);
s32 size = tic->api.text(tic, name, 0, -TIC_FONT_HEIGHT, 0, false);
drawInverseRect(tic, x + MAIN_OFFSET - 1, ym-1, size+1, tic->font.height+2);
drawInverseRect(tic, x + MAIN_OFFSET - 1, ym-1, size+1, TIC_FONT_HEIGHT+2);
}
else
{
tic->api.text(tic, name, x + MAIN_OFFSET, ym + 1, tic_color_black);
tic->api.text(tic, name, x + MAIN_OFFSET, ym, tic_color_white);
tic->api.text(tic, name, x + MAIN_OFFSET, ym + 1, tic_color_black, false);
tic->api.text(tic, name, x + MAIN_OFFSET, ym, tic_color_white, false);
}
}
}
@@ -670,7 +670,7 @@ static void onPlayCart(Surf* surf)
}
}
else
surf->console->load(surf->console, item->name);
surf->console->load(surf->console, item->name, item->hash);
runGameFromSurf();
}
@@ -837,8 +837,8 @@ static void tick(Surf* surf)
else
{
static const char Label[] = "You don't have any files...";
s32 size = tic->api.text(tic, Label, 0, -tic->font.height, tic_color_white);
tic->api.text(tic, Label, (TIC80_WIDTH - size) / 2, (TIC80_HEIGHT - tic->font.height)/2, tic_color_white);
s32 size = tic->api.text(tic, Label, 0, -TIC_FONT_HEIGHT, tic_color_white, false);
tic->api.text(tic, Label, (TIC80_WIDTH - size) / 2, (TIC80_HEIGHT - TIC_FONT_HEIGHT)/2, tic_color_white, false);
}
}
+326 -82
View File
@@ -17,6 +17,13 @@
#define OFFSET_LEFT ((TIC80_FULLWIDTH-TIC80_WIDTH)/2)
#define OFFSET_TOP ((TIC80_FULLHEIGHT-TIC80_HEIGHT)/2)
#define KBD_COLS 22
#define KBD_ROWS 17
#if defined(__TIC_WINRT__) || defined(__TIC_WINDOWS__)
#include <windows.h>
#endif
static struct
{
Studio* studio;
@@ -39,10 +46,6 @@ static struct
tic80_gamepads touch;
tic80_gamepads joystick;
bool show;
s32 counter;
s32 alpha;
struct
{
s32 size;
@@ -54,6 +57,25 @@ static struct
} part;
} gamepad;
struct
{
struct
{
GPU_Image* up;
GPU_Image* down;
} texture;
bool state[tic_keys_count];
struct
{
bool state[tic_keys_count];
} touch;
} keyboard;
u32 touchCounter;
struct
{
GPU_Image* texture;
@@ -83,7 +105,7 @@ static void initSound()
{
.freq = 44100,
.format = AUDIO_S16,
.channels = 1,
.channels = TIC_STEREO_CHANNLES,
.userdata = NULL,
};
@@ -93,7 +115,7 @@ static void initSound()
if(platform.audio.cvt.needed)
{
platform.audio.cvt.len = platform.audio.spec.freq * sizeof(s16) / TIC_FRAMERATE;
platform.audio.cvt.len = platform.audio.spec.freq * platform.audio.spec.channels * sizeof(s16) / TIC_FRAMERATE;
platform.audio.cvt.buf = SDL_malloc(platform.audio.cvt.len * platform.audio.cvt.len_mult);
}
}
@@ -162,15 +184,89 @@ static void updateGamepadParts()
platform.gamepad.part.y = (SDL_Point){rect.w - 2*tileSize, 0*tileSize + offset};
}
static void drawKeyboardLabels(s32 shift)
{
tic_mem* tic = platform.studio->tic;
typedef struct {const char* text; s32 x; s32 y; bool alt; const char* shift;} Label;
static const Label Labels[] =
{
#include "kbdlabels.inl"
};
for(s32 i = 0; i < COUNT_OF(Labels); i++)
{
const Label* label = Labels + i;
if(label->text)
tic->api.text(tic, label->text, label->x, label->y + shift, tic_color_dark_gray, label->alt);
if(label->shift)
tic->api.fixed_text(tic, label->shift, label->x + 6, label->y + shift + 2, tic_color_light_blue, label->alt);
}
}
static void initTouchKeyboard()
{
tic_mem* tic = platform.studio->tic;
enum{Cols=KBD_COLS, Rows=KBD_ROWS};
// TODO: add touch keyboard to one texture with gamepad (and mouse cursor???)
if(!platform.keyboard.texture.up)
{
platform.keyboard.texture.up = GPU_CreateImage(TIC80_FULLWIDTH, TIC80_FULLHEIGHT, STUDIO_PIXEL_FORMAT);
GPU_SetAnchor(platform.keyboard.texture.up, 0, 0);
GPU_SetImageFilter(platform.keyboard.texture.up, GPU_FILTER_NEAREST);
}
{
memcpy(tic->ram.vram.palette.data, platform.studio->config()->cart->bank0.palette.data, sizeof(tic_palette));
tic->api.clear(tic, 0);
tic->api.map(tic, &platform.studio->config()->cart->bank0.map,
&platform.studio->config()->cart->bank0.tiles, 8, 0, Cols, Rows, 0, 0, -1, 1);
drawKeyboardLabels(0);
tic->api.blit(tic, NULL, NULL, NULL);
GPU_UpdateImageBytes(platform.keyboard.texture.up, NULL, (const u8*)tic->screen, TIC80_FULLWIDTH * sizeof(u32));
}
if(!platform.keyboard.texture.down)
{
platform.keyboard.texture.down = GPU_CreateImage(TIC80_FULLWIDTH, TIC80_FULLHEIGHT, STUDIO_PIXEL_FORMAT);
GPU_SetAnchor(platform.keyboard.texture.down, 0, 0);
GPU_SetImageFilter(platform.keyboard.texture.down, GPU_FILTER_NEAREST);
}
{
memcpy(tic->ram.vram.palette.data, platform.studio->config()->cart->bank0.palette.data, sizeof(tic_palette));
tic->api.map(tic, &platform.studio->config()->cart->bank0.map,
&platform.studio->config()->cart->bank0.tiles, TIC_MAP_SCREEN_WIDTH+8, 0, Cols, Rows, 0, 0, -1, 1);
drawKeyboardLabels(2);
tic->api.blit(tic, NULL, NULL, NULL);
GPU_UpdateImageBytes(platform.keyboard.texture.down, NULL, (const u8*)tic->screen, TIC80_FULLWIDTH * sizeof(u32));
}
}
static void initTouchGamepad()
{
platform.studio->tic->api.map(platform.studio->tic, &platform.studio->config()->cart->bank0.map, &platform.studio->config()->cart->bank0.tiles, 0, 0, TIC_MAP_SCREEN_WIDTH, TIC_MAP_SCREEN_HEIGHT, 0, 0, -1, 1);
platform.studio->tic->api.map(platform.studio->tic, &platform.studio->config()->cart->bank0.map,
&platform.studio->config()->cart->bank0.tiles, 0, 0, TIC_MAP_SCREEN_WIDTH, TIC_MAP_SCREEN_HEIGHT, 0, 0, -1, 1);
if(!platform.gamepad.texture)
{
platform.gamepad.texture = GPU_CreateImage(TEXTURE_SIZE, TEXTURE_SIZE, STUDIO_PIXEL_FORMAT);
GPU_SetAnchor(platform.gamepad.texture, 0, 0);
GPU_SetImageFilter(platform.gamepad.texture, GPU_FILTER_NEAREST);
GPU_SetRGBA(platform.gamepad.texture, 0xff, 0xff, 0xff, platform.studio->config()->theme.gamepad.touch.alpha);
}
u32* data = SDL_malloc(TEXTURE_SIZE * TEXTURE_SIZE * sizeof(u32));
@@ -282,16 +378,20 @@ static void processMouse()
SDL_Rect rect = {0, 0, 0, 0};
calcTextureRect(&rect);
s32 x = -1, y = -1;
if(crtMonitorEnabled())
{
if(rect.w) input->mouse.x = (mx - rect.x) * TIC80_FULLWIDTH / rect.w - OFFSET_LEFT;
if(rect.h) input->mouse.y = (my - rect.y) * TIC80_FULLHEIGHT / rect.h - OFFSET_TOP;
if(rect.w) x = (mx - rect.x) * TIC80_FULLWIDTH / rect.w - OFFSET_LEFT;
if(rect.h) y = (my - rect.y) * TIC80_FULLHEIGHT / rect.h - OFFSET_TOP;
}
else
{
if(rect.w) input->mouse.x = (mx - rect.x) * TIC80_WIDTH / rect.w;
if(rect.h) input->mouse.y = (my - rect.y) * TIC80_HEIGHT / rect.h;
if(rect.w) x = (mx - rect.x) * TIC80_WIDTH / rect.w;
if(rect.h) y = (my - rect.y) * TIC80_HEIGHT / rect.h;
}
input->mouse.x = x >= 0 && x < 0xff ? x : 0xff;
input->mouse.y = y >= 0 && y < 0xff ? y : 0xff;
}
{
@@ -303,19 +403,29 @@ static void processMouse()
static void processKeyboard()
{
static const u8 KeyboardCodes[] =
{
#include "keycodes.c"
};
tic_mem* tic = platform.studio->tic;
tic80_input* input = &platform.studio->tic->ram.input;
{
SDL_Keymod mod = SDL_GetModState();
platform.keyboard.state[tic_key_shift] = mod & KMOD_SHIFT;
platform.keyboard.state[tic_key_ctrl] = mod & (KMOD_CTRL | KMOD_GUI);
platform.keyboard.state[tic_key_alt] = mod & KMOD_LALT;
platform.keyboard.state[tic_key_capslock] = mod & KMOD_CAPS;
// it's weird, but system sends CTRL when you press RALT
if(mod & KMOD_RALT)
platform.keyboard.state[tic_key_ctrl] = false;
}
tic80_input* input = &tic->ram.input;
input->keyboard.data = 0;
const u8* keyboard = SDL_GetKeyboardState(NULL);
enum{BufSize = COUNT_OF(input->keyboard.keys)};
for(s32 i = 0, c = 0; i < COUNT_OF(KeyboardCodes) && c < COUNT_OF(input->keyboard.keys); i++)
if(keyboard[i] && KeyboardCodes[i] > tic_key_unknown)
input->keyboard.keys[c++] = KeyboardCodes[i];
for(s32 i = 0, c = 0; i < COUNT_OF(platform.keyboard.state) && c < BufSize; i++)
if(platform.keyboard.state[i] || platform.keyboard.touch.state[i])
input->keyboard.keys[c++] = i;
}
#if !defined(__EMSCRIPTEN__) && !defined(__MACOSX__)
@@ -330,24 +440,9 @@ static bool checkTouch(const SDL_Rect* rect, s32* x, s32* y)
{
SDL_TouchID id = SDL_GetTouchDevice(i);
// very strange, but on Android id always == 0
//if (id)
{
s32 fingers = SDL_GetNumTouchFingers(id);
if(fingers)
{
platform.gamepad.counter = 0;
if (!platform.gamepad.show)
{
platform.gamepad.alpha = platform.studio->config()->theme.gamepad.touch.alpha;
GPU_SetRGBA(platform.gamepad.texture, 0xff, 0xff, 0xff, platform.gamepad.alpha);
platform.gamepad.show = true;
return false;
}
}
for (s32 f = 0; f < fingers; f++)
{
SDL_Finger* finger = SDL_GetTouchFinger(id, f);
@@ -369,10 +464,82 @@ static bool checkTouch(const SDL_Rect* rect, s32* x, s32* y)
return false;
}
static void processTouchGamepad()
static bool isKbdVisible()
{
s32 w, h;
SDL_GetWindowSize(platform.window, &w, &h);
SDL_Rect rect;
calcTextureRect(&rect);
float scale = (float)w / (KBD_COLS*TIC_SPRITESIZE);
return h - KBD_ROWS*TIC_SPRITESIZE*scale - (rect.h + rect.y*2) >= 0;
}
static void processTouchKeyboard()
{
if(platform.touchCounter == 0 || !isKbdVisible()) return;
enum{Cols=KBD_COLS, Rows=KBD_ROWS};
s32 w, h;
SDL_GetWindowSize(platform.window, &w, &h);
float scale = (float)w / (KBD_COLS*TIC_SPRITESIZE);
SDL_Rect kbd = {0, h - KBD_ROWS*TIC_SPRITESIZE*scale,
KBD_COLS*TIC_SPRITESIZE*scale, KBD_ROWS*TIC_SPRITESIZE*scale};
static const tic_key KbdLayout[] =
{
#include "kbdlayout.inl"
};
tic_mem* tic = platform.studio->tic;
tic80_input* input = &tic->ram.input;
s32 devices = SDL_GetNumTouchDevices();
enum {BufSize = COUNT_OF(input->keyboard.keys)};
SDL_memset(&platform.keyboard.touch.state, 0, sizeof platform.keyboard.touch.state);
for (s32 i = 0; i < devices; i++)
{
SDL_TouchID id = SDL_GetTouchDevice(i);
s32 fingers = SDL_GetNumTouchFingers(id);
for (s32 f = 0; f < fingers; f++)
{
SDL_Finger* finger = SDL_GetTouchFinger(id, f);
if (finger && finger->pressure > 0.0f)
{
SDL_Point pt = {finger->x * w, finger->y * h};
if(SDL_PointInRect(&pt, &kbd))
{
pt.x -= kbd.x;
pt.y -= kbd.y;
pt.x /= scale;
pt.y /= scale;
platform.keyboard.touch.state[KbdLayout[pt.x / TIC_SPRITESIZE + pt.y / TIC_SPRITESIZE * Cols]] = true;
}
}
}
}
}
static void processTouchGamepad()
{
platform.gamepad.touch.data = 0;
if(platform.touchCounter == 0) return;
const s32 size = platform.gamepad.part.size;
s32 x = 0, y = 0;
@@ -517,15 +684,7 @@ static void processJoysticks()
if(back)
{
tic_mem* tic = platform.studio->tic;
for(s32 i = 0; i < TIC80_KEY_BUFFER; i++)
{
if(!tic->ram.input.keyboard.keys[i])
{
tic->ram.input.keyboard.keys[i] = tic_key_escape;
break;
}
}
tic->ram.input.keyboard.keys[0] = tic_key_escape;
}
}
}
@@ -539,9 +698,6 @@ static void processJoysticks()
static void processGamepad()
{
#if !defined(__EMSCRIPTEN__) && !defined(__MACOSX__)
processTouchGamepad();
#endif
processJoysticks();
{
@@ -552,13 +708,51 @@ static void processGamepad()
}
}
static void processTouchInput()
{
#if !defined(__EMSCRIPTEN__) && !defined(__MACOSX__)
{
s32 devices = SDL_GetNumTouchDevices();
for (s32 i = 0; i < devices; i++)
if(SDL_GetNumTouchFingers(SDL_GetTouchDevice(i)) > 0)
platform.touchCounter = 10 * TIC_FRAMERATE;
if(platform.touchCounter)
platform.touchCounter--;
}
platform.studio->isGamepadMode()
? processTouchGamepad()
: processTouchKeyboard();
#endif
}
static void handleKeydown(SDL_Keycode keycode, bool down)
{
static const u32 KeyboardCodes[tic_keys_count] =
{
#include "keycodes.inl"
};
for(tic_key i = 0; i < COUNT_OF(KeyboardCodes); i++)
{
if(KeyboardCodes[i] == keycode)
{
platform.keyboard.state[i] = down;
break;
}
}
if(keycode == SDLK_AC_BACK)
platform.keyboard.state[tic_key_escape] = down;
}
static void pollEvent()
{
tic80_input* input = &platform.studio->tic->ram.input;
tic_mem* tic = platform.studio->tic;
tic80_input* input = &tic->ram.input;
{
input->mouse.btns = 0;
}
input->mouse.btns = 0;
SDL_Event event;
@@ -609,9 +803,17 @@ static void pollEvent()
updateGamepadParts();
}
break;
case SDL_WINDOWEVENT_FOCUS_GAINED: platform.studio->updateProject(); break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
platform.studio->updateProject();
break;
}
break;
case SDL_KEYDOWN:
handleKeydown(event.key.keysym.sym, true);
break;
case SDL_KEYUP:
handleKeydown(event.key.keysym.sym, false);
break;
case SDL_QUIT:
platform.studio->exit();
break;
@@ -621,6 +823,7 @@ static void pollEvent()
}
processMouse();
processTouchInput();
processKeyboard();
processGamepad();
}
@@ -675,9 +878,53 @@ static void blitSound()
else SDL_QueueAudio(platform.audio.device, tic->samples.buffer, tic->samples.size);
}
#if !defined(__EMSCRIPTEN__) && !defined(__MACOSX__)
static void renderKeyboard()
{
if(platform.touchCounter == 0 || !isKbdVisible()) return;
SDL_Rect rect;
SDL_GetWindowSize(platform.window, &rect.w, &rect.h);
GPU_Rect src = {OFFSET_LEFT, OFFSET_TOP, KBD_COLS*TIC_SPRITESIZE, KBD_ROWS*TIC_SPRITESIZE};
float scale = rect.w/src.w;
GPU_Rect dst = (GPU_Rect){0, rect.h - KBD_ROWS*TIC_SPRITESIZE*scale, scale, scale};
GPU_BlitScale(platform.keyboard.texture.up, &src, platform.gpu.screen, dst.x, dst.y, dst.w, dst.h);
static const tic_key KbdLayout[] =
{
#include "kbdlayout.inl"
};
tic80_input* input = &platform.studio->tic->ram.input;
enum{Cols=KBD_COLS, Rows=KBD_ROWS};
for(s32 i = 0; i < COUNT_OF(input->keyboard.keys); i++)
{
tic_key key = input->keyboard.keys[i];
if(key > tic_key_unknown)
{
for(s32 k = 0; k < COUNT_OF(KbdLayout); k++)
{
if(key == KbdLayout[k])
{
GPU_Rect src = {(k % Cols)*TIC_SPRITESIZE + OFFSET_LEFT, (k / Cols)*TIC_SPRITESIZE + OFFSET_TOP,
TIC_SPRITESIZE, TIC_SPRITESIZE};
GPU_BlitScale(platform.keyboard.texture.down, &src, platform.gpu.screen,
(src.x - OFFSET_LEFT) * dst.w, (src.y - OFFSET_TOP) * dst.h + dst.y, dst.w, dst.h);
}
}
}
}
}
static void renderGamepad()
{
if(platform.gamepad.show || platform.gamepad.alpha); else return;
if(platform.touchCounter == 0) return;
const s32 tileSize = platform.gamepad.part.size;
const SDL_Point axis = platform.gamepad.part.axis;
@@ -695,35 +942,19 @@ static void renderGamepad()
{platform.studio->tic->ram.input.gamepads.first.y, platform.gamepad.part.y.x, platform.gamepad.part.y.y},
};
enum {ButtonsCount = 8};
for(s32 i = 0; i < COUNT_OF(Tiles); i++)
{
const Tile* tile = Tiles + i;
GPU_Rect src = {(tile->press ? ButtonsCount + i : i) * TIC_SPRITESIZE, 0, TIC_SPRITESIZE, TIC_SPRITESIZE};
GPU_Rect src = {i * TIC_SPRITESIZE, tile->press ? TIC_SPRITESIZE : 0, TIC_SPRITESIZE, TIC_SPRITESIZE};
GPU_Rect dest = {tile->x, tile->y, tileSize, tileSize};
GPU_BlitScale(platform.gamepad.texture, &src, platform.gpu.screen, dest.x, dest.y,
(float)dest.w / TIC_SPRITESIZE, (float)dest.h / TIC_SPRITESIZE);
}
if(!platform.gamepad.show && platform.gamepad.alpha)
{
enum {Step = 3};
if(platform.gamepad.alpha - Step >= 0) platform.gamepad.alpha -= Step;
else platform.gamepad.alpha = 0;
GPU_SetRGBA(platform.gamepad.texture, 0xff, 0xff, 0xff, platform.gamepad.alpha);
}
platform.gamepad.counter = platform.gamepad.touch.data ? 0 : platform.gamepad.counter+1;
// wait 5 seconds and hide touch gamepad
if(platform.gamepad.counter >= 5 * TIC_FRAMERATE)
platform.gamepad.show = false;
}
#endif
static void blitCursor(const u8* in)
{
if(!platform.mouse.texture)
@@ -916,7 +1147,7 @@ static void openSystemPath(const char* path)
sprintf(command, "explorer \"%s\"", path);
wchar_t wcommand[FILENAME_MAX];
mbstowcs(wcommand, command, FILENAME_MAX);
MultiByteToWideChar(CP_UTF8, 0, command, FILENAME_MAX, wcommand, FILENAME_MAX);
_wsystem(wcommand);
@@ -958,7 +1189,7 @@ static void preseed()
static char* prepareShader(const char* code)
{
GPU_Renderer* renderer = GPU_GetCurrentRenderer();
const char* header = "";
const char* header = "";
if(renderer->shader_language == GPU_LANGUAGE_GLSL)
{
@@ -1050,10 +1281,7 @@ static void loadCrtShader()
static void updateConfig()
{
if(platform.gpu.screen)
{
initTouchGamepad();
loadCrtShader();
}
}
static System systemInterface =
@@ -1103,8 +1331,11 @@ static void gpuTick()
GPU_UpdateImageBytes(platform.gpu.texture, NULL, (const u8*)tic->screen, TIC80_FULLWIDTH * sizeof(u32));
{
if(crtMonitorEnabled())
if(platform.studio->config()->crtMonitor)
{
if(platform.gpu.shader == 0)
loadCrtShader();
SDL_Rect rect = {0, 0, 0, 0};
calcTextureRect(&rect);
@@ -1135,7 +1366,12 @@ static void gpuTick()
}
renderCursor();
renderGamepad();
#if !defined(__EMSCRIPTEN__) && !defined(__MACOSX__)
platform.studio->isGamepadMode()
? renderGamepad()
: renderKeyboard();
#endif
}
GPU_Flip(platform.gpu.screen);
@@ -1171,6 +1407,9 @@ static void emsGpuTick()
static s32 start(s32 argc, char **argv, const char* folder)
{
SDL_SetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, "1");
SDL_SetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, "0");
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
initSound();
@@ -1198,13 +1437,12 @@ static s32 start(s32 argc, char **argv, const char* folder)
}
initTouchGamepad();
initTouchKeyboard();
platform.gpu.texture = GPU_CreateImage(TIC80_FULLWIDTH, TIC80_FULLHEIGHT, STUDIO_PIXEL_FORMAT);
GPU_SetAnchor(platform.gpu.texture, 0, 0);
GPU_SetImageFilter(platform.gpu.texture, GPU_FILTER_NEAREST);
loadCrtShader();
#if defined(__EMSCRIPTEN__)
emscripten_set_main_loop(emsGpuTick, 0, 1);
@@ -1252,6 +1490,12 @@ static s32 start(s32 argc, char **argv, const char* folder)
if(platform.gamepad.texture)
GPU_FreeImage(platform.gamepad.texture);
if(platform.keyboard.texture.up)
GPU_FreeImage(platform.keyboard.texture.up);
if(platform.keyboard.texture.down)
GPU_FreeImage(platform.keyboard.texture.down);
if(platform.mouse.texture)
GPU_FreeImage(platform.mouse.texture);
+4 -6
View File
@@ -52,6 +52,8 @@ typedef struct
u8 select;
u8 cursor;
bool shadow;
bool altFont;
} code;
struct
@@ -63,12 +65,6 @@ typedef struct
} gamepad;
struct
{
s32 width;
s32 height;
} font;
} theme;
s32 gifScale;
@@ -97,6 +93,8 @@ typedef struct
void (*updateProject)();
const StudioConfig* (*config)();
// TODO: remove this method, system has to know nothing about current mode
bool (*isGamepadMode)();
} Studio;
TIC80_API Studio* studioInit(s32 argc, char **argv, s32 samplerate, const char* appFolder, System* system);
+268 -237
View File
File diff suppressed because it is too large Load Diff
+61 -25
View File
@@ -27,9 +27,9 @@
#include "defines.h"
#define TIC_VERSION_MAJOR 0
#define TIC_VERSION_MINOR 70
#define TIC_VERSION_MINOR 80
#define TIC_VERSION_PATCH 0
#define TIC_VERSION_STATUS "-dev.2"
#define TIC_VERSION_STATUS "-dev"
#if defined(TIC80_PRO)
#define TIC_VERSION_POST " Pro"
@@ -53,6 +53,9 @@
#define TIC_VRAM_SIZE (16*1024) //16K
#define TIC_RAM_SIZE (80*1024) //80K
#define TIC_FONT_WIDTH 6
#define TIC_FONT_HEIGHT 6
#define TIC_ALTFONT_WIDTH 4
#define TIC_PALETTE_BPP 4
#define TIC_PALETTE_SIZE (1 << TIC_PALETTE_BPP)
#define TIC_FRAMERATE 60
@@ -76,6 +79,7 @@
#define TIC_SAVEID_SIZE 64
#define TIC_SOUND_CHANNELS 4
#define TIC_STEREO_CHANNLES 2
#define SFX_TICKS 30
#define SFX_COUNT_BITS 6
#define SFX_COUNT (1 << SFX_COUNT_BITS)
@@ -109,6 +113,10 @@
#define TIC_GAMEPADS (sizeof(tic80_gamepads) / sizeof(tic80_gamepad))
#define SFX_NOTES {"C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"}
#define TIC_FONT_CHARS 256
#define KEYBOARD_HOLD 20
#define KEYBOARD_PERIOD 3
enum
{
@@ -178,8 +186,9 @@ typedef struct
s8 speed:3;
u8 reverse:1; // arpeggio reverse
u8 note:4;
u8 chain:1;
u8 temp:3;
u8 stereo_left:1;
u8 stereo_right:1;
u8 temp:2;
};
union
@@ -259,18 +268,50 @@ typedef struct
tic_tracks tracks;
}tic_music;
typedef enum
{
tic_music_stop,
tic_music_play_frame,
tic_music_play,
} tic_music_state;
typedef struct
{
s8 track;
s8 frame;
s8 row;
struct
{
s8 track;
s8 frame;
s8 row;
} music;
struct
{
bool loop:1;
u8 music_loop:1;
u8 music_state:2; // enum tic_music_state
u8 unknown:5;
} flag;
} tic_music_pos;
} tic_sound_state;
typedef union
{
struct
{
u8 left1:4;
u8 right1:4;
u8 left2:4;
u8 right2:4;
u8 left3:4;
u8 right3:4;
u8 left4:4;
u8 right4:4;
};
u32 data;
} tic_stereo_volume;
typedef struct
{
@@ -330,7 +371,6 @@ typedef struct
tic_map map;
tic_sfx sfx;
tic_music music;
tic_code code;
tic_palette palette;
} tic_bank;
@@ -338,24 +378,19 @@ typedef struct
{
union
{
struct
{
tic_bank bank0;
tic_bank bank1;
tic_bank bank2;
tic_bank bank3;
tic_bank bank4;
tic_bank bank5;
tic_bank bank6;
tic_bank bank7;
};
tic_bank bank0;
tic_bank banks[TIC_BANKS];
};
tic_code code;
tic_cover_image cover;
} tic_cartridge;
typedef struct
{
u8 data[TIC_FONT_CHARS * BITS_IN_BYTE];
} tic_font;
typedef struct
{
u8 data[TIC80_WIDTH * TIC80_HEIGHT * TIC_PALETTE_BPP / BITS_IN_BYTE];
@@ -416,11 +451,12 @@ typedef union
tic_tiles sprites;
tic_map map;
tic80_input input;
u8 unknown[16];
u8 unknown[12];
tic_stereo_volume stereo;
tic_sound_register registers[TIC_SOUND_CHANNELS];
tic_sfx sfx;
tic_music music;
tic_music_pos music_pos;
tic_sound_state sound_state;
};
u8 data[TIC_RAM_SIZE];
+2 -6
View File
File diff suppressed because one or more lines are too long
+5 -13
View File
@@ -24,8 +24,6 @@
#include "tic.h"
#define TIC_FONT_CHARS 128
typedef struct { u8 index; tic_flip flip; tic_rotate rotate; } RemapResult;
typedef void(*RemapFunc)(void*, s32 x, s32 y, RemapResult* result);
typedef struct
@@ -123,10 +121,10 @@ struct tic_script_config
typedef struct
{
s32 (*draw_char) (tic_mem* memory, u8 symbol, s32 x, s32 y, u8 color);
s32 (*text) (tic_mem* memory, const char* text, s32 x, s32 y, u8 color);
s32 (*fixed_text) (tic_mem* memory, const char* text, s32 x, s32 y, u8 color);
s32 (*text_ex) (tic_mem* memory, const char* text, s32 x, s32 y, u8 color, bool fixed, s32 scale);
s32 (*draw_char) (tic_mem* memory, u8 symbol, s32 x, s32 y, u8 color, bool alt);
s32 (*text) (tic_mem* memory, const char* text, s32 x, s32 y, u8 color, bool alt);
s32 (*fixed_text) (tic_mem* memory, const char* text, s32 x, s32 y, u8 color, bool alt);
s32 (*text_ex) (tic_mem* memory, const char* text, s32 x, s32 y, u8 color, bool fixed, s32 scale, bool alt);
void (*clear) (tic_mem* memory, u8 color);
void (*pixel) (tic_mem* memory, s32 x, s32 y, u8 color);
u8 (*get_pixel) (tic_mem* memory, s32 x, s32 y);
@@ -176,6 +174,7 @@ struct tic_mem
{
tic_ram ram;
tic_cartridge cart;
tic_font font;
tic_api api;
tic_persistent persistent;
@@ -200,13 +199,6 @@ struct tic_mem
} samples;
u32 screen[TIC80_FULLWIDTH * TIC80_FULLHEIGHT];
struct
{
u8 data[TIC_FONT_CHARS * BITS_IN_BYTE];
s32 width;
s32 height;
} font;
};
tic_mem* tic_create(s32 samplerate);
+1 -1
View File
@@ -23,8 +23,8 @@
#pragma once
#include "studio.h"
#include "map.h"
typedef struct Map Map;
typedef struct World World;
struct World
+73 -11
View File
@@ -91,6 +91,7 @@ class TIC {\n\
foreign static poke4(addr, val)\n\
foreign static memcpy(dst, src, size)\n\
foreign static memset(dst, src, size)\n\
foreign static pmem(index)\n\
foreign static pmem(index, val)\n\
foreign static sfx(id)\n\
foreign static sfx(id, note)\n\
@@ -112,15 +113,16 @@ class TIC {\n\
foreign static map_width__\n\
foreign static map_height__\n\
foreign static spritesize__\n\
foreign static print__(v, x, y, color, fixed, scale)\n\
foreign static print__(v, x, y, color, fixed, scale, alt)\n\
foreign static trace__(msg, color)\n\
foreign static spr__(id, x, y, alpha_color, scale, flip, rotate)\n\
foreign static mgeti__(index)\n\
static print(v) { TIC.print__(v.toString, 0, 0, 15, false, 1) }\n\
static print(v,x,y) { TIC.print__(v.toString, x, y, 15, false, 1) }\n\
static print(v,x,y,color) { TIC.print__(v.toString, x, y, color, false, 1) }\n\
static print(v,x,y,color,fixed) { TIC.print__(v.toString, x, y, color, fixed, 1) }\n\
static print(v,x,y,color,fixed,scale) { TIC.print__(v.toString, x, y, color, fixed, scale) }\n\
static print(v) { TIC.print__(v.toString, 0, 0, 15, false, 1, false) }\n\
static print(v,x,y) { TIC.print__(v.toString, x, y, 15, false, 1, false) }\n\
static print(v,x,y,color) { TIC.print__(v.toString, x, y, color, false, 1, false) }\n\
static print(v,x,y,color,fixed) { TIC.print__(v.toString, x, y, color, fixed, 1, false) }\n\
static print(v,x,y,color,fixed,scale) { TIC.print__(v.toString, x, y, color, fixed, scale, false) }\n\
static print(v,x,y,color,fixed,scale,alt) { TIC.print__(v.toString, x, y, color, fixed, scale, alt) }\n\
static trace(v) { TIC.trace__(v.toString, 15) }\n\
static trace(v,color) { TIC.trace__(v.toString, color) }\n\
static map(cell_x, cell_y, cell_w, cell_h, x, y, alpha_color, scale, remap) {\n\
@@ -397,7 +399,9 @@ static void wren_print(WrenVM* vm)
return;
}
s32 size = memory->api.text_ex(memory, text, x, y, color, fixed, scale);
bool alt = wrenGetSlotBool(vm, 7);
s32 size = memory->api.text_ex(memory, text, x, y, color, fixed, scale, alt);
wrenSetSlotDouble(vm, 0, size);
}
@@ -422,6 +426,7 @@ static void wren_font(WrenVM* vm)
u8 chromakey = 0;
bool fixed = false;
s32 scale = 1;
bool alt = false;
if(top > 3)
{
@@ -444,6 +449,11 @@ static void wren_font(WrenVM* vm)
if(top > 8)
{
scale = getWrenNumber(vm, 8);
if(top > 9)
{
alt = wrenGetSlotBool(vm, 9);
}
}
}
}
@@ -456,7 +466,7 @@ static void wren_font(WrenVM* vm)
return;
}
s32 size = drawText(memory, text ? text : "null", x, y, width, height, chromakey, scale, fixed ? drawSpriteFont : drawFixedSpriteFont);
s32 size = drawText(memory, text ? text : "null", x, y, width, height, chromakey, scale, fixed ? drawSpriteFont : drawFixedSpriteFont, alt);
wrenSetSlotDouble(vm, 0, size);
}
}
@@ -1057,7 +1067,7 @@ static void wren_sync(WrenVM* vm)
{
tic_mem* memory = (tic_mem*)getWrenMachine(vm);
bool toCart = true;
bool toCart = false;
u32 mask = 0;
s32 bank = 0;
@@ -1158,6 +1168,7 @@ static WrenForeignMethodFn foreignTicMethods(const char* signature)
if (strcmp(signature, "static TIC.poke4(_,_)" ) == 0) return wren_poke4;
if (strcmp(signature, "static TIC.memcpy(_,_,_)" ) == 0) return wren_memcpy;
if (strcmp(signature, "static TIC.memset(_,_,_)" ) == 0) return wren_memset;
if (strcmp(signature, "static TIC.pmem(_)" ) == 0) return wren_pmem;
if (strcmp(signature, "static TIC.pmem(_,_)" ) == 0) return wren_pmem;
if (strcmp(signature, "static TIC.sfx(_)" ) == 0) return wren_sfx;
@@ -1183,7 +1194,7 @@ static WrenForeignMethodFn foreignTicMethods(const char* signature)
if (strcmp(signature, "static TIC.map_width__" ) == 0) return wren_map_width;
if (strcmp(signature, "static TIC.map_height__" ) == 0) return wren_map_height;
if (strcmp(signature, "static TIC.spritesize__" ) == 0) return wren_spritesize;
if (strcmp(signature, "static TIC.print__(_,_,_,_,_,_)" ) == 0) return wren_print;
if (strcmp(signature, "static TIC.print__(_,_,_,_,_,_,_)" ) == 0) return wren_print;
if (strcmp(signature, "static TIC.trace__(_,_)" ) == 0) return wren_trace;
if (strcmp(signature, "static TIC.spr__(_,_,_,_,_,_,_)" ) == 0) return wren_spr_internal;
if (strcmp(signature, "static TIC.mgeti__(_)" ) == 0) return wren_mgeti;
@@ -1352,6 +1363,8 @@ static const char* const WrenKeywords [] =
"static", "super", "this", "true", "var", "while"
};
static inline bool isalnum_(char c) {return isalnum(c) || c == '_';}
static const tic_outline_item* getWrenOutline(const char* code, s32* size)
{
enum{Size = sizeof(tic_outline_item)};
@@ -1360,10 +1373,59 @@ static const tic_outline_item* getWrenOutline(const char* code, s32* size)
static tic_outline_item* items = NULL;
if(items)
{
free(items);
items = NULL;
}
const char* ptr = code;
while(true)
{
static const char ClassString[] = "class ";
ptr = strstr(ptr, ClassString);
if(ptr)
{
ptr += sizeof ClassString - 1;
const char* start = ptr;
const char* end = start;
while(*ptr)
{
char c = *ptr;
if(isalnum_(c));
else if(c == ' ' || c == '{')
{
end = ptr;
break;
}
else break;
ptr++;
}
if(end > start)
{
items = items ? realloc(items, (*size + 1) * Size) : malloc(Size);
items[*size].pos = start - code;
items[*size].size = end - start;
(*size)++;
}
}
else break;
}
return items;
}
void evalWren(tic_mem* memory, const char* code)
static void evalWren(tic_mem* memory, const char* code)
{
tic_machine* machine = (tic_machine*)memory;
wrenInterpret(machine->wren, code);