diff --git a/autogen.sh b/autogen.sh index 47736e2..318d661 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,3 +1,5 @@ +#!/bin/bash + # This file is part of SmallBASIC # # Copyright(C) 2001-2020 Chris Warren-Smith. diff --git a/configure.ac b/configure.ac index a9f12a5..e3f5f79 100644 --- a/configure.ac +++ b/configure.ac @@ -33,6 +33,27 @@ function checkDebugMode() { AC_SUBST(CFLAGS) } +function generate_wayland_protocols() { + RAYLIB_SRC_PATH="${srcdir}/raylib/raylib/src" + WL_PROTOCOLS_DIR="${RAYLIB_SRC_PATH}/external/glfw/deps/wayland" + AC_MSG_NOTICE([Generating Wayland protocol headers]) + wl_generate() { + protocol="$1" + basename="$2" + "$WAYLAND_SCANNER" client-header "$protocol" "$RAYLIB_SRC_PATH/$basename.h" || exit 1 + "$WAYLAND_SCANNER" private-code "$protocol" "$RAYLIB_SRC_PATH/$basename-code.h" || exit 1 + } + wl_generate "$WL_PROTOCOLS_DIR/wayland.xml" wayland-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/xdg-shell.xml" xdg-shell-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/xdg-decoration-unstable-v1.xml" xdg-decoration-unstable-v1-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/viewporter.xml" viewporter-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/relative-pointer-unstable-v1.xml" relative-pointer-unstable-v1-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/pointer-constraints-unstable-v1.xml" pointer-constraints-unstable-v1-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/fractional-scale-v1.xml" fractional-scale-v1-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/xdg-activation-v1.xml" xdg-activation-v1-client-protocol + wl_generate "$WL_PROTOCOLS_DIR/idle-inhibit-unstable-v1.xml" idle-inhibit-unstable-v1-client-protocol +} + AC_ARG_WITH(mlpack, [AS_HELP_STRING([--with-mlpack], [Build the mlpack module])], [MLPACK="yes"], @@ -66,14 +87,22 @@ case "${host_os}" in *) PLATFORM_LDFLAGS="-Wl,--no-undefined -avoid-version" CLIPBOARD_LDFLAGS="`pkg-config xcb --libs` -lpthread" - NUKLEAR_LDFLAGS="-lGL -lm -lpthread -ldl -lrt -lX11" WEBSOCKET_LDFLAGS="" GTK_SERVER_LDFLAGS="`pkg-config --libs gtk+-3.0` -lXm -lXt" GTK_SERVER_CPPFLAGS="`pkg-config --cflags gtk+-3.0` -DGTK_SERVER_FFI -DGTK_SERVER_LIBRARY -DGTK_SERVER_UNIX -DGTK_SERVER_GTK3x" - RAYLIB_LDFLAGS="-lGL -lm -lpthread -ldl -lrt -lX11" + RAYLIB_LDFLAGS="`pkg-config wayland-client wayland-cursor wayland-egl xkbcommon --libs`" JVM_CPPFLAGS="-I/usr/lib/jvm/java-1.8.0-openjdk-amd64/include -I/usr/lib/jvm/java-1.8.0-openjdk-amd64/include/linux" JVM_LDFLAGS="-L/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/amd64/server -ljvm" - NUKLEAR_CPPFLAGS="-D_GLFW_X11=1" + NUKLEAR_CPPFLAGS="-D_GLFW_WAYLAND=1" + NUKLEAR_LDFLAGS="`pkg-config wayland-client wayland-cursor wayland-egl xkbcommon --libs`" + + AC_ARG_VAR([WAYLAND_SCANNER], [Path to wayland-scanner]) + AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner]) + AS_IF([test -n "$WAYLAND_SCANNER"], [ + generate_wayland_protocols + ], [ + AC_MSG_WARN([wayland-scanner not found; Wayland support disabled]) + ]) esac AC_SUBST(DEBUG_LDFLAGS) diff --git a/glfw/Makefile.am b/glfw/Makefile.am index dc0dbaa..35ff783 100644 --- a/glfw/Makefile.am +++ b/glfw/Makefile.am @@ -7,6 +7,7 @@ AM_CXXFLAGS=-fno-rtti -std=c++14 AM_CPPFLAGS = \ + -I../raylib/raylib/src \ -I../raylib/raylib/src/external/glfw/include \ -I../raylib/raylib/src/external/glfw/deps \ -Wall -Wextra -Wshadow -Wdouble-promotion -Wno-unused-parameter -D_GLFW_BUILD_DLL=1 diff --git a/glfw/main.cpp b/glfw/main.cpp index 2a49198..07f8872 100644 --- a/glfw/main.cpp +++ b/glfw/main.cpp @@ -404,3 +404,7 @@ SBLIB_API void sblib_ellipse(int xc, int yc, int xr, int yr, int fill) { glEnd(); } +SBLIB_API int sblib_has_window_ui(void) { + // module creates a UI in a new window + return 1; +} diff --git a/include/module.h b/include/module.h index d27ea52..c7753b2 100644 --- a/include/module.h +++ b/include/module.h @@ -25,6 +25,15 @@ extern "C" { */ int sblib_init(const char *sourceFile); +/** + * @ingroup modstd + * + * Returns whether the module is compatible with IDE builds + * + * @return non-zero on success + */ +int sblib_has_window_ui(void); + /** * @ingroup modstd * @@ -116,7 +125,7 @@ int sblib_func_exec(int index, int param_count, slib_par_t *params, var_t *retva * @param cls_id the variable class identifier * @param id the variable instance identifier */ -void sblib_free(int cls_id, int id); +int sblib_free(int cls_id, int id); /** * @ingroup modlib diff --git a/llama/llama-sb.cpp b/llama/llama-sb.cpp index 2bff5e8..0325509 100644 --- a/llama/llama-sb.cpp +++ b/llama/llama-sb.cpp @@ -31,7 +31,8 @@ Llama::Llama() : _min_p(0), _top_k(0), _max_tokens(0), - _log_level(GGML_LOG_LEVEL_CONT) { + _log_level(GGML_LOG_LEVEL_CONT), + _seed(LLAMA_DEFAULT_SEED) { llama_log_set([](enum ggml_log_level level, const char * text, void *user_data) { Llama *llama = (Llama *)user_data; if (level > llama->_log_level) { @@ -39,6 +40,7 @@ Llama::Llama() : } }, this); reset(); + llama_backend_init(); } Llama::~Llama() { @@ -51,6 +53,7 @@ Llama::~Llama() { if (_model) { llama_model_free(_model); } + llama_backend_free(); } void Llama::reset() { @@ -63,19 +66,23 @@ void Llama::reset() { _top_p = 1.0f; _min_p = 0.0f; _max_tokens = 150; + _grammar_src.clear(); + _grammar_root.clear(); + _seed = LLAMA_DEFAULT_SEED; if (_ctx) { llama_memory_clear(llama_get_memory(_ctx), true); } } -bool Llama::construct(string model_path, int n_ctx, int n_batch, int n_gpu_layers) { +bool Llama::construct(string model_path, int n_ctx, int n_batch, int n_gpu_layers, int log_level) { ggml_backend_load_all(); llama_model_params mparams = llama_model_default_params(); if (n_gpu_layers >= 0) { - mparams.n_gpu_layers = n_gpu_layers; + mparams.n_gpu_layers = n_gpu_layers; } + _log_level = log_level; _model = llama_model_load_from_file(model_path.c_str(), mparams); if (!_model) { _last_error = "Failed to load model"; @@ -93,36 +100,53 @@ bool Llama::construct(string model_path, int n_ctx, int n_batch, int n_gpu_layer _last_error = "Failed to create context"; } else { _vocab = llama_model_get_vocab(_model); - - auto sparams = llama_sampler_chain_default_params(); - sparams.no_perf = false; - _sampler = llama_sampler_chain_init(sparams); } } return _last_error.empty(); } -void Llama::configure_sampler() { - llama_sampler_reset(_sampler); +void Llama::set_grammar(const string &src, const string &root) { + _grammar_src = src; + _grammar_root = root; +} + +bool Llama::configure_sampler() { + auto sparams = llama_sampler_chain_default_params(); + sparams.no_perf = false; + llama_sampler *chain = llama_sampler_chain_init(sparams); + + if (!_grammar_src.empty()) { + llama_sampler *grammar = llama_sampler_init_grammar(_vocab, _grammar_src.c_str(), _grammar_root.c_str()); + if (!grammar) { + _last_error = "failed to initialize grammar sampler"; + return false; + } + llama_sampler_chain_add(chain, grammar); + } if (_penalty_last_n != 0 && _penalty_repeat != 1.0f) { auto penalties = llama_sampler_init_penalties(_penalty_last_n, _penalty_repeat, 0.0f, 0.0f); - llama_sampler_chain_add(_sampler, penalties); + llama_sampler_chain_add(chain, penalties); } if (_temperature <= 0.0f) { - llama_sampler_chain_add(_sampler, llama_sampler_init_greedy()); + llama_sampler_chain_add(chain, llama_sampler_init_greedy()); } else { - llama_sampler_chain_add(_sampler, llama_sampler_init_temp(_temperature)); if (_top_k > 0) { - llama_sampler_chain_add(_sampler, llama_sampler_init_top_k(_top_k)); + llama_sampler_chain_add(chain, llama_sampler_init_top_k(_top_k)); } - if (_top_p < 1.0f) { - llama_sampler_chain_add(_sampler, llama_sampler_init_top_p(_top_p, 1)); + if (_top_p < 1.0f || _min_p > 0.0f) { + llama_sampler_chain_add(chain, llama_sampler_init_top_p(_top_p, 1)); } if (_min_p > 0.0f) { - llama_sampler_chain_add(_sampler, llama_sampler_init_min_p(_min_p, 1)); + llama_sampler_chain_add(chain, llama_sampler_init_min_p(_min_p, 1)); } - llama_sampler_chain_add(_sampler, llama_sampler_init_dist(LLAMA_DEFAULT_SEED)); + llama_sampler_chain_add(chain, llama_sampler_init_temp(_temperature)); + llama_sampler_chain_add(chain, llama_sampler_init_dist(_seed)); } + if (_sampler) { + llama_sampler_free(_sampler); + } + _sampler = chain; + return true; } vector Llama::tokenize(const string &prompt) { @@ -201,7 +225,9 @@ bool Llama::make_space_for_tokens(int n_tokens, int keep_min) { } bool Llama::generate(LlamaIter &iter, const string &prompt) { - configure_sampler(); + if (!configure_sampler()) { + return false; + } vector prompt_tokens = tokenize(prompt); if (prompt_tokens.size() == 0) { diff --git a/llama/llama-sb.h b/llama/llama-sb.h index b1da148..10414c8 100644 --- a/llama/llama-sb.h +++ b/llama/llama-sb.h @@ -33,7 +33,7 @@ struct Llama { ~Llama(); // init - bool construct(string model_path, int n_ctx, int n_batch, int n_gpu_layers); + bool construct(string model_path, int n_ctx, int n_batch, int n_gpu_layers, int log_level); // generation bool generate(LlamaIter &iter, const string &prompt); @@ -50,6 +50,8 @@ struct Llama { void set_temperature(float temperature) { _temperature = temperature; } void set_top_k(int top_k) { _top_k = top_k; } void set_top_p(float top_p) { _top_p = top_p; } + void set_grammar(const string &src, const string &root); + void set_seed(unsigned int seed) { _seed = seed; } // error handling const char *last_error() { return _last_error.c_str(); } @@ -58,7 +60,7 @@ struct Llama { private: bool ends_with_sentence_boundary(const string &out); - void configure_sampler(); + bool configure_sampler(); bool make_space_for_tokens(int n_tokens, int keep_min); vector tokenize(const string &prompt); string token_to_string(LlamaIter &iter, llama_token tok); @@ -68,6 +70,8 @@ struct Llama { llama_sampler *_sampler; const llama_vocab *_vocab; vector _stop_sequences; + string _grammar_src; + string _grammar_root; string _last_error; int32_t _penalty_last_n; float _penalty_repeat; @@ -77,4 +81,5 @@ struct Llama { int _top_k; int _max_tokens; int _log_level; + unsigned int _seed; }; diff --git a/llama/llama.cpp b/llama/llama.cpp index af3be13..e365e65 160000 --- a/llama/llama.cpp +++ b/llama/llama.cpp @@ -1 +1 @@ -Subproject commit af3be131c065a38e476c34295bceda6cb956e7d7 +Subproject commit e365e658f07b63371489570dfde597f199b26c23 diff --git a/llama/main.cpp b/llama/main.cpp index 1c0de21..7b6bb75 100644 --- a/llama/main.cpp +++ b/llama/main.cpp @@ -211,6 +211,42 @@ static int cmd_llama_set_top_p(var_s *self, int argc, slib_par_t *arg, var_s *re return result; } +// +// llama.set_grammar("text") +// +static int cmd_llama_set_grammar(var_s *self, int argc, slib_par_t *arg, var_s *retval) { + int result = 0; + if (argc != 1) { + error(retval, "llama.set_grammar", 1, 1); + } else { + int id = get_llama_class_id(self, retval); + if (id != -1) { + Llama &llama = g_llama.at(id); + llama.set_grammar(get_param_str(argc, arg, 0, 0), "root"); + result = 1; + } + } + return result; +} + +// +// llama.set_seed(123) +// +static int cmd_llama_set_seed(var_s *self, int argc, slib_par_t *arg, var_s *retval) { + int result = 0; + if (argc != 1) { + error(retval, "llama.set_seed", 1, 1); + } else { + int id = get_llama_class_id(self, retval); + if (id != -1) { + Llama &llama = g_llama.at(id); + llama.set_seed(get_param_num(argc, arg, 0, 0)); + result = 1; + } + } + return result; +} + // // llama.reset() - make the model forget everything // @@ -341,9 +377,10 @@ static int cmd_create_llama(int argc, slib_par_t *params, var_t *retval) { auto n_ctx = get_param_int(argc, params, 1, 2048); auto n_batch = get_param_int(argc, params, 2, 1024); auto n_gpu_layers = get_param_int(argc, params, 3, -1); + auto n_log_level = get_param_int(argc, params, 4, GGML_LOG_LEVEL_CONT); int id = ++g_nextId; Llama &llama = g_llama[id]; - if (llama.construct(model, n_ctx, n_batch, n_gpu_layers)) { + if (llama.construct(model, n_ctx, n_batch, n_gpu_layers, n_log_level)) { map_init_id(retval, id, CLASS_ID_LLAMA); v_create_callback(retval, "add_stop", cmd_llama_add_stop); v_create_callback(retval, "generate", cmd_llama_generate); @@ -355,6 +392,8 @@ static int cmd_create_llama(int argc, slib_par_t *params, var_t *retval) { v_create_callback(retval, "set_temperature", cmd_llama_set_temperature); v_create_callback(retval, "set_top_k", cmd_llama_set_top_k); v_create_callback(retval, "set_top_p", cmd_llama_set_top_p); + v_create_callback(retval, "set_grammar", cmd_llama_set_grammar); + v_create_callback(retval, "set_seed", cmd_llama_set_seed); result = 1; } else { error(retval, llama.last_error()); @@ -365,7 +404,7 @@ static int cmd_create_llama(int argc, slib_par_t *params, var_t *retval) { } FUNC_SIG lib_func[] = { - {1, 4, "LLAMA", cmd_create_llama}, + {1, 5, "LLAMA", cmd_create_llama}, }; SBLIB_API int sblib_func_count() { @@ -388,7 +427,7 @@ int sblib_init(const char *sourceFile) { // // Release variables falling out of scope // -SBLIB_API void sblib_free(int cls_id, int id) { +SBLIB_API int sblib_free(int cls_id, int id) { if (id != -1) { switch (cls_id) { case CLASS_ID_LLAMA: @@ -403,6 +442,7 @@ SBLIB_API void sblib_free(int cls_id, int id) { break; } } + return 0; } // diff --git a/llama/samples/nitro.md b/llama/samples/nitro.md new file mode 100644 index 0000000..50587cb --- /dev/null +++ b/llama/samples/nitro.md @@ -0,0 +1,148 @@ +You are Nitro, a highly capable AI programming assistant. + +Your goal is to solve user requests accurately by combining: +1. Internal reasoning (<|think|>) +2. External data via file system tools + +--- + +## Core Principle + +Always follow this loop: + +THINK → DECIDE → ACT → RESPOND + +--- + +## Reasoning Protocol (<|think|>) + +Use <|think|> to reason BEFORE: +- Answering complex questions +- Deciding to use tools +- Writing or modifying files + +### Format + +<|think|> +- What is the user asking? +- Do I need external data (files)? +- What is the safest and most correct action? + + +### Rules + +- Keep reasoning concise and structured +- Do NOT include the final answer inside <|think|> +- Do NOT call tools inside <|think|> +- Always follow with either: + - A tool call, OR + - A final answer + +### Extra notes + +- If no user request is provided upon receiving the turn, the AI must respond with a predefined readiness message in the tone of startrek rather than attempting internal reasoning loops. +- Tools are reserved exclusively for operations that modify state (WRITE), retrieve dynamic external information (READ/LIST), or require temporal context (DATE/TIME). All logical derivations based on general programming knowledge must be answered directly. +- If the user request is ambiguous, contradictory, or lacks necessary parameters (e.g., asking to 'write' without specifying a path or content), the AI must respond with a specific clarification question rather than guessing or failing silently. Example: 'Please clarify which file you wish to modify. + +--- + +## Tool Usage (File System) + +Available commands: + +- TOOL:LIST `[directory_path. items enclosed in square brackets (`[...]`) represent directories within the file listing output]` +- TOOL:READ `[file_path]` +- TOOL:WRITE `[file_path]` +- TOOL:DATE `[Returns the current date as string with format “DD/MM/YYYY”]` +- TOOL:TIME `[Returns the time in “HH:MM:SS” format]` +- TOOL:RND [Returns a random number betweem 0 and 1]` +--- + +## Tool Decision Rules + +Use tools ONLY if: +- The user explicitly references files, OR +- The user asks for date, time or a random number OR +- The answer depends on local/project data + +Otherwise: +- Answer directly using internal knowledge + +--- + +## Tool Call Format (STRICT) + +When calling a tool, output EXACTLY on a new line: + +TOOL:COMMAND arguments + +Examples: +TOOL:LIST ./src +TOOL:READ README.md + +DO NOT: +- Include <|think|> in the same message as a tool call +- Add explanations or extra text +- Use code blocks + +--- + +## Tool Execution Flow + +1. Think using <|think|> +2. If a tool is needed → output ONLY the tool call +3. After receiving tool results → think again +4. Then provide final answer + +--- + +## File Writing Rules (TOOL:WRITE) + +Use ONLY if explicitly requested. + +Requirements: +- Write complete and valid content +- Do not overwrite without clear intent +- Preserve formatting + +--- + +## Interaction Guidelines + +- Be precise and efficient +- Ask clarifying questions if needed +- Avoid unnecessary tool calls +- Prefer direct answers when possible + +--- + +## Constraints + +- Do NOT hallucinate file contents +- Do NOT fabricate tool outputs +- Do NOT assume files exist +- Do NOT mix reasoning with tool commands +- Do NOT skip <|think|> for non-trivial tasks + +--- + +## Decision Checklist + +For every request: + +1. <|think|> Do I need files? +2. <|think|> Is the request clear? +3. <|think|> What is the best action? + +Then: +- If tool needed → CALL TOOL +- Else → ANSWER + +--- + +## Behavioral Summary + +- Think explicitly using <|think|> +- Act only when necessary +- Keep tool usage strict and clean +- Produce clear, correct final answers diff --git a/llama/samples/nitro_cli.bas b/llama/samples/nitro_cli.bas new file mode 100644 index 0000000..a3b438e --- /dev/null +++ b/llama/samples/nitro_cli.bas @@ -0,0 +1,263 @@ +' =============================================================== +' NITRO AGENT SYSTEM (Enhanced Version) +' Designed for Agentic LLM interaction with external tools. +' =============================================================== + +import llm + +' --- Configuration --- +const model = "models/google_gemma-4-E4B-it-Q4_K_L.gguf" +const knowledge_files = ["nitro.md"] + +' ANSI Color Codes +const RESET = chr(27) + "[0m" +const GREEN = chr(27) + "[32m" +const YELLOW = chr(27) + "[33m" +const BLUE = chr(27) + "[34m" +const CYAN = chr(27) + "[36m" +const RED = chr(27) + "[31m" +const BOLD_CYAN = chr(27) + "[1;36m" +const CHANNEL_END = "" + +' llama configuration +const n_ctx = 16000 +const n_batch = 512 +const n_max_tokens = 4096 +const n_temperature = 0.2 +const n_top_k = 40 +const n_top_p = 0.9 +const n_min_p = 0.05 +const n_penalty_repeat = 1.1 +const n_penalty_last_n = 256 + +sandbox_home = cwd + +' +' Displays the welcome message +' +sub welcome_message() + print + print BOLD_CYAN; + print " • • • ••••• •••• ••• " + print " •• • • • • • • • " + print " • •• • • •••• • •" + print " • • • • • • • • " + print " • • • • • • ••• " + print + print BOLD_CYAN + " N I T R O A G E N T S Y S T E M v1.0" + RESET + print "" + print CYAN + " >> Welcome to Nitro! Your AI Agent Companion. << " + RESET + print CYAN + " I am primed with several knowledge files and ready to assist." + RESET + print CYAN + " Try asking me about the contents of 'nitro.md' or listing files in './data'." + RESET + print CYAN + " Type 'exit' to quit." + RESET + print +end sub + +' +' handles the TOOL:LIST command +' +func list_files(arg) + if (arg == "./") then + arg = sandbox_home + arg + else if (arg == ".") then + arg = sandbox_home + endif + + local result = [] + + func walker(node) + if (node.depth == 0) then + if (node.dir && left(node.name, 1) != ".") then + result << "[" + node.name + "]" + else + result << node.name + endif + endif + return node.depth == 0 + end + + dirwalk arg, "", use walker(x) + return str(result) +end + +' +' handles the TOOL:READ command +' +func read_file(arg) + try + tload sandbox_home + arg, result, 1 + catch + result = "ERROR: File not found or unreadable." + end try + return result +end + +' +' handles the TOOL:WRITE command +' +func write_file(arg) + result = "OK: Data written successfully to " + arg + return result +end + +' +' Handles file system commands received from the LLM. +' +func handle_cmd(cmd) + local v, result + + split(cmd, " ", v) + local op = v[0] + local arg = iff(len(v) == 2, v[1], "") + + print RED + "TOOL:" + op + " - " + arg + RESET + + select case op + case "TOOL:DATE" + result = date + case "TOOL:TIME" + result = time + case "TOOL:RND" + result = rnd + case "TOOL:LIST" + result = list_files(arg) + case "TOOL:READ" + result = read_file(arg) + case "TOOL:WRITE" + result = write_file(arg) + case else + result = "ERROR: unknown command " + op + end select + + print RED + "TOOL RESULT:" + result + RESET + return result +end + +' +' Loads knowledge_files then returns the following format: +' +' <|turn|>system +' {nitro.md...} +' <|turn|> +' +func initialize_agent() + local prompt = "" + + for file in knowledge_files + content = "" + try + tload file, content, 1 + prompt = prompt + chr(10) + content + chr(10) + print GREEN + "✅ Loaded knowledge file: " + file + RESET + catch + print RED + "❌ ERROR: Could not load " + file + ". Check path." + RESET + end try + next + + ' Set the initial system prompt for the LLM + print YELLOW + "\n[ Nitro Agent Initialized Successfully! ]" + RESET + print + return "<|turn|>system\n" + prompt + "\n<|turn|>" +end + +' +' Execute the given tool, then returns the following format: +' +' <|turn|>tool +' {tool_output} +' <|turn|> +' <|turn|>model +' +func process_tool(tool) + return "<|turn|>tool\n" + handle_cmd(trim(tool)) + "\n<|turn|>\n<|turn|>model" +end + +' +' Process user input, then returns the following format +' +' <|turn|>user +' {user_input} +' <|turn|> +' <|turn|>model +' +func process_input() + local user_input + input "You:? ", user_input + user_input = trim(user_input) + if user_input == "exit" OR user_input = "quit" then + stop + endif + return "<|turn|>user\n" + user_input + "\n<|turn|>\n<|turn|>model" +end + +' +' Main process +' +sub main() + local llama = llm.llama(model, n_ctx, n_batch, 50) + + llama.add_stop("<|turn|>") + llama.set_max_tokens(n_max_tokens) + llama.set_temperature(n_temperature) + llama.set_top_k(n_top_k) + llama.set_top_p(n_top_p) + llama.set_min_p(n_min_p) + llama.set_penalty_repeat(n_penalty_repeat) + llama.set_penalty_last_n(n_penalty_last_n) + + local iter = llama.generate(initialize_agent()) + + while 1 + local buffer = "" + local text_colour = BLUE + + while iter.has_next() + buffer += iter.next() + local chan_end = instr(buffer, CHANNEL_END) + + if chan_end != 0 then + ' print buffer up to channel_end + buffer = left(buffer, chan_end - 1) + print text_colour + buffer + RESET + print + + ' print buffer following channel_end + text_colour = CYAN + print text_colour + mid(buffer, chan_end + len(CHANNEL_END)) + RESET; + + ' reset buffer + buffer = "" + endif + + ' Only print non-command tokens + local nl = instr(buffer, chr(10)) + if nl then + local text_line = left(buffer, nl - 1) + buffer = mid(buffer, nl + 1) + if text_line == "" then + text_colour = CYAN + else + print text_colour + text_line + RESET + end if + end if + wend + + ' Flush remaining line buffer + if len(buffer) > 0 and left(trim(buffer), 5) == "TOOL:" then + ' TOOL:xxx should always appear on the final line + iter = llama.generate(process_tool(buffer)) + else + if len(buffer) > 0 then + ' TODO: trim any trailing <|turn|> + print text_colour + buffer + RESET + endif + print + print "--- Tokens/sec: " + round(iter.tokens_sec(), 2) + " ---\n" + iter = llama.generate(process_input()) + endif + wend +end + +welcome_message() +main() +'print list_files(".") diff --git a/llama/test_main.cpp b/llama/test_main.cpp index 2c082bf..eb959b3 100644 --- a/llama/test_main.cpp +++ b/llama/test_main.cpp @@ -56,7 +56,7 @@ int main(int argc, char ** argv) { } Llama llama; - if (llama.construct(model_path, 1024, 1024, -1)) { + if (llama.construct(model_path, 1024, 1024, -1, GGML_LOG_LEVEL_CONT)) { LlamaIter iter; llama.set_max_tokens(n_predict); llama.generate(iter, prompt); diff --git a/nuklear/Makefile.am b/nuklear/Makefile.am index 5b4f06f..d96ea60 100644 --- a/nuklear/Makefile.am +++ b/nuklear/Makefile.am @@ -7,6 +7,7 @@ AM_CXXFLAGS=-fno-rtti -std=c++14 AM_CPPFLAGS = -D_GLFW_BUILD_DLL=1 @NUKLEAR_CPPFLAGS@ \ + -I../raylib/raylib/src \ -I../raylib/raylib/src/external/glfw/include \ -I../raylib/raylib/src/external/glfw/deps lib_LTLIBRARIES = libnuklear.la diff --git a/nuklear/main.cpp b/nuklear/main.cpp index 00ac348..d4ec06d 100644 --- a/nuklear/main.cpp +++ b/nuklear/main.cpp @@ -95,7 +95,7 @@ static void window_size_callback(GLFWwindow* window, int width, int height) { nk_context *nkp_create_window(const char *title, int width, int height) { if (!glfwInit()) { fprintf(stdout, "[GFLW] failed to init!\n"); - exit(1); + return nullptr; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); @@ -106,6 +106,8 @@ nk_context *nkp_create_window(const char *title, int width, int height) { title, nullptr, nullptr); glfwMakeContextCurrent(_window); + glfwSwapBuffers(_window); + gladLoadGL((GLADloadfunc) glfwGetProcAddress); glfwSetErrorCallback(error_callback); glfwSetWindowSizeCallback(_window, window_size_callback); @@ -873,16 +875,22 @@ static int cmd_widgetishovered(int argc, slib_par_t *params, var_t *retval) { } static int cmd_windowbegin(int argc, slib_par_t *params, var_t *retval) { - nkp_process_events(); - nkbd_begin(_ctx); - const char *title = get_param_str(argc, params, 0, "Untitled"); - struct nk_rect rc = get_param_rect(argc, params, 1); - nk_flags flags = get_param_window_flags(argc, params, 5); - v_setint(retval, nk_begin(_ctx, title, rc, flags)); - if ((flags & NK_WINDOW_TITLE) == 0) { - nkp_set_window_title(title); + int result; + if (_ctx != nullptr) { + nkp_process_events(); + nkbd_begin(_ctx); + const char *title = get_param_str(argc, params, 0, "Untitled"); + struct nk_rect rc = get_param_rect(argc, params, 1); + nk_flags flags = get_param_window_flags(argc, params, 5); + v_setint(retval, nk_begin(_ctx, title, rc, flags)); + if ((flags & NK_WINDOW_TITLE) == 0) { + nkp_set_window_title(title); + } + result = 1; + } else { + result = 0; } - return 1; + return result; } static int cmd_windowend(int argc, slib_par_t *params, var_t *retval) { @@ -1181,3 +1189,7 @@ SBLIB_API void sblib_ellipse(int xc, int yc, int xr, int yr, int fill) { drawEnd(); } +SBLIB_API int sblib_has_window_ui(void) { + // module creates a UI in a new window + return 1; +} diff --git a/raylib/Makefile.am b/raylib/Makefile.am index 60b17a4..84c24b5 100644 --- a/raylib/Makefile.am +++ b/raylib/Makefile.am @@ -5,11 +5,14 @@ # Download the GNU Public License (GPL) from www.gnu.org # -generated = func-def.h proc-def.h proc.h func.h sbasic=sbasic +generated = func-def.h proc-def.h proc.h func.h +raylib_api_json=raylib/tools/rlparser/output/raylib_api.json + +CLEANFILES = $(generated) -raylib/tools/rlparser/output/raylib_api.json: raylib/src/raylib.h raylib/tools/rlparser/rlparser.c - (cd raylib/tools/rlparser && make && ./rlparser --format JSON --input ../../src/raylib.h --output raylib_api.json) +$(raylib_api_json): raylib/src/raylib.h raylib/tools/rlparser/rlparser.c + (cd raylib/tools/rlparser && make && ./rlparser --format JSON --input ../../src/raylib.h --output output/raylib_api.json) UNSUPPORTED.md: $(generated) $(sbasic) mkraylib.bas unsupported > $@ @@ -17,16 +20,21 @@ UNSUPPORTED.md: $(generated) README.md: $(generated) mkreadme.bas UNSUPPORTED.md $(sbasic) mkreadme.bas `grep RAYLIB_VERSION raylib/src/raylib.h | sed 's/#define RAYLIB_VERSION//g' | sed 's/\"//g'` > README.md -$(generated): raylib/parser/raylib_api.json mkraylib.bas +$(generated): $(raylib_api_json) mkraylib.bas $(sbasic) mkraylib.bas $@ > $@ @touch main.cpp -gen: $(generated) README.md +gen: $(generated) + +gen: $(generated) + +all-am: $(generated) README.md AM_CXXFLAGS=-fno-rtti -std=c++14 -fpermissive AM_CPPFLAGS = -Iraylib/src -Iraylib/src/external/glfw/include -Iraylib/src/external/glfw/deps/mingw \ + -Iraylib/src/external/glfw/src \ -DPLATFORM_DESKTOP=1 -DSUPPORT_BUSY_WAIT_LOOP=1 -DSUPPORT_SCREEN_CAPTURE=1 \ - -DSUPPORT_GIF_RECORDING=1 -DSUPPORT_COMPRESSION_API=1 -D_GLFW_BUILD_DLL=1 \ + -DSUPPORT_GIF_RECORDING=1 -DSUPPORT_COMPRESSION_API=1 -D_GLFW_WAYLAND=1 \ -Wall -Wextra -Wshadow -Wdouble-promotion -Wno-unused-parameter -fPIC lib_LTLIBRARIES = libraylib.la @@ -39,7 +47,6 @@ libraylib_la_SOURCES = \ raylib/src/rshapes.c \ raylib/src/rtextures.c \ raylib/src/rtext.c \ - raylib/src/utils.c \ ../include/param.cpp \ ../include/hashmap.cpp \ physac.cpp \ diff --git a/raylib/README.md b/raylib/README.md index b0f9723..08f508e 100644 --- a/raylib/README.md +++ b/raylib/README.md @@ -4,7 +4,7 @@ raylib is a simple and easy-to-use library to enjoy videogames programming. https://www.raylib.com/ -Implemented APIs (633) +Implemented APIs (646) ---------------- | Name | Description | @@ -16,7 +16,7 @@ Implemented APIs (633) | sub BeginScissorMode(x, y, width, height) | Begin scissor mode (define screen area for following drawing) | | sub BeginShaderMode(shader) | Begin custom shader drawing | | sub BeginTextureMode(target) | Begin drawing to render texture | -| func ChangeDirectory(dir) | Change working directory, return true on success | +| func ChangeDirectory(dirPath) | Change working directory, return true on success | | func CheckCollisionBoxes(box1, box2) | Check collision between two bounding boxes | | func CheckCollisionBoxSphere(box, center, radius) | Check collision between box and sphere | | func CheckCollisionCircleLine(center, radius, p1, p2) | Check if circle collides with a line created betweeen two points [p1] and [p2] | @@ -52,10 +52,11 @@ Implemented APIs (633) | func ComputeCRC32(data, dataSize) | Compute CRC32 hash code | | func ComputeMD5(data, dataSize) | Compute MD5 hash code, returns static int[4] (16 bytes) | | func ComputeSHA1(data, dataSize) | Compute SHA1 hash code, returns static int[5] (20 bytes) | +| func ComputeSHA256(data, dataSize) | Compute SHA256 hash code, returns static int[8] (32 bytes) | | func createPhysicsbodycircle() | n/a | | func createPhysicsbodypolygon() | n/a | | func createPhysicsbodyrectangle() | n/a | -| func DecodeDataBase64(data, outputSize) | Decode Base64 string data, memory must be MemFree() | +| func DecodeDataBase64(text, outputSize) | Decode Base64 string (expected NULL terminated), memory must be MemFree() | | func DecompressData(compData, compDataSize, dataSize) | Decompress data (DEFLATE algorithm), memory must be MemFree() | | func destroyPhysicsbody() | n/a | | func DirectoryExists(dirPath) | Check if a directory path exists | @@ -85,11 +86,14 @@ Implemented APIs (633) | sub DrawCylinderWiresEx(startPos, endPos, startRadius, endRadius, sides, color) | Draw a cylinder wires with base at startPos and top at endPos | | sub DrawEllipse(centerX, centerY, radiusH, radiusV, color) | Draw ellipse | | sub DrawEllipseLines(centerX, centerY, radiusH, radiusV, color) | Draw ellipse outline | +| sub DrawEllipseLinesV(center, radiusH, radiusV, color) | Draw ellipse outline (Vector version) | +| sub DrawEllipseV(center, radiusH, radiusV, color) | Draw ellipse (Vector version) | | sub DrawFPS(posX, posY) | Draw current FPS | | sub DrawGrid(slices, spacing) | Draw a grid (centered at (0, 0, 0)) | | sub DrawLine(startPosX, startPosY, endPosX, endPosY, color) | Draw a line | | sub DrawLine3D(startPos, endPos, color) | Draw a line in 3D world space | | sub DrawLineBezier(startPos, endPos, thick, color) | Draw line segment cubic-bezier in-out interpolation | +| sub DrawLineDashed(startPos, endPos, dashSize, spaceSize, color) | Draw a dashed line | | sub DrawLineEx(startPos, endPos, thick, color) | Draw a line (using triangles/quads) | | sub DrawLineStrip(points, pointCount, color) | Draw lines sequence (using gl lines) | | sub DrawLineV(startPos, endPos, color) | Draw a line (using gl lines) | @@ -108,7 +112,7 @@ Implemented APIs (633) | sub DrawPolyLinesEx(center, sides, radius, rotation, lineThick, color) | Draw a polygon outline of n sides with extended parameters | | sub DrawRay(ray, color) | Draw a ray line | | sub DrawRectangle(posX, posY, width, height, color) | Draw a color-filled rectangle | -| sub DrawRectangleGradientEx(rec, topLeft, bottomLeft, topRight, bottomRight) | Draw a gradient-filled rectangle with custom vertex colors | +| sub DrawRectangleGradientEx(rec, topLeft, bottomLeft, bottomRight, topRight) | Draw a gradient-filled rectangle with custom vertex colors | | sub DrawRectangleGradientH(posX, posY, width, height, left, right) | Draw a horizontal-gradient-filled rectangle | | sub DrawRectangleGradientV(posX, posY, width, height, top, bottom) | Draw a vertical-gradient-filled rectangle | | sub DrawRectangleLines(posX, posY, width, height, color) | Draw rectangle outline | @@ -153,7 +157,7 @@ Implemented APIs (633) | sub DrawTriangleStrip3D(points, pointCount, color) | Draw a triangle strip defined by points | | sub EnableCursor() | Enables cursor (unlock cursor) | | sub EnableEventWaiting() | Enable waiting for events on EndDrawing(), no automatic event polling | -| func EncodeDataBase64(data, dataSize, outputSize) | Encode data to Base64 string, memory must be MemFree() | +| func EncodeDataBase64(data, dataSize, outputSize) | Encode data to Base64 string (includes NULL terminator), memory must be MemFree() | | sub EndBlendMode() | End blending mode (reset to default: alpha blending) | | sub EndDrawing() | End canvas drawing and swap buffers (double buffering) | | sub EndMode2D() | Ends 2D mode with custom camera | @@ -173,7 +177,13 @@ Implemented APIs (633) | func ExportWave(wave, fileName) | Export wave data to file, returns true on success | | func ExportWaveAsCode(wave, fileName) | Export wave sample data to code (.h), returns true on success | | func Fade(color, alpha) | Get color with alpha applied, alpha goes from 0.0f to 1.0f | +| func FileCopy(srcPath, dstPath) | Copy file from one path to another, dstPath created if it doesn't exist | | func FileExists(fileName) | Check if file exists | +| func FileMove(srcPath, dstPath) | Move file from one directory to another, dstPath created if it doesn't exist | +| func FileRemove(fileName) | Remove file (if exists) | +| func FileRename(fileName, fileRename) | Rename file (if exists) | +| func FileTextFindIndex(fileName, search) | Find text in existing file | +| func FileTextReplace(fileName, search, replacement) | Replace text in an existing file | | func GenImageCellular(width, height, tileSize) | Generate image: cellular algorithm, bigger tileSize means bigger cells | | func GenImageChecked(width, height, checksX, checksY, col1, col2) | Generate image: checked | | func GenImageColor(width, height, color) | Generate image: plain color | @@ -218,8 +228,8 @@ Implemented APIs (633) | func GetFontDefault() | Get the default Font | | func GetFPS() | Get current FPS | | func GetFrameTime() | Get time in seconds for last frame drawn (delta time) | -| func GetGamepadAxisCount(gamepad) | Get gamepad axis count for a gamepad | -| func GetGamepadAxisMovement(gamepad, axis) | Get axis movement value for a gamepad axis | +| func GetGamepadAxisCount(gamepad) | Get axis count for a gamepad | +| func GetGamepadAxisMovement(gamepad, axis) | Get movement value for a gamepad axis | | func GetGamepadButtonPressed() | Get the last gamepad button pressed | | func GetGamepadName(gamepad) | Get gamepad internal name id | | func GetGestureDetected() | Get latest detected gesture | @@ -282,6 +292,7 @@ Implemented APIs (633) | func GetSplinePointBezierQuad(p1, c2, p3, t) | Get (evaluate) spline point: Quadratic Bezier | | func GetSplinePointCatmullRom(p1, p2, p3, p4, t) | Get (evaluate) spline point: Catmull-Rom | | func GetSplinePointLinear(startPos, endPos, t) | Get (evaluate) spline point: Linear | +| func GetTextBetween(text, begin, end) | Get text between two strings | | func GetTime() | Get elapsed time in seconds since InitWindow() | | func GetTouchPointCount() | Get number of touch points | | func GetTouchPointId(index) | Get touch point identifier for given index | @@ -396,7 +407,7 @@ Implemented APIs (633) | func IsCursorHidden() | Check if cursor is not visible | | func IsCursorOnScreen() | Check if cursor is on the screen | | func IsFileDropped() | Check if a file has been dropped into window | -| func IsFileExtension(fileName, ext) | Check file extension (including point: .png, .wav) | +| func IsFileExtension(fileName, ext) | Check file extension (recommended include point: .png, .wav) | | func IsFileNameValid(fileName) | Check if fileName is valid for the platform/OS | | func IsFontValid(font) | Check if a font is valid (font data loaded, WARNING: GPU texture not checked) | | func IsGamepadAvailable(gamepad) | Check if a gamepad is available | @@ -498,7 +509,7 @@ Implemented APIs (633) | func pollevents() | n/a | | sub PollInputEvents() | Register all input events | | func resetPhysics() | n/a | -| sub RestoreWindow() | Set window state: not minimized/maximized | +| sub RestoreWindow() | Restore window from being minimized/maximized | | sub ResumeAudioStream(stream) | Resume audio stream | | sub ResumeMusicStream(music) | Resume playing paused music | | sub ResumeSound(sound) | Resume a paused sound | @@ -525,7 +536,7 @@ Implemented APIs (633) | sub SetMouseOffset(offsetX, offsetY) | Set mouse offset | | sub SetMousePosition(x, y) | Set mouse position XY | | sub SetMouseScale(scaleX, scaleY) | Set mouse scaling | -| sub SetMusicPan(music, pan) | Set pan for a music (0.5 is center) | +| sub SetMusicPan(music, pan) | Set pan for a music (-1.0 left, 0.0 center, 1.0 right) | | sub SetMusicPitch(music, pitch) | Set pitch for a music (1.0 is base level) | | sub SetMusicVolume(music, volume) | Set volume for music (1.0 is max level) | | func setPhysicsbodyangularvelocity() | n/a | @@ -555,7 +566,7 @@ Implemented APIs (633) | sub SetShaderValueTexture(shader, locIndex, texture) | Set shader uniform value and bind the texture (sampler2d) | | sub SetShaderValueV(shader, locIndex, value, uniformType, count) | Set shader uniform value vector | | sub SetShapesTexture(texture, source) | Set texture and rectangle to be used on shapes drawing | -| sub SetSoundPan(sound, pan) | Set pan for a sound (0.5 is center) | +| sub SetSoundPan(sound, pan) | Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) | | sub SetSoundPitch(sound, pitch) | Set pitch for a sound (1.0 is base level) | | sub SetSoundVolume(sound, volume) | Set volume for a sound (1.0 is max level) | | sub SetTargetFPS(fps) | Set target FPS (maximum) | @@ -582,14 +593,16 @@ Implemented APIs (633) | sub StopSound(sound) | Stop playing a sound | | sub SwapScreenBuffer() | Swap back buffer with front buffer (screen drawing) | | sub TakeScreenshot(fileName) | Takes a screenshot of current screen (filename extension defines format) | -| sub TextAppend(text, append, position) | Append text at specific position and move cursor! | +| sub TextAppend(text, append, position) | Append text at specific position and move cursor | | func TextCopy(dst, src) | Copy one string to another, returns bytes copied | -| func TextFindIndex(text, find) | Find first text occurrence within a string | +| func TextFindIndex(text, search) | Find first text occurrence within a string, -1 if not found | | func TextFormat(text, args) | Text formatting with variables (sprintf() style) | | func TextInsert(text, insert, position) | Insert text in a position (WARNING: memory must be freed!) | | func TextIsEqual(text1, text2) | Check if two text string are equal | | func TextLength(text) | Get text length, checks for '\\0' ending | -| func TextReplace(text, replace, by) | Replace text string (WARNING: memory must be freed!) | +| func TextRemoveSpaces(text) | Remove text spaces, concat words | +| func TextReplace(text, search, replacement) | Replace text string (WARNING: memory must be freed!) | +| func TextReplaceBetween(text, begin, end, replacement) | Replace text between two specific strings (WARNING: memory must be freed!) | | func TextSubtext(text, position, length) | Get a piece of a text string | | func TextToCamel(text) | Get Camel case notation version of provided string | | func TextToFloat(text) | Get float value from text | @@ -632,9 +645,9 @@ Implemented APIs (633) | sub UpdateModelAnimationBones(model, anim, frame) | Update model animation mesh bone matrices (GPU skinning) | | sub UpdateMusicStream(music) | Updates buffers for music streaming | | func updatePhysics() | n/a | -| sub UpdateSound(sound, data, sampleCount) | Update sound buffer with new data | -| sub UpdateTexture(texture, pixels) | Update GPU texture with new data | -| sub UpdateTextureRec(texture, rec, pixels) | Update GPU texture rectangle with new data | +| sub UpdateSound(sound, data, sampleCount) | Update sound buffer with new data (default data format: 32 bit float, stereo) | +| sub UpdateTexture(texture, pixels) | Update GPU texture with new data (pixels should be able to fill texture) | +| sub UpdateTextureRec(texture, rec, pixels) | Update GPU texture rectangle with new data (pixels and rec should fit in texture) | | sub UploadMesh(mesh, dynamic) | Upload mesh vertex data in GPU and provide VAO/VBO ids | | func waitevents() | n/a | | sub WaitTime(seconds) | Wait for some time (halt program execution) | @@ -661,6 +674,7 @@ Unimplemented APIs | LoadFontData | Load font data for further use | | LoadMaterialDefault | Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) | | LoadMaterials | Load materials from model file | +| LoadTextLines | Load text as separate lines ('\\n') | | LoadVrStereoConfig | Load VR stereo config for VR simulator device parameters | | SetAudioStreamCallback | Audio thread callback to request new data | | SetLoadFileDataCallback | Set custom file binary data loader | @@ -670,8 +684,9 @@ Unimplemented APIs | SetSaveFileTextCallback | Set custom file text data saver | | SetTraceLogCallback | Set custom trace log | | TextJoin | Join text strings with delimiter | -| TextSplit | Split text into multiple strings | +| TextSplit | Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings | | UnloadFontData | Unload font chars info data (RAM) | | UnloadMaterial | Unload material from GPU memory (VRAM) | +| UnloadTextLines | Unload text lines | | UnloadVrStereoConfig | Unload VR stereo config | diff --git a/raylib/func-def.h b/raylib/func-def.h index 831f691..42552b2 100644 --- a/raylib/func-def.h +++ b/raylib/func-def.h @@ -29,6 +29,7 @@ {2, 2, "COMPUTECRC32", cmd_computecrc32}, {2, 2, "COMPUTEMD5", cmd_computemd5}, {2, 2, "COMPUTESHA1", cmd_computesha1}, + {2, 2, "COMPUTESHA256", cmd_computesha256}, {1, 1, "DECODEDATABASE64", cmd_decodedatabase64}, {2, 2, "DECOMPRESSDATA", cmd_decompressdata}, {1, 1, "DIRECTORYEXISTS", cmd_directoryexists}, @@ -44,7 +45,13 @@ {2, 2, "EXPORTWAVE", cmd_exportwave}, {2, 2, "EXPORTWAVEASCODE", cmd_exportwaveascode}, {2, 2, "FADE", cmd_fade}, + {2, 2, "FILECOPY", cmd_filecopy}, {1, 1, "FILEEXISTS", cmd_fileexists}, + {2, 2, "FILEMOVE", cmd_filemove}, + {1, 1, "FILEREMOVE", cmd_fileremove}, + {2, 2, "FILERENAME", cmd_filerename}, + {2, 2, "FILETEXTFINDINDEX", cmd_filetextfindindex}, + {3, 3, "FILETEXTREPLACE", cmd_filetextreplace}, {3, 3, "GENIMAGECELLULAR", cmd_genimagecellular}, {6, 6, "GENIMAGECHECKED", cmd_genimagechecked}, {3, 3, "GENIMAGECOLOR", cmd_genimagecolor}, @@ -146,6 +153,7 @@ {4, 4, "GETSPLINEPOINTBEZIERQUAD", cmd_getsplinepointbezierquad}, {5, 5, "GETSPLINEPOINTCATMULLROM", cmd_getsplinepointcatmullrom}, {3, 3, "GETSPLINEPOINTLINEAR", cmd_getsplinepointlinear}, + {3, 3, "GETTEXTBETWEEN", cmd_gettextbetween}, {0, 0, "GETTIME", cmd_gettime}, {0, 0, "GETTOUCHPOINTCOUNT", cmd_gettouchpointcount}, {1, 1, "GETTOUCHPOINTID", cmd_gettouchpointid}, @@ -218,9 +226,9 @@ {1, 1, "LOADFILEDATA", cmd_loadfiledata}, {1, 1, "LOADFILETEXT", cmd_loadfiletext}, {1, 1, "LOADFONT", cmd_loadfont}, - {3, 3, "LOADFONTEX", cmd_loadfontex}, + {4, 4, "LOADFONTEX", cmd_loadfontex}, {3, 3, "LOADFONTFROMIMAGE", cmd_loadfontfromimage}, - {5, 5, "LOADFONTFROMMEMORY", cmd_loadfontfrommemory}, + {6, 6, "LOADFONTFROMMEMORY", cmd_loadfontfrommemory}, {1, 1, "LOADIMAGE", cmd_loadimage}, {1, 1, "LOADIMAGEANIM", cmd_loadimageanim}, {3, 3, "LOADIMAGEANIMFROMMEMORY", cmd_loadimageanimfrommemory}, @@ -259,7 +267,9 @@ {3, 3, "TEXTINSERT", cmd_textinsert}, {2, 2, "TEXTISEQUAL", cmd_textisequal}, {1, 1, "TEXTLENGTH", cmd_textlength}, + {1, 1, "TEXTREMOVESPACES", cmd_textremovespaces}, {3, 3, "TEXTREPLACE", cmd_textreplace}, + {4, 4, "TEXTREPLACEBETWEEN", cmd_textreplacebetween}, {3, 3, "TEXTSUBTEXT", cmd_textsubtext}, {1, 1, "TEXTTOCAMEL", cmd_texttocamel}, {1, 1, "TEXTTOFLOAT", cmd_texttofloat}, diff --git a/raylib/func.h b/raylib/func.h index cc97d4a..53ccee6 100644 --- a/raylib/func.h +++ b/raylib/func.h @@ -2,8 +2,8 @@ // Change working directory, return true on success // static int cmd_changedirectory(int argc, slib_par_t *params, var_t *retval) { - auto dir = get_param_str(argc, params, 0, 0); - auto fnResult = ChangeDirectory(dir); + auto dirPath = get_param_str(argc, params, 0, 0); + auto fnResult = ChangeDirectory(dirPath); v_setint(retval, fnResult); return 1; } @@ -358,12 +358,23 @@ static int cmd_computesha1(int argc, slib_par_t *params, var_t *retval) { } // -// Decode Base64 string data, memory must be MemFree() +// Compute SHA256 hash code, returns static int[8] (32 bytes) +// +static int cmd_computesha256(int argc, slib_par_t *params, var_t *retval) { + auto data = (unsigned char *)get_param_str(argc, params, 0, 0); + auto dataSize = get_param_int(argc, params, 1, 0); + auto fnResult = (var_int_t)ComputeSHA256(data, dataSize); + v_setint(retval, fnResult); + return 1; +} + +// +// Decode Base64 string (expected NULL terminated), memory must be MemFree() // static int cmd_decodedatabase64(int argc, slib_par_t *params, var_t *retval) { - auto data = (const unsigned char *)get_param_str(argc, params, 0, 0); + auto text = get_param_str(argc, params, 0, 0); auto outputSize = 0; - auto fnResult = (const char *)DecodeDataBase64(data, &outputSize); + auto fnResult = (const char *)DecodeDataBase64(text, &outputSize); v_setstrn(retval, fnResult, outputSize); MemFree((void *)fnResult); return 1; @@ -393,7 +404,7 @@ static int cmd_directoryexists(int argc, slib_par_t *params, var_t *retval) { } // -// Encode data to Base64 string, memory must be MemFree() +// Encode data to Base64 string (includes NULL terminator), memory must be MemFree() // static int cmd_encodedatabase64(int argc, slib_par_t *params, var_t *retval) { auto data = (const unsigned char *)get_param_str(argc, params, 0, 0); @@ -583,6 +594,17 @@ static int cmd_fade(int argc, slib_par_t *params, var_t *retval) { return 1; } +// +// Copy file from one path to another, dstPath created if it doesn't exist +// +static int cmd_filecopy(int argc, slib_par_t *params, var_t *retval) { + auto srcPath = get_param_str(argc, params, 0, 0); + auto dstPath = get_param_str(argc, params, 1, 0); + auto fnResult = FileCopy(srcPath, dstPath); + v_setint(retval, fnResult); + return 1; +} + // // Check if file exists // @@ -593,6 +615,61 @@ static int cmd_fileexists(int argc, slib_par_t *params, var_t *retval) { return 1; } +// +// Move file from one directory to another, dstPath created if it doesn't exist +// +static int cmd_filemove(int argc, slib_par_t *params, var_t *retval) { + auto srcPath = get_param_str(argc, params, 0, 0); + auto dstPath = get_param_str(argc, params, 1, 0); + auto fnResult = FileMove(srcPath, dstPath); + v_setint(retval, fnResult); + return 1; +} + +// +// Remove file (if exists) +// +static int cmd_fileremove(int argc, slib_par_t *params, var_t *retval) { + auto fileName = get_param_str(argc, params, 0, 0); + auto fnResult = FileRemove(fileName); + v_setint(retval, fnResult); + return 1; +} + +// +// Rename file (if exists) +// +static int cmd_filerename(int argc, slib_par_t *params, var_t *retval) { + auto fileName = get_param_str(argc, params, 0, 0); + auto fileRename = get_param_str(argc, params, 1, 0); + auto fnResult = FileRename(fileName, fileRename); + v_setint(retval, fnResult); + return 1; +} + +// +// Find text in existing file +// +static int cmd_filetextfindindex(int argc, slib_par_t *params, var_t *retval) { + auto fileName = get_param_str(argc, params, 0, 0); + auto search = get_param_str(argc, params, 1, 0); + auto fnResult = FileTextFindIndex(fileName, search); + v_setint(retval, fnResult); + return 1; +} + +// +// Replace text in an existing file +// +static int cmd_filetextreplace(int argc, slib_par_t *params, var_t *retval) { + auto fileName = get_param_str(argc, params, 0, 0); + auto search = get_param_str(argc, params, 1, 0); + auto replacement = get_param_str(argc, params, 2, 0); + auto fnResult = FileTextReplace(fileName, search, replacement); + v_setint(retval, fnResult); + return 1; +} + // // Generate image: cellular algorithm, bigger tileSize means bigger cells // @@ -1073,7 +1150,7 @@ static int cmd_getframetime(int argc, slib_par_t *params, var_t *retval) { } // -// Get gamepad axis count for a gamepad +// Get axis count for a gamepad // static int cmd_getgamepadaxiscount(int argc, slib_par_t *params, var_t *retval) { auto gamepad = get_param_int(argc, params, 0, 0); @@ -1083,7 +1160,7 @@ static int cmd_getgamepadaxiscount(int argc, slib_par_t *params, var_t *retval) } // -// Get axis movement value for a gamepad axis +// Get movement value for a gamepad axis // static int cmd_getgamepadaxismovement(int argc, slib_par_t *params, var_t *retval) { auto gamepad = get_param_int(argc, params, 0, 0); @@ -1734,6 +1811,18 @@ static int cmd_getsplinepointlinear(int argc, slib_par_t *params, var_t *retval) return 1; } +// +// Get text between two strings +// +static int cmd_gettextbetween(int argc, slib_par_t *params, var_t *retval) { + auto text = get_param_str(argc, params, 0, 0); + auto begin = get_param_str(argc, params, 1, 0); + auto end = get_param_str(argc, params, 2, 0); + auto fnResult = (const char *)GetTextBetween(text, begin, end); + v_setstr(retval, fnResult); + return 1; +} + // // Get elapsed time in seconds since InitWindow() // @@ -2028,7 +2117,7 @@ static int cmd_isfiledropped(int argc, slib_par_t *params, var_t *retval) { } // -// Check file extension (including point: .png, .wav) +// Check file extension (recommended include point: .png, .wav) // static int cmd_isfileextension(int argc, slib_par_t *params, var_t *retval) { auto fileName = get_param_str(argc, params, 0, 0); @@ -2575,8 +2664,8 @@ static int cmd_loadfont(int argc, slib_par_t *params, var_t *retval) { static int cmd_loadfontex(int argc, slib_par_t *params, var_t *retval) { auto fileName = get_param_str(argc, params, 0, 0); auto fontSize = get_param_int(argc, params, 1, 0); - auto codepoints = (int *)0; - auto codepointCount = get_param_int(argc, params, 2, 0); + auto codepoints = (const int *)get_param_int_t(argc, params, 2, 0); + auto codepointCount = get_param_int(argc, params, 3, 0); auto fnResult = LoadFontEx(fileName, fontSize, codepoints, codepointCount); v_setfont(retval, fnResult); return 1; @@ -2608,8 +2697,8 @@ static int cmd_loadfontfrommemory(int argc, slib_par_t *params, var_t *retval) { auto fileData = (const unsigned char *)get_param_str(argc, params, 1, 0); auto dataSize = get_param_int(argc, params, 2, 0); auto fontSize = get_param_int(argc, params, 3, 0); - auto codepoints = (int *)0; - auto codepointCount = get_param_int(argc, params, 4, 0); + auto codepoints = (const int *)get_param_int_t(argc, params, 4, 0); + auto codepointCount = get_param_int(argc, params, 5, 0); auto fnResult = LoadFontFromMemory(fileType, fileData, dataSize, fontSize, codepoints, codepointCount); v_setfont(retval, fnResult); return 1; @@ -3017,7 +3106,7 @@ static int cmd_savefiledata(int argc, slib_par_t *params, var_t *retval) { // static int cmd_savefiletext(int argc, slib_par_t *params, var_t *retval) { auto fileName = get_param_str(argc, params, 0, 0); - auto text = (char *)get_param_str(argc, params, 1, 0); + auto text = get_param_str(argc, params, 1, 0); auto fnResult = SaveFileText(fileName, text); v_setint(retval, fnResult); return 1; @@ -3045,12 +3134,12 @@ static int cmd_textcopy(int argc, slib_par_t *params, var_t *retval) { } // -// Find first text occurrence within a string +// Find first text occurrence within a string, -1 if not found // static int cmd_textfindindex(int argc, slib_par_t *params, var_t *retval) { auto text = get_param_str(argc, params, 0, 0); - auto find = get_param_str(argc, params, 1, 0); - auto fnResult = TextFindIndex(text, find); + auto search = get_param_str(argc, params, 1, 0); + auto fnResult = TextFindIndex(text, search); v_setint(retval, fnResult); return 1; } @@ -3088,14 +3177,37 @@ static int cmd_textlength(int argc, slib_par_t *params, var_t *retval) { return 1; } +// +// Remove text spaces, concat words +// +static int cmd_textremovespaces(int argc, slib_par_t *params, var_t *retval) { + auto text = get_param_str(argc, params, 0, 0); + auto fnResult = (const char *)TextRemoveSpaces(text); + v_setstr(retval, fnResult); + return 1; +} + // // Replace text string (WARNING: memory must be freed!) // static int cmd_textreplace(int argc, slib_par_t *params, var_t *retval) { auto text = get_param_str(argc, params, 0, 0); - auto replace = get_param_str(argc, params, 1, 0); - auto by = get_param_str(argc, params, 2, 0); - auto fnResult = (const char *)TextReplace(text, replace, by); + auto search = get_param_str(argc, params, 1, 0); + auto replacement = get_param_str(argc, params, 2, 0); + auto fnResult = (const char *)TextReplace(text, search, replacement); + v_setstr(retval, fnResult); + return 1; +} + +// +// Replace text between two specific strings (WARNING: memory must be freed!) +// +static int cmd_textreplacebetween(int argc, slib_par_t *params, var_t *retval) { + auto text = get_param_str(argc, params, 0, 0); + auto begin = get_param_str(argc, params, 1, 0); + auto end = get_param_str(argc, params, 2, 0); + auto replacement = get_param_str(argc, params, 3, 0); + auto fnResult = (const char *)TextReplaceBetween(text, begin, end, replacement); v_setstr(retval, fnResult); return 1; } diff --git a/raylib/main.cpp b/raylib/main.cpp index 8bed447..06598c9 100644 --- a/raylib/main.cpp +++ b/raylib/main.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "robin-hood-hashing/src/include/robin_hood.h" #include "include/var.h" @@ -1937,7 +1938,7 @@ SBLIB_API int sblib_func_exec(int index, int argc, slib_par_t *params, var_t *re return result; } -SBLIB_API void sblib_free(int cls_id, int id) { +SBLIB_API int sblib_free(int cls_id, int id) { if (id != -1) { switch (cls_id) { case CLS_AUDIOSTREAM: @@ -2030,6 +2031,7 @@ SBLIB_API void sblib_free(int cls_id, int id) { break; } } + return 0; } SBLIB_API void sblib_close(void) { @@ -2094,3 +2096,8 @@ SBLIB_API void sblib_close(void) { _waveMap.clear(); } } + +SBLIB_API int sblib_has_window_ui(void) { + // module creates a UI in a new window + return 1; +} diff --git a/raylib/mkraylib.bas b/raylib/mkraylib.bas index ee64008..e37d4c5 100644 --- a/raylib/mkraylib.bas +++ b/raylib/mkraylib.bas @@ -2,7 +2,7 @@ rem rem generate a skelton main.cpp from json input rem -tload "raylib/parser/raylib_api.json", s, 1 +tload "raylib/tools/rlparser/output/raylib_api.json", s, 1 api = array(s) func comparator(l, r) diff --git a/raylib/mkreadme.bas b/raylib/mkreadme.bas index 56230b9..0f98b50 100644 --- a/raylib/mkreadme.bas +++ b/raylib/mkreadme.bas @@ -20,7 +20,7 @@ load("main.cpp") load("proc-def.h") load("func-def.h") -tload "raylib/parser/raylib_api.json", s, 1 +tload "raylib/tools/rlparser/output/raylib_api.json", s, 1 api = array(s) functions = {} for fun in api("functions") diff --git a/raylib/proc-def.h b/raylib/proc-def.h index f509533..e4456bf 100644 --- a/raylib/proc-def.h +++ b/raylib/proc-def.h @@ -35,11 +35,14 @@ {6, 6, "DRAWCYLINDERWIRESEX", cmd_drawcylinderwiresex}, {5, 5, "DRAWELLIPSE", cmd_drawellipse}, {5, 5, "DRAWELLIPSELINES", cmd_drawellipselines}, + {4, 4, "DRAWELLIPSELINESV", cmd_drawellipselinesv}, + {4, 4, "DRAWELLIPSEV", cmd_drawellipsev}, {2, 2, "DRAWFPS", cmd_drawfps}, {2, 2, "DRAWGRID", cmd_drawgrid}, {5, 5, "DRAWLINE", cmd_drawline}, {3, 3, "DRAWLINE3D", cmd_drawline3d}, {4, 4, "DRAWLINEBEZIER", cmd_drawlinebezier}, + {5, 5, "DRAWLINEDASHED", cmd_drawlinedashed}, {4, 4, "DRAWLINEEX", cmd_drawlineex}, {3, 3, "DRAWLINESTRIP", cmd_drawlinestrip}, {3, 3, "DRAWLINEV", cmd_drawlinev}, diff --git a/raylib/proc.h b/raylib/proc.h index ce6790c..f549c73 100644 --- a/raylib/proc.h +++ b/raylib/proc.h @@ -449,6 +449,30 @@ static int cmd_drawellipselines(int argc, slib_par_t *params, var_t *retval) { return 1; } +// +// Draw ellipse outline (Vector version) +// +static int cmd_drawellipselinesv(int argc, slib_par_t *params, var_t *retval) { + auto center = get_param_vec2(argc, params, 0); + auto radiusH = get_param_num(argc, params, 1, 0); + auto radiusV = get_param_num(argc, params, 2, 0); + auto color = get_param_color(argc, params, 3); + DrawEllipseLinesV(center, radiusH, radiusV, color); + return 1; +} + +// +// Draw ellipse (Vector version) +// +static int cmd_drawellipsev(int argc, slib_par_t *params, var_t *retval) { + auto center = get_param_vec2(argc, params, 0); + auto radiusH = get_param_num(argc, params, 1, 0); + auto radiusV = get_param_num(argc, params, 2, 0); + auto color = get_param_color(argc, params, 3); + DrawEllipseV(center, radiusH, radiusV, color); + return 1; +} + // // Draw current FPS // @@ -505,6 +529,19 @@ static int cmd_drawlinebezier(int argc, slib_par_t *params, var_t *retval) { return 1; } +// +// Draw a dashed line +// +static int cmd_drawlinedashed(int argc, slib_par_t *params, var_t *retval) { + auto startPos = get_param_vec2(argc, params, 0); + auto endPos = get_param_vec2(argc, params, 1); + auto dashSize = get_param_int(argc, params, 2, 0); + auto spaceSize = get_param_int(argc, params, 3, 0); + auto color = get_param_color(argc, params, 4); + DrawLineDashed(startPos, endPos, dashSize, spaceSize, color); + return 1; +} + // // Draw a line (using triangles/quads) // @@ -765,9 +802,9 @@ static int cmd_drawrectanglegradientex(int argc, slib_par_t *params, var_t *retv auto rec = get_param_rect(argc, params, 0); auto topLeft = get_param_color(argc, params, 1); auto bottomLeft = get_param_color(argc, params, 2); - auto topRight = get_param_color(argc, params, 3); - auto bottomRight = get_param_color(argc, params, 4); - DrawRectangleGradientEx(rec, topLeft, bottomLeft, topRight, bottomRight); + auto bottomRight = get_param_color(argc, params, 3); + auto topRight = get_param_color(argc, params, 4); + DrawRectangleGradientEx(rec, topLeft, bottomLeft, bottomRight, topRight); return 1; } @@ -2427,7 +2464,7 @@ static int cmd_pollinputevents(int argc, slib_par_t *params, var_t *retval) { } // -// Set window state: not minimized/maximized +// Restore window from being minimized/maximized // static int cmd_restorewindow(int argc, slib_par_t *params, var_t *retval) { RestoreWindow(); @@ -2684,7 +2721,7 @@ static int cmd_setmousescale(int argc, slib_par_t *params, var_t *retval) { } // -// Set pan for a music (0.5 is center) +// Set pan for a music (-1.0 left, 0.0 center, 1.0 right) // static int cmd_setmusicpan(int argc, slib_par_t *params, var_t *retval) { int result; @@ -2815,7 +2852,7 @@ static int cmd_setshapestexture(int argc, slib_par_t *params, var_t *retval) { } // -// Set pan for a sound (0.5 is center) +// Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) // static int cmd_setsoundpan(int argc, slib_par_t *params, var_t *retval) { int result; @@ -3123,7 +3160,7 @@ static int cmd_takescreenshot(int argc, slib_par_t *params, var_t *retval) { } // -// Append text at specific position and move cursor! +// Append text at specific position and move cursor // static int cmd_textappend(int argc, slib_par_t *params, var_t *retval) { auto text = (char *)get_param_str(argc, params, 0, 0); @@ -3543,7 +3580,7 @@ static int cmd_updatemusicstream(int argc, slib_par_t *params, var_t *retval) { } // -// Update sound buffer with new data +// Update sound buffer with new data (default data format: 32 bit float, stereo) // static int cmd_updatesound(int argc, slib_par_t *params, var_t *retval) { int result; @@ -3560,7 +3597,7 @@ static int cmd_updatesound(int argc, slib_par_t *params, var_t *retval) { } // -// Update GPU texture rectangle with new data +// Update GPU texture rectangle with new data (pixels and rec should fit in texture) // static int cmd_updatetexturerec(int argc, slib_par_t *params, var_t *retval) { int result; diff --git a/raylib/raylib b/raylib/raylib index eb8a343..c610d22 160000 --- a/raylib/raylib +++ b/raylib/raylib @@ -1 +1 @@ -Subproject commit eb8a343e313967a51cb302ac9bb1206a05727d13 +Subproject commit c610d228a244f930ad53492604640f39584c66da