diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07ed706 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/* \ No newline at end of file diff --git a/build/animate b/build/animate deleted file mode 100755 index cf9e88e..0000000 Binary files a/build/animate and /dev/null differ diff --git a/build/colors b/build/colors deleted file mode 100755 index 48d8379..0000000 Binary files a/build/colors and /dev/null differ diff --git a/build/printinput b/build/printinput deleted file mode 100755 index 0512145..0000000 Binary files a/build/printinput and /dev/null differ diff --git a/build/resize b/build/resize deleted file mode 100755 index 50d960c..0000000 Binary files a/build/resize and /dev/null differ diff --git a/build_menu.sh b/build_menu.sh new file mode 100755 index 0000000..093e8a4 --- /dev/null +++ b/build_menu.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +code="$PWD" +opts="-g -Wno-switch" + +mkdir -p build +cd build +echo menu +clang $opts $code/src/menu.main.c -lncurses -o menu diff --git a/project.4coder b/project.4coder index d46b769..76546a2 100644 --- a/project.4coder +++ b/project.4coder @@ -33,10 +33,15 @@ commands = { .build_resize = { .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .win = "build_resize.bat", .linux = "./build_resize.sh", .mac = "./build_resize.sh", }, + + .build_menu = { .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, + .win = "build_menu.bat", .linux = "./build_menu.sh", .mac = "./build_menu.sh", }, }; + fkey_command = { .F1 = "build_printinput", .F2 = "build_animate", .F3 = "build_colors", .F4 = "build_resize", +.F5 = "build_menu", }; diff --git a/src/animate.main.c b/src/animate.main.c index 4c4920d..a3fece7 100644 --- a/src/animate.main.c +++ b/src/animate.main.c @@ -12,6 +12,7 @@ int main(){ // settings noecho(); cbreak(); + curs_set(0); B32 animating = 1; diff --git a/src/colors.main.c b/src/colors.main.c index 6d19390..680071c 100644 --- a/src/colors.main.c +++ b/src/colors.main.c @@ -18,6 +18,7 @@ int main(){ // settings noecho(); cbreak(); + curs_set(0); B32 animating = 1; diff --git a/src/menu.main.c b/src/menu.main.c new file mode 100644 index 0000000..8e2e7d7 --- /dev/null +++ b/src/menu.main.c @@ -0,0 +1,168 @@ +#include "mr4th/mr4th_base.h" +#include + +#include "menu.main.h" + +#include "mr4th/mr4th_base.c" + +MR4TH_SYMBOL NCRS_Bfr +ncrs_bfr_alloc(Arena *arena, U32 w, U32 h){ + NCRS_Bfr result = { w, h }; + result.chr = push_array(arena, U8, w*h); + result.color = push_array(arena, U8, w*h); + return(result); +} + +MR4TH_SYMBOL void +ncrs_bfr_fill_rect(NCRS_Bfr *bfr, RectS32 rect, U8 chr, U8 color){ + S32 x0 = ClampBot(rect.x0, 0); + S32 x1 = ClampTop(rect.x1, bfr->w); + S32 y0 = ClampBot(rect.y0, 0); + S32 y1 = ClampTop(rect.y1, bfr->h); + + for (S32 iy = y0; iy < y1; iy += 1){ + S32 iyb = iy*bfr->w; + for (S32 ix = x0; ix < x1; ix += 1){ + bfr->chr[iyb + ix] = chr; + bfr->color[iyb + ix] = color; + } + } +} + +MR4TH_SYMBOL void +ncrs_bfr_outline_rect(NCRS_Bfr *bfr, RectS32 rect, U8 chr, U8 color){ + S32 x0 = ClampBot(rect.x0, 0); + S32 x1 = ClampTop(rect.x1, bfr->w); + S32 y0 = ClampBot(rect.y0, 0); + S32 y1 = ClampTop(rect.y1, bfr->h); + + // top + if (0 <= rect.y0 && rect.y0 < bfr->h){ + S32 iyb = rect.y0*bfr->w; + for (S32 ix = x0; ix < x1; ix += 1){ + bfr->chr[iyb + ix] = chr; + bfr->color[iyb + ix] = color; + } + } + + // bottom + if (0 < rect.y1 && rect.y1 <= bfr->h){ + S32 iyb = (rect.y1 - 1)*bfr->w; + for (S32 ix = x0; ix < x1; ix += 1){ + bfr->chr[iyb + ix] = chr; + bfr->color[iyb + ix] = color; + } + } + + // left + if (0 <= rect.x0 && rect.x0 < bfr->w){ + S32 ix = rect.x0; + for (S32 iy = y0; iy < y1; iy += 1){ + S32 iyb = iy*bfr->w; + bfr->chr[iyb + ix] = chr; + bfr->color[iyb + ix] = color; + } + } + + // right + if (0 < rect.x1 && rect.x1 <= bfr->w){ + S32 ix = rect.x1 - 1; + for (S32 iy = y0; iy < y1; iy += 1){ + S32 iyb = iy*bfr->w; + bfr->chr[iyb + ix] = chr; + bfr->color[iyb + ix] = color; + } + } + +} + +MR4TH_SYMBOL void +ncrs_bfr_write(NCRS_Bfr *bfr, S32 x, S32 y, S32 xmax, String8 str, U8 color){ + if (0 <= x && x < bfr->w && x < xmax && + 0 <= y && y < bfr->h){ + S32 iyb = y*bfr->w; + S32 x1 = ClampTop(x + str.size, xmax); + for (U32 xi = x, i = 0; xi < x1; xi += 1, i += 1){ + bfr->chr[iyb + xi] = str.str[i]; + bfr->color[iyb + xi] = color; + } + } +} + +MR4TH_SYMBOL void +ncrs_bfr_to_window(NCRS_Bfr *bfr, WINDOW *window){ + S32 w = 0; + S32 h = 0; + getmaxyx(window, h, w); + + S32 x1 = ClampTop(bfr->w, w); + S32 y1 = ClampTop(bfr->h, h); + + for (U32 iy = 0; iy < y1; iy += 1){ + S32 iyb = iy*bfr->w; + wmove(window, iy, 0); + for (U32 ix = 0; ix < x1; ix += 1){ + S16 color = (S16)bfr->color[iyb + ix]; + if (color != 0){ + attron(COLOR_PAIR(color)); + } + waddch(window, bfr->chr[iyb + ix]); + attroff(COLOR_PAIR(color)); + } + } + + wrefresh(window); +} + +int main(){ + ArenaTemp scratch = arena_get_scratch(0, 0); + + // initializes ncurses + initscr(); + + if (!has_colors()){ + goto no_color; + } + start_color(); + + noecho(); + cbreak(); + curs_set(0); + + // colors + { +#define X(F,B) init_pair(NCRS_ColorPair_##F##_##B, COLOR_##F, COLOR_##B); + NCRS_ColorPair_XList(X) +#undef X + } + + // virtual buffer + NCRS_Bfr bfr = ncrs_bfr_alloc(scratch.arena, 160, 40); + ncrs_bfr_fill_rect(&bfr, (RectS32){0, 0, 160, 40}, ' ', 0); + ncrs_bfr_outline_rect(&bfr, (RectS32){0, 0, 160, 40}, + '#', NCRS_ColorPair_WHITE_BLACK); + + ncrs_bfr_write(&bfr, 2, 2, 30, str8_lit("Continue"), NCRS_ColorPair_BLACK_WHITE); + ncrs_bfr_write(&bfr, 2, 4, 30, str8_lit("New Game (Abandon Current)"), NCRS_ColorPair_WHITE_BLACK); + ncrs_bfr_write(&bfr, 2, 6, 30, str8_lit("Custom Game Mode"), NCRS_ColorPair_WHITE_BLACK); + ncrs_bfr_write(&bfr, 2, 8, 30, str8_lit("Quite"), NCRS_ColorPair_WHITE_BLACK); + + // program + for (;;){ + // bfr -> screen + ncrs_bfr_to_window(&bfr, stdscr); + + int c = getch(); + } + + // end ncurses + endwin(); + + if (0){ no_color: + endwin(); + printf("no ncurses color support\n"); + } + + arena_release_scratch(&scratch); + return(0); +} diff --git a/src/menu.main.h b/src/menu.main.h new file mode 100644 index 0000000..63e64ce --- /dev/null +++ b/src/menu.main.h @@ -0,0 +1,53 @@ +#ifndef MENU_MAIN_H +#define MENU_MAIN_H + +/****************************************************************************** +* NCRS Types * +******************************************************************************/ + +#define NCRS_ColorPair_XList(X)\ +X(WHITE, BLACK) \ +X(RED, BLACK) \ +X(GREEN, BLACK) \ +X(BLUE, BLACK) \ +X(YELLOW, BLACK) \ +X(MAGENTA, BLACK) \ +X(CYAN, BLACK) \ +X(BLACK, WHITE) \ +X(BLACK, RED) \ +X(BLACK, GREEN) \ +X(BLACK, BLUE) \ +X(BLACK, YELLOW) \ +X(BLACK, MAGENTA) \ +X(BLACK, CYAN) + +typedef enum NCRS_ColorPair{ + NCRS_ColorPair_NULL = 0, + +#define X(F,B) NCRS_ColorPair_##F##_##B, + NCRS_ColorPair_XList(X) +#undef X + + NCRS_ColorPair_COUNT +} NCRS_ColorPair; + +typedef struct NCRS_Bfr{ + U32 w; + U32 h; + U8 *chr; + U8 *color; +} NCRS_Bfr; + +/****************************************************************************** +* NCRS Functions * +******************************************************************************/ + +MR4TH_SYMBOL NCRS_Bfr ncrs_bfr_alloc(Arena *arena, U32 w, U32 h); + +MR4TH_SYMBOL void ncrs_bfr_fill_rect(NCRS_Bfr *bfr, RectS32 rect, U8 chr, U8 color); +MR4TH_SYMBOL void ncrs_bfr_outline_rect(NCRS_Bfr *bfr, RectS32 rect, U8 chr, U8 color); +MR4TH_SYMBOL void ncrs_bfr_write(NCRS_Bfr *bfr, S32 x, S32 y, S32 xmax, String8 str, U8 color); + +MR4TH_SYMBOL void ncrs_bfr_to_window(NCRS_Bfr *bfr, WINDOW *w); + +#endif //MENU_MAIN_H diff --git a/src/printinput.main.c b/src/printinput.main.c index fbb1905..ae5e676 100644 --- a/src/printinput.main.c +++ b/src/printinput.main.c @@ -10,6 +10,7 @@ int main(){ // settings noecho(); cbreak(); + curs_set(0); // get size int window_x = 0; diff --git a/src/resize.main.c b/src/resize.main.c index 217a54d..67f2168 100644 --- a/src/resize.main.c +++ b/src/resize.main.c @@ -10,13 +10,13 @@ int main(){ // settings noecho(); cbreak(); + curs_set(0); // get size int window_x = 0; int window_y = 0; getmaxyx(stdscr, window_y, window_x); - { clear();