diff options
| -rw-r--r-- | README.md | 18 | ||||
| -rw-r--r-- | main.c | 104 | ||||
| -rw-r--r-- | tests/test.lua | 24 |
3 files changed, 116 insertions, 30 deletions
@@ -1,8 +1,9 @@ **Bidi** is a lightweight framework and fantasy console designed for creating tiny video games, perfect for learning and having fun. It takes heavy inspiration from [LÖVE](https://www.love2d.org/), -[Pico8](https://www.lexaloffle.com/pico-8.php) and [Atari -2600](https://en.wikipedia.org/wiki/Atari_2600). +[Pico8](https://www.lexaloffle.com/pico-8.php), [Atari +2600](https://en.wikipedia.org/wiki/Atari_2600) and [Windows +3.1](https://en.wikipedia.org/wiki/Windows_3.1). You develop your games in Lua and you are only allowed to have one Lua file where all your code lives. You can then load external assets like images and @@ -75,7 +76,8 @@ close_window() | `draw_circle` | `number center_x`, `number center_y`, `number radius`, `color color` | | | `draw_ellipse` | `number center_x`, `number center_y`, `number radius_h`, `number radius_v`, `color color` | | | `draw_triangle` | `number x1`, `number y1`, `number x2`, `number y2`, `number x3`, `number y3`, `color color` | | -| `load_image` | `TODO` | | +| `load_image` | `string filepath` | `string` | +| `draw_image` | `string uid`, `number x`, `number y` | | | `load_audio` | `TODO` | | | `button_down` | `button button` | `bool` | | `button_pressed` | `button button` | `bool` | @@ -138,6 +140,16 @@ close_window() - https://hardwaretester.com/gamepad - https://www.raylib.com/examples/core/loader.html?name=core_input_gamepad +## Interesting games + +- https://www.old-games.com/download/3873/aethra-s-chronicles +- https://www.old-games.com/download/10746/wintrek-1992 +- https://www.old-games.com/download/3887/bard-s-tale-1 +- https://www.old-games.com/download/3902/castle-of-the-winds +- https://www.old-games.com/download/3923/decker +- https://www.old-games.com/download/3920/darkspyre +- https://www.old-games.com/download/6089/exile-3-ruined-world + ## Development references - https://www.love2d.org/wiki/Main_Page @@ -3,6 +3,7 @@ #include <getopt.h> #include <stdlib.h> #include <time.h> +#include <string.h> #include "raylib.h" #include "lua.h" @@ -24,31 +25,43 @@ #define XBOX_ALIAS_2 "x-box" #define PS_ALIAS "playstation" -typedef struct { +typedef struct ExternalImage { char uid[UID_LENGTH + 1]; - const char* filepath; + Texture2D texture; + struct ExternalImage *next; } ExternalImage; typedef struct { -} ExternalAudio; + ExternalImage *head; + ExternalImage *tail; + int count; +} ImageList; typedef struct { Font font; int font_size; Camera2D camera; - ExternalImage *images; - ExternalAudio *audio; + ImageList images; } Context; // Setting up global context. Context ctx = {0}; -static void generate_uid(char *uid) { - const char *chars = "0123456789abcdef"; - for (size_t i = 0; i < UID_LENGTH; i++) { - uid[i] = chars[rand() % 16]; +static void generate_uid(char *str, size_t length) { + static const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + size_t charset_size = sizeof(charset) - 1; // exclude null terminator + + for (size_t i = 0; i < length; i++) { + int key = rand() % charset_size; + str[i] = charset[key]; } - uid[UID_LENGTH + 1] = '\0'; + str[length] = '\0'; +} + +void init_image_list(ImageList *list) { + list->head = NULL; + list->tail = NULL; + list->count = 0; } static int lua_getfield_int(lua_State *L, int index, const char *key) { @@ -67,7 +80,7 @@ static int lua_getfield_int_opt(lua_State *L, int index, const char *key, int de static int load_embedded_module(lua_State *L, const char *module_code, size_t code_len, const char *module_name) { if (luaL_loadbuffer(L, module_code, code_len, module_name) || lua_pcall(L, 0, 1, 0)) { - fprintf(stderr, "Error loading %s: %s\n", module_name, lua_tostring(L, -1)); + TraceLog(LOG_FATAL, "Error loading %s: %s\n", module_name, lua_tostring(L, -1)); return 0; } lua_setglobal(L, module_name); @@ -380,13 +393,64 @@ static int l_button_pressed(lua_State *L) { } static int l_load_image(lua_State *L) { - return 0; + const char *filepath = luaL_checkstring(L, 1); + + ExternalImage *img = malloc(sizeof(ExternalImage)); + if (!img) { + TraceLog(LOG_FATAL, "Out of memory!"); + return 0; + } + + Image image = LoadImage(filepath); + if (!image.data) { + TraceLog(LOG_FATAL, "Failed to load image: %s\n", filepath); + free(img); + return 0; + } + + img->texture = LoadTextureFromImage(image); + UnloadImage(image); + + generate_uid(img->uid, UID_LENGTH); + img->next = NULL; + + if (ctx.images.tail) { + ctx.images.tail->next = img; + ctx.images.tail = img; + } else { + ctx.images.head = img; + ctx.images.tail = img; + } + ctx.images.count++; + + TraceLog(LOG_WARNING, "[adding]\t %s (%d)", img->uid, strlen(img->uid)); + + lua_pushstring(L, img->uid); + return 1; } static int l_load_audio(lua_State *L) { return 0; } +static int l_draw_image(lua_State *L) { + const char *uid = luaL_checkstring(L, 1); + int x = luaL_checknumber(L, 2); + int y = luaL_checknumber(L, 3); + + ExternalImage *current = ctx.images.head; + while (current) { + if (strncmp(current->uid, uid, UID_LENGTH) == 0) { + /* TraceLog(LOG_WARNING, "[match]\t %s (%d)", uid, strlen(uid)); */ + DrawTexture(current->texture, x, y, WHITE); + break; + } + current = current->next; + } + + return 0; +} + static void help(const char *argv0) { printf("Usage: %s [options]\n" "\nAvailable options:\n" @@ -404,6 +468,7 @@ static void version(const char *argv0) { int main(int argc, char *argv[]) { srand(time(NULL)); + init_image_list(&ctx.images); TraceLogLevel debug_level = LOG_WARNING; const char *run_file = NULL; @@ -472,6 +537,12 @@ int main(int argc, char *argv[]) { lua_register(L, "get_width", l_get_width); lua_register(L, "get_height", l_get_height); + lua_register(L, "load_image", l_load_image); + lua_register(L, "load_audio", l_load_audio); + + lua_register(L, "button_down", l_button_down); + lua_register(L, "button_pressed", l_button_pressed); + lua_register(L, "draw_info", l_draw_info); lua_register(L, "draw_rect", l_draw_rect); lua_register(L, "draw_text", l_draw_text); @@ -480,16 +551,11 @@ int main(int argc, char *argv[]) { lua_register(L, "draw_circle", l_draw_circle); lua_register(L, "draw_ellipse", l_draw_ellipse); lua_register(L, "draw_triangle", l_draw_triangle); - - lua_register(L, "load_image", l_load_image); - lua_register(L, "load_audio", l_load_audio); - - lua_register(L, "button_down", l_button_down); - lua_register(L, "button_pressed", l_button_pressed); + lua_register(L, "draw_image", l_draw_image); // Interpreting and running input file Lua script. if (luaL_loadfile(L, run_file) || lua_pcall(L, 0, 0, 0)) { - fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); + TraceLog(LOG_FATAL, "Error: %s\n", lua_tostring(L, -1)); return 1; } diff --git a/tests/test.lua b/tests/test.lua index f85b644..372b221 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -1,16 +1,15 @@ math.randomseed(os.time()) +open_window(800, 800, "Sample Window") +set_fps(60) + test_button_square = { x = 400, y = 400 } test_button_color = color.RED test_button_speed = 200 - test_camera_position = { x = 0, y = 0 } test_camera_speed = 200 - test_images_asset1 = load_image("tests/icons/icon_1.png") - -open_window(800, 800, "Sample Window") -set_fps(60) +test_images_asset2 = load_image("tests/icons/icon_2.png") function test_api() draw_rect(100, 100, 300, 200, color.YELLOW) @@ -26,10 +25,10 @@ end function get_random_color() local keys = {} for k in pairs(color) do - table.insert(keys, k) -- Collect all keys + table.insert(keys, k) end - local randomKey = keys[math.random(1, #keys)] -- Select a random key - return color[randomKey] -- Return the corresponding color + local randomKey = keys[math.random(1, #keys)] + return color[randomKey] end function test_json() @@ -140,6 +139,14 @@ function test_camera() draw_text("This text doesn't move!", 10, 10, 20, color.VIOLET) end +function test_images() + draw_text(string.format("uid: %s", test_images_asset1), 50, 50, 20, color.VIOLET) + draw_text(string.format("uid: %s", test_images_asset2), 50, 80, 20, color.VIOLET) + + draw_image(test_images_asset1, 150, 150) + draw_image(test_images_asset2, 200, 200) +end + while window_running() do start_drawing() clear_window(color.BLACK) @@ -148,6 +155,7 @@ while window_running() do -- test_api() -- test_buttons() -- test_camera() + -- test_images() draw_info() stop_drawing() |
