WIP: guile support
This commit is contained in:
parent
7369fcac75
commit
746b94599a
|
@ -197,6 +197,7 @@ set(TIC80CORE_SRC
|
||||||
${TIC80CORE_DIR}/luaapi.c
|
${TIC80CORE_DIR}/luaapi.c
|
||||||
${TIC80CORE_DIR}/wrenapi.c
|
${TIC80CORE_DIR}/wrenapi.c
|
||||||
${TIC80CORE_DIR}/squirrelapi.c
|
${TIC80CORE_DIR}/squirrelapi.c
|
||||||
|
${TIC80CORE_DIR}/guileapi.c
|
||||||
${TIC80CORE_DIR}/ext/gif.c
|
${TIC80CORE_DIR}/ext/gif.c
|
||||||
3rd-party/blip-buf/blip_buf.c # TODO: link it as lib?
|
3rd-party/blip-buf/blip_buf.c # TODO: link it as lib?
|
||||||
3rd-party/duktape-2.2.0/src/duktape.c # TODO: link it as lib?
|
3rd-party/duktape-2.2.0/src/duktape.c # TODO: link it as lib?
|
||||||
|
@ -637,3 +638,11 @@ foreach(TIC80_OUTPUT ${TIC80_OUTPUTS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
|
# LMAO GUILE
|
||||||
|
# include_directories(/gnu/store/9alic3caqhay3h8mx4iihpmyj6ymqpcx-guile-2.2.4/include/guile/2.2)
|
||||||
|
# link_directories(/gnu/store/9alic3caqhay3h8mx4iihpmyj6ymqpcx-guile-2.2.4/include/guile/2.2 /gnu/store/04vqghzmpqzxpd94h1q931xpmazp5s7g-libgc-7.6.6/lib)
|
||||||
|
include_directories(/usr/include/guile/2.2)
|
||||||
|
target_link_libraries(tic80core guile-2.2 pthread gc)
|
||||||
|
SET(CMAKE_C_COMPILER /usr/bin/gcc)
|
||||||
|
SET(CMAKE_CXX_COMPILER /usr/bin/c++)
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
!defined(TIC_BUILD_WITH_MOON) && \
|
!defined(TIC_BUILD_WITH_MOON) && \
|
||||||
!defined(TIC_BUILD_WITH_FENNEL) && \
|
!defined(TIC_BUILD_WITH_FENNEL) && \
|
||||||
!defined(TIC_BUILD_WITH_JS) && \
|
!defined(TIC_BUILD_WITH_JS) && \
|
||||||
!defined(TIC_BUILD_WITH_WREN)
|
!defined(TIC_BUILD_WITH_WREN) && \
|
||||||
|
!defined(TIC_BUILD_WITH_GUILE)
|
||||||
|
|
||||||
#define TIC_BUILD_WITH_LUA 1
|
#define TIC_BUILD_WITH_LUA 1
|
||||||
#define TIC_BUILD_WITH_MOON 1
|
#define TIC_BUILD_WITH_MOON 1
|
||||||
|
@ -34,7 +35,7 @@
|
||||||
#define TIC_BUILD_WITH_JS 1
|
#define TIC_BUILD_WITH_JS 1
|
||||||
#define TIC_BUILD_WITH_WREN 1
|
#define TIC_BUILD_WITH_WREN 1
|
||||||
#define TIC_BUILD_WITH_SQUIRREL 1
|
#define TIC_BUILD_WITH_SQUIRREL 1
|
||||||
|
#define TIC_BUILD_WITH_GUILE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
|
|
@ -77,6 +77,10 @@ typedef enum
|
||||||
SquirrelScript,
|
SquirrelScript,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TIC_BUILD_WITH_GUILE)
|
||||||
|
Guile,
|
||||||
|
#endif
|
||||||
|
|
||||||
} ScriptLang;
|
} ScriptLang;
|
||||||
|
|
||||||
#if defined(__TIC_WINDOWS__) || defined(__TIC_LINUX__) || defined(__TIC_MACOSX__)
|
#if defined(__TIC_WINDOWS__) || defined(__TIC_LINUX__) || defined(__TIC_MACOSX__)
|
||||||
|
@ -490,6 +494,10 @@ static void* getDemoCart(Console* console, ScriptLang script, s32* size)
|
||||||
case JavaScript: strcpy(path, DefaultJSTicPath); break;
|
case JavaScript: strcpy(path, DefaultJSTicPath); break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TIC_BUILD_WITH_GUILE)
|
||||||
|
case Guile: strcpy(path, DefaultFennelTicPath); break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TIC_BUILD_WITH_WREN)
|
#if defined(TIC_BUILD_WITH_WREN)
|
||||||
case WrenScript: strcpy(path, DefaultWrenTicPath); break;
|
case WrenScript: strcpy(path, DefaultWrenTicPath); break;
|
||||||
#endif
|
#endif
|
||||||
|
@ -695,6 +703,7 @@ static bool hasProjectExt(const char* name)
|
||||||
|| hasExt(name, PROJECT_JS_EXT)
|
|| hasExt(name, PROJECT_JS_EXT)
|
||||||
|| hasExt(name, PROJECT_WREN_EXT)
|
|| hasExt(name, PROJECT_WREN_EXT)
|
||||||
|| hasExt(name, PROJECT_SQUIRREL_EXT)
|
|| hasExt(name, PROJECT_SQUIRREL_EXT)
|
||||||
|
|| hasExt(name, PROJECT_GUILE_EXT)
|
||||||
|| hasExt(name, PROJECT_FENNEL_EXT);
|
|| hasExt(name, PROJECT_FENNEL_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,7 +715,8 @@ static const char* projectComment(const char* name)
|
||||||
|| hasExt(name, PROJECT_WREN_EXT)
|
|| hasExt(name, PROJECT_WREN_EXT)
|
||||||
|| hasExt(name, PROJECT_SQUIRREL_EXT))
|
|| hasExt(name, PROJECT_SQUIRREL_EXT))
|
||||||
comment = "//";
|
comment = "//";
|
||||||
else if(hasExt(name, PROJECT_FENNEL_EXT))
|
else if(hasExt(name, PROJECT_FENNEL_EXT)
|
||||||
|
|| hasExt(name, PROJECT_GUILE_EXT))
|
||||||
comment = ";;";
|
comment = ";;";
|
||||||
else
|
else
|
||||||
comment = "--";
|
comment = "--";
|
||||||
|
@ -1089,6 +1099,9 @@ static void onConsoleLoadCommandConfirmed(Console* console, const char* param)
|
||||||
if(!fsExistsFile(console->fs, name))
|
if(!fsExistsFile(console->fs, name))
|
||||||
name = getName(param, PROJECT_FENNEL_EXT);
|
name = getName(param, PROJECT_FENNEL_EXT);
|
||||||
|
|
||||||
|
if(!fsExistsFile(console->fs, name))
|
||||||
|
name = getName(param, PROJECT_GUILE_EXT);
|
||||||
|
|
||||||
if(!fsExistsFile(console->fs, name))
|
if(!fsExistsFile(console->fs, name))
|
||||||
name = getName(param, PROJECT_SQUIRREL_EXT);
|
name = getName(param, PROJECT_SQUIRREL_EXT);
|
||||||
|
|
||||||
|
@ -1265,6 +1278,14 @@ static void onConsoleNewCommandConfirmed(Console* console, const char* param)
|
||||||
|
|
||||||
#endif /* defined(TIC_BUILD_WITH_LUA) */
|
#endif /* defined(TIC_BUILD_WITH_LUA) */
|
||||||
|
|
||||||
|
#if defined(TIC_BUILD_WITH_GUILE)
|
||||||
|
if(strcmp(param, "guile") == 0)
|
||||||
|
{
|
||||||
|
loadDemo(console, Guile);
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TIC_BUILD_WITH_JS)
|
#if defined(TIC_BUILD_WITH_JS)
|
||||||
if(strcmp(param, "js") == 0 || strcmp(param, "javascript") == 0)
|
if(strcmp(param, "js") == 0 || strcmp(param, "javascript") == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
#include "machine.h"
|
||||||
|
|
||||||
|
//#if defined(TIC_BUILD_WITH_GUILE)
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libguile.h>
|
||||||
|
|
||||||
|
static const char TicMachine[] = "_TIC80";
|
||||||
|
|
||||||
|
// this wouldn't work with multiple guile instances
|
||||||
|
// pls hide this inside the guile interpreter
|
||||||
|
tic_mem* memory = NULL;
|
||||||
|
|
||||||
|
/* Utils */
|
||||||
|
static s32 getGuileNumber(SCM num)
|
||||||
|
{
|
||||||
|
return (s32)scm_to_signed_integer(num, INT_MIN, INT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementing the TIC-80 API */
|
||||||
|
static SCM guile_btn(SCM id)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
if (id != SCM_UNDEFINED)
|
||||||
|
{
|
||||||
|
u32 c_id = getGuileNumber(id);
|
||||||
|
r = memory->ram.input.gamepads.data & (1 << c_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = (int)memory->ram.input.gamepads.data;
|
||||||
|
}
|
||||||
|
return scm_from_bool(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM guile_btnp(SCM id, SCM hold, SCM period)
|
||||||
|
{
|
||||||
|
s32 c_id = -1;
|
||||||
|
s32 c_hold = -1;
|
||||||
|
s32 c_period = -1;
|
||||||
|
|
||||||
|
if (id != SCM_UNDEFINED) c_id = getGuileNumber(id);
|
||||||
|
if (hold != SCM_UNDEFINED) c_hold = getGuileNumber(hold);
|
||||||
|
if (period != SCM_UNDEFINED) c_period = getGuileNumber(period);
|
||||||
|
int r = (int)memory->api.btnp(memory, c_id, c_hold, c_period);
|
||||||
|
return scm_from_bool(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM guile_cls(SCM c)
|
||||||
|
{
|
||||||
|
if(c != SCM_UNDEFINED)
|
||||||
|
memory->api.clear(memory, getGuileNumber(c));
|
||||||
|
else
|
||||||
|
memory->api.clear(memory, 0);
|
||||||
|
return SCM_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM guile_print(SCM text, SCM x, SCM y, SCM color,
|
||||||
|
SCM fixed, SCM scale, SCM smallfont)
|
||||||
|
{
|
||||||
|
if (text == SCM_UNDEFINED) return scm_from_int(0);
|
||||||
|
char * c_txt = scm_to_stringn(text,NULL,"UTF-8",SCM_FAILED_CONVERSION_QUESTION_MARK);
|
||||||
|
s32 c_x = 0;
|
||||||
|
if (x != SCM_UNDEFINED) c_x = scm_to_int(x);
|
||||||
|
s32 c_y = 0;
|
||||||
|
if (y != SCM_UNDEFINED) c_y = scm_to_int(y);
|
||||||
|
s32 c_color = TIC_PALETTE_SIZE-1;
|
||||||
|
if (color != SCM_UNDEFINED) c_color = scm_to_int(color) % TIC_PALETTE_SIZE;
|
||||||
|
bool c_fixed = false;
|
||||||
|
if (fixed != SCM_UNDEFINED) c_fixed = scm_to_bool(fixed);
|
||||||
|
s32 c_scale = 1;
|
||||||
|
if (scale != SCM_UNDEFINED) c_scale = scm_to_int(scale);
|
||||||
|
bool alt = false;
|
||||||
|
if (smallfont != SCM_UNDEFINED) alt = scm_to_bool(smallfont);
|
||||||
|
s32 width = memory->api.text_ex(memory, c_txt ? c_txt : "nil",
|
||||||
|
c_x, c_y, c_color, c_fixed, c_scale, alt);
|
||||||
|
return scm_from_int(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM guile_rect(SCM x, SCM y, SCM w, SCM h, SCM color)
|
||||||
|
{
|
||||||
|
s32 c_x = -1;
|
||||||
|
s32 c_y = -1;
|
||||||
|
s32 c_w = -1;
|
||||||
|
s32 c_h = -1;
|
||||||
|
s32 c_color = -1;
|
||||||
|
if (x != SCM_UNDEFINED) c_x = getGuileNumber(x);
|
||||||
|
if (y != SCM_UNDEFINED) c_y = getGuileNumber(y);
|
||||||
|
if (w != SCM_UNDEFINED) c_w = getGuileNumber(w);
|
||||||
|
if (h != SCM_UNDEFINED) c_h = getGuileNumber(h);
|
||||||
|
if (color != SCM_UNDEFINED) c_color = getGuileNumber(color);
|
||||||
|
memory->api.rect(memory, c_x, c_y, c_w, c_h, c_color);
|
||||||
|
return scm_from_bool(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void* guile_register_functions(void * data) {
|
||||||
|
scm_c_define_gsubr("btnp", 0, 3, 0, &guile_btnp);
|
||||||
|
scm_c_define_gsubr("cls", 0, 1, 0, &guile_cls);
|
||||||
|
scm_c_define_gsubr("rect", 5, 0, 0, &guile_rect);
|
||||||
|
scm_c_define_gsubr("print", 1, 6, 0, &guile_print);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: pre-compilation
|
||||||
|
// TODO: error handling much?
|
||||||
|
static void evalGuile(tic_mem* tic, const char* code)
|
||||||
|
{
|
||||||
|
scm_c_eval_string(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool initGuile(tic_mem* tic, const char* code)
|
||||||
|
{
|
||||||
|
memory = tic;
|
||||||
|
scm_with_guile (&guile_register_functions, NULL);
|
||||||
|
evalGuile(tic, code);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void closeGuile(tic_mem* tic)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void callGuileTick(tic_mem* tic)
|
||||||
|
{
|
||||||
|
SCM ticProc = scm_c_eval_string("TIC");
|
||||||
|
// TODO, pre-load this in init
|
||||||
|
if (scm_procedure_p(ticProc))
|
||||||
|
{
|
||||||
|
// TODO: check for errors
|
||||||
|
scm_call_0(ticProc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("OwO not a procedure heh");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void callGuileScanline(tic_mem* memory, s32 row, void* data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void callGuileOverline(tic_mem* memory, void* data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const tic_outline_item* getGuileOutline(const char* code, s32* size)
|
||||||
|
{
|
||||||
|
static tic_outline_item* items = NULL;
|
||||||
|
|
||||||
|
if(items)
|
||||||
|
{
|
||||||
|
free(items);
|
||||||
|
items = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("UwU..\n");
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char* const GuileKeywords [] =
|
||||||
|
{
|
||||||
|
"do", "values", "if", "when", "each", "for", "fn", "lambda", "partial",
|
||||||
|
"while", "set", "global", "var", "local", "let", "tset",
|
||||||
|
"or", "and", "true", "false", "nil", "#", ":", "->", "->>"
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char* const ApiKeywords[] = API_KEYWORDS;
|
||||||
|
|
||||||
|
static const tic_script_config GuileSyntaxConfig =
|
||||||
|
{
|
||||||
|
.init = initGuile,
|
||||||
|
.close = closeGuile,
|
||||||
|
.tick = callGuileTick,
|
||||||
|
.scanline = callGuileScanline,
|
||||||
|
.overline = callGuileOverline,
|
||||||
|
|
||||||
|
.getOutline = getGuileOutline,
|
||||||
|
.parse = parseCode,
|
||||||
|
.eval = evalGuile,
|
||||||
|
|
||||||
|
.blockCommentStart = NULL,
|
||||||
|
.blockCommentEnd = NULL,
|
||||||
|
.blockStringStart = NULL,
|
||||||
|
.blockStringEnd = NULL,
|
||||||
|
.singleComment = ";",
|
||||||
|
|
||||||
|
.keywords = GuileKeywords,
|
||||||
|
.keywordsCount = COUNT_OF(GuileKeywords),
|
||||||
|
|
||||||
|
.api = ApiKeywords,
|
||||||
|
.apiCount = COUNT_OF(ApiKeywords),
|
||||||
|
};
|
||||||
|
|
||||||
|
const tic_script_config* getGuileConfig()
|
||||||
|
{
|
||||||
|
return &GuileSyntaxConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//#endif /* defined(TIC_BUILD_WITH_GUILE) */
|
|
@ -198,6 +198,10 @@ const tic_script_config* getFennelConfig();
|
||||||
const tic_script_config* getJsScriptConfig();
|
const tic_script_config* getJsScriptConfig();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TIC_BUILD_WITH_GUILE)
|
||||||
|
const tic_script_config* getGuileConfig();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TIC_BUILD_WITH_WREN)
|
#if defined(TIC_BUILD_WITH_WREN)
|
||||||
const tic_script_config* getWrenScriptConfig();
|
const tic_script_config* getWrenScriptConfig();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#define PROJECT_WREN_EXT ".wren"
|
#define PROJECT_WREN_EXT ".wren"
|
||||||
#define PROJECT_SQUIRREL_EXT ".nut"
|
#define PROJECT_SQUIRREL_EXT ".nut"
|
||||||
#define PROJECT_FENNEL_EXT ".fnl"
|
#define PROJECT_FENNEL_EXT ".fnl"
|
||||||
|
#define PROJECT_GUILE_EXT ".scm"
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -398,6 +398,7 @@ static bool addMenuItem(const char* name, const char* info, s32 id, void* ptr, b
|
||||||
|| hasExt(name, PROJECT_WREN_EXT)
|
|| hasExt(name, PROJECT_WREN_EXT)
|
||||||
|| hasExt(name, PROJECT_FENNEL_EXT)
|
|| hasExt(name, PROJECT_FENNEL_EXT)
|
||||||
|| hasExt(name, PROJECT_SQUIRREL_EXT)
|
|| hasExt(name, PROJECT_SQUIRREL_EXT)
|
||||||
|
|| hasExt(name, PROJECT_GUILE_EXT)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1635,6 +1635,11 @@ static const tic_script_config* getScriptConfig(const char* code)
|
||||||
return getFennelConfig();
|
return getFennelConfig();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(TIC_BUILD_WITH_GUILE)
|
||||||
|
if(compareMetatag(code, "script", "guile", getGuileConfig()->singleComment))
|
||||||
|
return getGuileConfig();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TIC_BUILD_WITH_JS)
|
#if defined(TIC_BUILD_WITH_JS)
|
||||||
if(compareMetatag(code, "script", "js", getJsScriptConfig()->singleComment) ||
|
if(compareMetatag(code, "script", "js", getJsScriptConfig()->singleComment) ||
|
||||||
compareMetatag(code, "script", "javascript", getJsScriptConfig()->singleComment))
|
compareMetatag(code, "script", "javascript", getJsScriptConfig()->singleComment))
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
;; title: game title
|
||||||
|
;; author: game developer
|
||||||
|
;; desc: short description
|
||||||
|
;; script: guile
|
||||||
|
|
||||||
|
(use-modules (srfi srfi-28))
|
||||||
|
|
||||||
|
(define c 2)
|
||||||
|
(define (TIC)
|
||||||
|
(if (btnp 0)
|
||||||
|
(set! c (+ c 1)))
|
||||||
|
(if (btnp 1)
|
||||||
|
(set! c (- c 1)))
|
||||||
|
(cls c)
|
||||||
|
(rect 0 0 240 8 0)
|
||||||
|
(print (string-append
|
||||||
|
"cls(" (format "~a" c)
|
||||||
|
") -- Use Up/Down to change")))
|
||||||
|
|
||||||
|
;; <TILES>
|
||||||
|
;; 001:efffffffff222222f8888888f8222222f8fffffff8ff0ffff8ff0ffff8ff0fff
|
||||||
|
;; 002:fffffeee2222ffee88880fee22280feefff80fff0ff80f0f0ff80f0f0ff80f0f
|
||||||
|
;; 003:efffffffff222222f8888888f8222222f8fffffff8fffffff8ff0ffff8ff0fff
|
||||||
|
;; 004:fffffeee2222ffee88880fee22280feefff80ffffff80f0f0ff80f0f0ff80f0f
|
||||||
|
;; 017:f8fffffff8888888f888f888f8888ffff8888888f2222222ff000fffefffffef
|
||||||
|
;; 018:fff800ff88880ffef8880fee88880fee88880fee2222ffee000ffeeeffffeeee
|
||||||
|
;; 019:f8fffffff8888888f888f888f8888ffff8888888f2222222ff000fffefffffef
|
||||||
|
;; 020:fff800ff88880ffef8880fee88880fee88880fee2222ffee000ffeeeffffeeee
|
||||||
|
;; </TILES>
|
||||||
|
|
||||||
|
;; <WAVES>
|
||||||
|
;; 000:00000000ffffffff00000000ffffffff
|
||||||
|
;; 001:0123456789abcdeffedcba9876543210
|
||||||
|
;; 002:0123456789abcdef0123456789abcdef
|
||||||
|
;; </WAVES>
|
||||||
|
|
||||||
|
;; <SFX>
|
||||||
|
;; 000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000304000000000
|
||||||
|
;; </SFX>
|
||||||
|
|
||||||
|
;; <PALETTE>
|
||||||
|
;; 000:140c1c44243430346d4e4a4e854c30346524d04648757161597dced27d2c8595a16daa2cd2aa996dc2cadad45edeeed6
|
||||||
|
;; </PALETTE>
|
||||||
|
|
Loading…
Reference in New Issue