// TODO
// remove #ifdef _WIN32 - use #if __target_os__ ==
// replace writeToSelf to __...write__
// about
// licenze:
// This code and its derivatives can be used under the following conditions:
// - Do not attack other countries.
// - Jerk off on public at least 1 time per day.
// - Observe hygiene.
// - check my other projects https://chiselapp.com/user/sergey6661313
// about:
// ScalpiEditor - ansi-only text editor for terminals.
// killer features: no. its just editor.
// Compile:
// this file is just part of zig version (for now)
// current version used zig compiller for compile zig file. (unstructions inside zig file)
// in future you can use tcc for compile
// tcc se_windows.c
// to support me
// with boosty:
// https://boosty.to/cutloosedev
// with monero:
// 87T7 qGbA TrM3 a6Br
// DyeC jQQf NWtU u3iZ
// bHVB MC6W mEbN NE13
// Qrrt KhBb e4vF 58NR
// 8PTF dYk2 Sozc HexX
// 4Q69 jbdQ Asrs P7B
// enums and constants
// compilation target
// os
#define __TargetOs_windows__ 1
#define __TargetOs_linux__ 2
// memory type
#define __TargetMemoryType_endiansLittle__ 1
#define __TargetMemoryType_endiansBig__ 2
// time
#define Scalpi_time_ms_per_s 1000
// Scalpi_Logger_writers
#define Scalpi_Logger_writers_c_out_writer 0
#define Scalpi_Logger_writers_file_writer 1
#define Scalpi_Logger_writers_console_writer 2
#define Scalpi_Logger_writers_terminal_writer 3
// settings
#define __target_os__ __TargetOs_windows__
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
#else
#error "please define __target_os__ with __TargetOs_"
#endif
#ifdef _WIN32
#define __target_os__ __TargetOs_windows__
#elif defined(__linux__)
#define __target_os__ __TargetOs_linux__
#endif
#define __target_memory_type__ __TargetMemoryType_endiansLittle__
#define __Scalpi_Terminal_Input_size__ 32
// App
#define App_expected_fps 30
// imports
// libC
#include "stdarg.h"
#include "stdbool.h"
#include "stddef.h"
#include "stdint.h"
#include "stdio.h"
#include "stdlib.h"
#include "assert.h"
#include "ctype.h"
#include "errno.h"
#include "fenv.h"
#include "float.h"
#include "inttypes.h"
#include "iso646.h"
#include "limits.h"
#include "locale.h"
#include "math.h"
#include "setjmp.h"
#include "signal.h"
#include "string.h"
#include "tgmath.h"
#include "time.h"
#include "uchar.h"
#include "wchar.h"
#include "wctype.h"
#if __target_os__ == __TargetOs_windows__
// posix
#include "fcntl.h"
// Windows
#include "windef.h"
#include "windows.h"
#include "winuser.h"
#include "commctrl.h"
#include "io.h"
#include "conio.h"
// network
// #include "ws2tcpip.h"
// #include "winsock2.h"
#elif __target_os__ == __TargetOs_linux__
#include "sys/ioctl.h"
#include "termios.h"
#include "unistd.h"
// network
// #include "arpa/inet.h"
// #include "netinet/in.h"
// #include "netinet/ip.h"
// #include "sys/socket.h"
#else
#error "please define __target_os__ with __TargetOs_"
#endif
// strings
// Scalpi_Console_ansi
#define Scalpi_Console_ansi_esc "\x1B"
#define __ScalpiConsoleAnsi_control__ Scalpi_Console_ansi_esc "["
#define Scalpi_Console_ansi_output_clear_to_end_line __ScalpiConsoleAnsi_control__ "0K"
#define Scalpi_Console_ansi_output_clear_to_start_line __ScalpiConsoleAnsi_control__ "1K"
#define Scalpi_Console_ansi_output_clear_line __ScalpiConsoleAnsi_control__ "2K"
// cursor
#define Scalpi_Console_ansi_output_cursor_hide __ScalpiConsoleAnsi_control__ "?25l"
#define Scalpi_Console_ansi_output_cursor_show __ScalpiConsoleAnsi_control__ "?25h"
#define __ScalpiConsoleAnsiOutputCursorStyle_reset__ __ScalpiConsoleAnsi_control__ "0 q"
#define Scalpi_Console_ansi_output_cursor_style_blinking_block __ScalpiConsoleAnsi_control__ "1 q"
#define Scalpi_Console_ansi_output_cursor_style_steady_block __ScalpiConsoleAnsi_control__ "2 q"
#define Scalpi_Console_ansi_output_cursor_style_blinking_underline __ScalpiConsoleAnsi_control__ "3 q"
#define Scalpi_Console_ansi_output_cursor_style_steady_underline __ScalpiConsoleAnsi_control__ "4 q"
#define Scalpi_Console_ansi_output_cursor_style_blinking_I_beam __ScalpiConsoleAnsi_control__ "5 q"
#define Scalpi_Console_ansi_output_cursor_style_steady_I_beam __ScalpiConsoleAnsi_control__ "6 q"
// color
#define Scalpi_Console_ansi_output_FontStyle_color_zero "39"
#define Scalpi_Console_ansi_output_FontStyle_color_black "30"
#define Scalpi_Console_ansi_output_FontStyle_color_red "31"
#define Scalpi_Console_ansi_output_FontStyle_color_green "32"
#define Scalpi_Console_ansi_output_FontStyle_color_gold "33"
#define Scalpi_Console_ansi_output_FontStyle_color_blue "34"
#define Scalpi_Console_ansi_output_FontStyle_color_magenta "35"
#define Scalpi_Console_ansi_output_FontStyle_color_cyan "36"
#define Scalpi_Console_ansi_output_FontStyle_color_light_gray "37"
#define Scalpi_Console_ansi_output_FontStyle_color_gray "90"
#define Scalpi_Console_ansi_output_FontStyle_color_pink "91"
#define Scalpi_Console_ansi_output_FontStyle_color_light_green "92"
#define Scalpi_Console_ansi_output_FontStyle_color_yellow "93"
#define Scalpi_Console_ansi_output_FontStyle_color_light_blue "94"
#define Scalpi_Console_ansi_output_FontStyle_color_light_magenta "95"
#define Scalpi_Console_ansi_output_FontStyle_color_light_cyan "96"
#define Scalpi_Console_ansi_output_FontStyle_color_white "97"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_zero "49"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_black "40"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_red "41"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_green "42"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_gold "43"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_blue "44"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_magenta "45"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_cyan "46"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_gray "47"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_gray "100"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_pink "101"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_green "102"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_yellow "103"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_blue "104"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_magenta "105"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_light_cyan "106"
#define Scalpi_Console_ansi_output_FontStyle_bg_color_white "107"
#define Scalpi_Console_ansi_output_FontStyle_sep ";"
#define Scalpi_Console_ansi_output_FontStyle_end "m"
#define Scalpi_Console_ansi_output_FontStyle_reset "0"
#define Scalpi_Console_ansi_output_FontStyle_bold "1"
#define Scalpi_Console_ansi_output_FontStyle_dim "2"
#define Scalpi_Console_ansi_output_FontStyle_italic "3"
#define Scalpi_Console_ansi_output_FontStyle_underline "4"
#define Scalpi_Console_ansi_output_FontStyle_conceal "8"
#define Scalpi_Console_ansi_output_FontStyle_fraktur "20"
#define Scalpi_Console_ansi_output_FontStyle_unbold "21;24"
#define Scalpi_Console_ansi_output_FontStyle_set_color "38"
#define Scalpi_Console_ansi_output_FontStyle_set_bg_color "48"
#define Scalpi_Console_ansi_output_FontStyle_start __ScalpiConsoleAnsi_control__
#define Scalpi_Console_ansi_output_FontStyle_RESET Scalpi_Console_ansi_output_FontStyle_start Scalpi_Console_ansi_output_FontStyle_reset Scalpi_Console_ansi_output_FontStyle_end
// mouse
#define Scalpi_ansi_input_mouse_release __ScalpiConsoleAnsi_control__ "?1000l"
#define Scalpi_ansi_input_mouse_grab __ScalpiConsoleAnsi_control__ "?1000h"
#define __ScalpiConsoleAnsiOutputSettings_enableLineWrap__ __ScalpiConsoleAnsi_control__ "?7h"
#define __ScalpiConsoleAnsiOutputSettings_disableLineWrap__ __ScalpiConsoleAnsi_control__ "?7l"
// const Scalpi_Console_ansi_input_Key
// ascii
#define __Scalpi_Console_ansi_input_Key_ascii_ctrl__ (-'a' + 1) /* do not use externally */
#define __Scalpi_Console_ansi_input_Key_ctrl_bs__ 8 /* also ctrl_h */
#define __Scalpi_Console_ansi_input_Key_tab__ 9 /* also ctrl_i */
#define __Scalpi_Console_ansi_input_Key_enter__ 13 /* also ctrl_m */
#define __Scalpi_Console_ansi_input_Key_escape__ 27
#define __Scalpi_Console_ansi_input_Key_back_space__ 127 /* sometime delete */
#define __Scalpi_Console_ansi_input_Key_ctrl_a__ ('a' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 1 start_of_heading */
#define __Scalpi_Console_ansi_input_Key_ctrl_b__ ('b' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 2 */
#define __Scalpi_Console_ansi_input_Key_ctrl_c__ ('c' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 3 */
#define __Scalpi_Console_ansi_input_Key_ctrl_d__ ('d' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 4 */
#define __Scalpi_Console_ansi_input_Key_ctrl_e__ ('e' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 5 */
#define __Scalpi_Console_ansi_input_Key_ctrl_f__ ('f' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 6 */
#define __Scalpi_Console_ansi_input_Key_ctrl_g__ ('g' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 7 */
#define __Scalpi_Console_ansi_input_Key_ctrl_h__ ('h' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 8 also */ ctrl_bs */
#define __Scalpi_Console_ansi_input_Key_ctrl_i__ ('i' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 9 also */ tab */
#define __Scalpi_Console_ansi_input_Key_ctrl_j__ ('j' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 10 */
#define __Scalpi_Console_ansi_input_Key_ctrl_k__ ('k' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 11 vertical_tab */ */
#define __Scalpi_Console_ansi_input_Key_ctrl_l__ ('l' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 12 formFeed */ */
#define __Scalpi_Console_ansi_input_Key_ctrl_m__ ('m' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 13 also */ enter */
#define __Scalpi_Console_ansi_input_Key_ctrl_n__ ('n' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 14 */
#define __Scalpi_Console_ansi_input_Key_ctrl_o__ ('o' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 15 */
#define __Scalpi_Console_ansi_input_Key_ctrl_p__ ('p' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 16 */
#define __Scalpi_Console_ansi_input_Key_ctrl_q__ ('q' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 17 */
#define __Scalpi_Console_ansi_input_Key_ctrl_r__ ('r' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 18 */
#define __Scalpi_Console_ansi_input_Key_ctrl_s__ ('s' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 19 */
#define __Scalpi_Console_ansi_input_Key_ctrl_t__ ('t' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 20 */
#define __Scalpi_Console_ansi_input_Key_ctrl_u__ ('u' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 21 */
#define __Scalpi_Console_ansi_input_Key_ctrl_v__ ('v' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 22 */
#define __Scalpi_Console_ansi_input_Key_ctrl_w__ ('w' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 23 */
#define __Scalpi_Console_ansi_input_Key_ctrl_x__ ('x' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 24 */
#define __Scalpi_Console_ansi_input_Key_ctrl_y__ ('y' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 25 */
#define __Scalpi_Console_ansi_input_Key_ctrl_z__ ('z' + __Scalpi_Console_ansi_input_Key_ascii_ctrl__) /* 26 */
// __Scalpi_Console_ansi_input_Key_non_ascii__
#define __Scalpi_Console_ansi_input_Key_special__ (1 << 8)
#define __Scalpi_Console_ansi_input_Key_functional__ (1 << 9)
#define __Scalpi_Console_ansi_input_Key_ctrl__ (1 << 10)
#define __Scalpi_Console_ansi_input_Key_alt__ (1 << 11)
#define __Scalpi_Console_ansi_input_Key_shift__ (1 << 12)
#define __Scalpi_Console_ansi_input_Key_mouse__ (1 << 13)
// FN
#define __Scalpi_Console_ansi_input_Key_f1__ (1 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f2__ (2 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f3__ (3 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f4__ (4 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f5__ (5 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f6__ (6 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f7__ (7 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f8__ (8 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f9__ (9 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f10__ (10 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f11__ (11 + __Scalpi_Console_ansi_input_Key_functional__)
#define __Scalpi_Console_ansi_input_Key_f12__ (12 + __Scalpi_Console_ansi_input_Key_functional__)
// arrows
// left
#define __Scalpi_Console_ansi_input_Key_left__ (1 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_ctrl_left__ (__Scalpi_Console_ansi_input_Key_left__ + __Scalpi_Console_ansi_input_Key_ctrl__)
#define __Scalpi_Console_ansi_input_Key_alt_left__ (__Scalpi_Console_ansi_input_Key_left__ + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_shift_left__ (__Scalpi_Console_ansi_input_Key_left__ + __Scalpi_Console_ansi_input_Key_shift__)
#define __Scalpi_Console_ansi_input_Key_ctrl_shift_left__ (__Scalpi_Console_ansi_input_Key_left__ + __Scalpi_Console_ansi_input_Key_ctrl__ + __Scalpi_Console_ansi_input_Key_shift__)
// right
#define __Scalpi_Console_ansi_input_Key_right__ (2 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_ctrl_right__ (__Scalpi_Console_ansi_input_Key_right__ + __Scalpi_Console_ansi_input_Key_ctrl__)
#define __Scalpi_Console_ansi_input_Key_alt_right__ (__Scalpi_Console_ansi_input_Key_right__ + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_shift_right__ (__Scalpi_Console_ansi_input_Key_right__ + __Scalpi_Console_ansi_input_Key_shift__)
#define __Scalpi_Console_ansi_input_Key_ctrl_shift_right__ (__Scalpi_Console_ansi_input_Key_right__ + __Scalpi_Console_ansi_input_Key_ctrl__ + __Scalpi_Console_ansi_input_Key_shift__)
// up
#define __Scalpi_Console_ansi_input_Key_up__ (3 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_ctrl_up__ (__Scalpi_Console_ansi_input_Key_up__ + __Scalpi_Console_ansi_input_Key_ctrl__)
#define __Scalpi_Console_ansi_input_Key_alt_up__ (__Scalpi_Console_ansi_input_Key_up__ + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_shift_up__ (__Scalpi_Console_ansi_input_Key_up__ + __Scalpi_Console_ansi_input_Key_shift__)
// down
#define __Scalpi_Console_ansi_input_Key_down__ (4 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_ctrl_down__ (__Scalpi_Console_ansi_input_Key_down__ + __Scalpi_Console_ansi_input_Key_ctrl__)
#define __Scalpi_Console_ansi_input_Key_alt_down__ (__Scalpi_Console_ansi_input_Key_down__ + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_shift_down__ (__Scalpi_Console_ansi_input_Key_down__ + __Scalpi_Console_ansi_input_Key_shift__)
// spec keys
#define __Scalpi_Console_ansi_input_Key_delete__ (5 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_shift_delete__ (__Scalpi_Console_ansi_input_Key_delete__ + __Scalpi_Console_ansi_input_Key_shift__)
#define __Scalpi_Console_ansi_input_Key_page_up__ (6 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_page_down__ (7 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_end__ (8 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_home__ (9 + __Scalpi_Console_ansi_input_Key_special__)
#define __Scalpi_Console_ansi_input_Key_ctrl_enter__ (__Scalpi_Console_ansi_input_Key_enter__ + __Scalpi_Console_ansi_input_Key_special__ + __Scalpi_Console_ansi_input_Key_ctrl__)
#define __Scalpi_Console_ansi_input_Key_ctrl_triangular_open_quotation_mark__ ('<' + __Scalpi_Console_ansi_input_Key_special__ + __Scalpi_Console_ansi_input_Key_ctrl__)
#define __Scalpi_Console_ansi_input_Key_ctrl_triangular_close_quotation_mark__ ('>' + __Scalpi_Console_ansi_input_Key_special__ + __Scalpi_Console_ansi_input_Key_ctrl__)
#define __Scalpi_Console_ansi_input_Key_ctrl_alt_v__ ('v' + __Scalpi_Console_ansi_input_Key_alt__ + __Scalpi_Console_ansi_input_Key_ctrl__)
// altX
#define __Scalpi_Console_ansi_input_Key_alt_a__ ('a' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_b__ ('b' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_c__ ('c' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_d__ ('d' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_e__ ('e' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_f__ ('f' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_g__ ('g' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_h__ ('h' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_i__ ('i' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_j__ ('j' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_k__ ('k' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_l__ ('l' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_m__ ('m' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_n__ ('n' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_o__ ('o' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_p__ ('p' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_q__ ('q' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_r__ ('r' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_s__ ('s' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_t__ ('t' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_u__ ('u' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_v__ ('v' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_w__ ('w' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_x__ ('x' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_y__ ('y' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_z__ ('z' + __Scalpi_Console_ansi_input_Key_alt__)
// alt_shiftX,
#define __Scalpi_Console_ansi_input_Key_alt_M__ ('M' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_N__ ('N' + __Scalpi_Console_ansi_input_Key_alt__)
// altN
#define __Scalpi_Console_ansi_input_Key_alt_0__ ('0' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_1__ ('1' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_2__ ('2' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_3__ ('3' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_4__ ('4' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_5__ ('5' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_6__ ('6' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_7__ ('7' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_8__ ('8' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_9__ ('9' + __Scalpi_Console_ansi_input_Key_alt__)
// alt_spec
#define __Scalpi_Console_ansi_input_Key_alt_comma__ (',' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_dot__ ('.' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_open_bracket__ ('[' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_close_bracket__ (']' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_semicolon__ (';' + __Scalpi_Console_ansi_input_Key_alt__)
#define __Scalpi_Console_ansi_input_Key_alt_apostrophe__ ('`' + __Scalpi_Console_ansi_input_Key_alt__)
// __OsFilePath_separator__
#if __target_os__ == __TargetOs_windows__
#define __OsFilePath_separator__ "\\"
#elif __target_os__ == __TargetOs_linux__
#define __OsFilePath_separator__ "/"
#else
#error "please define __target_os__ with __TargetOs_"
#endif
// basic types
typedef uint8_t* __AlignedPtr__;
typedef uint64_t __ScalpiConsoleAnsiInputKey__;
typedef size_t (*__WriteFnPtr__) (void* context, const char* bytes, size_t bytes_len);
typedef void (*__WriteFnPtrVoid__) (void* context, const char* bytes, size_t bytes_len);
// OS
// Os_Console_Input_Handle
#if __target_os__ == __TargetOs_windows__
typedef void* Os_Console_Input_Handle;
#elif __target_os__ == __TargetOs_linux__
typedef FILE* Os_Console_Input_Handle;
#else
#error "please define __target_os__ with __TargetOs_"
#endif
// Os_Console_Output_Handle
#if __target_os__ == __TargetOs_windows__
typedef void* Os_Console_Output_Handle;
#elif __target_os__ == __TargetOs_linux__
typedef FILE* Os_Console_Output_Handle;
#else
#error "please define __target_os__ with __TargetOs_"
#endif
// macroses
// c
#define or ||
#define and &&
#define OFFSETOF(type, field) ((size_t) &(((type *)0)->field))
#define FIELD_PARENT_PTR(type, field, instance) ((type *)((char *)(instance) - OFFSETOF(type, field)))
#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
#define TEXT_LEN(str) (ARRAY_LEN(str) - 1)
#define __FN__
// text
#define SLICE_TEXT(text) {.ptr=text, .len=TEXT_LEN(text)}
#define TEXT_PTR(text) (char(*)[TEXT_LEN(text)]) text
#define DEF_TEXT_PTR(name, text) char(*name)[TEXT_LEN(text)] = TEXT_PTR(text)
#define DEF_SLICE_TEXT(name, text) struct Slice name = SLICE_TEXT(text)
// App
#define App_delay_to_start_frame_target (Scalpi_time_ms_per_s / App_expected_fps)
// structs
// core
// memory
struct Slice {
char* ptr;
size_t len;
};
struct Finder {
struct Slice text;
struct Slice desired;
size_t pos;
};
// Os
// OsConsole
struct __OsConsoleFlags__ {
bool inited;
#if __target_os__ == __TargetOs_windows__
DWORD input_mode;
DWORD output_mode;
#elif __target_os__ == __TargetOs_linux__
struct termios termios;
#else
#error "please define __target_os__ with __TargetOs_"
#endif
};
struct Os_Console_Input {
Os_Console_Input_Handle handle;
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
int fileno;
#else
#error "please define __target_os__ with __TargetOs_"
#endif
};
struct Os_Console_Output {
Os_Console_Output_Handle handle;
#if __target_os__ == __TargetOs_windows__
#elif __target_os__ == __TargetOs_linux__
int fileno;
#else
#error "please define __target_os__ with __TargetOs_"
#endif
};
struct __OsHelper__ {
bool network_inited;
#if __target_os__ == __TargetOs_windows__
HINSTANCE instance;
void* console_input_handle;
void* console_output_handle;
WSADATA wsdata;
#elif __target_os__ == __TargetOs_linux__
FILE* console_input_handle;
FILE* console_output_handle;
#else
#error "please define __target_os__ with __TargetOs_"
#endif
};
// Scalpi
// math
struct __Scalpi_math_d2_U_Pos__ {
size_t x;
size_t y;
};
// text
struct Scalpi_Text_Splitter {
struct Finder finder;
bool stop;
size_t last_pos;
};
struct __Scalpi_Writer__ {
void* context;
__WriteFnPtr__ write;
};
struct Scalpi_Logger {
// write to terminal, console, file or to all together, but no real check "bytes is writen"
struct __Scalpi_Writer__ writers[4] // Scalpi_Logger_writers
};
// Console
// __Scalpi_Console_ansi_input_Key_SequenceParser__
struct __Scalpi_Console_ansi_input_Key_SequenceParser__ {
__ScalpiConsoleAnsiInputKey__ sequence;
size_t used;
};
struct Scalpi_Console_ansi_input_Key_SequenceParser_fromBytes_SequenceInfo {
const char* text;
size_t len;
__ScalpiConsoleAnsiInputKey__ key;
};
struct __Scalpi_Console__ {
struct Os_Console_Input input;
struct Os_Console_Output output;
};
// Terminal
struct __Scalpi_Terminal_Output_Cursor__ {
struct __Scalpi_math_d2_U_Pos__ pos;
};
struct __Scalpi_Terminal_Output__ {
struct __Scalpi_Terminal_Output_Cursor__ cursor;
const char* font_style;
struct __Scalpi_math_d2_U_Pos__ size;
bool convert_n_to_rn;
bool apply_r;
bool apply_n;
};
struct __Scalpi_Terminal_Input__ {
// usage:
// call __Scalpi_Terminal_Input_update_buffer__ for update unreaded
// use __Scalpi_Terminal_Input_grab__ in loop for get keys
size_t ungrabed;
char buffer[__Scalpi_Terminal_Input_size__];
};
struct __Scalpi_Terminal__ {
struct __Scalpi_Console__* console;
struct __OsConsoleFlags__ system_flags;
struct __Scalpi_Terminal_Input__ input;
struct __Scalpi_Terminal_Output__ output;
};
// App
struct App_Os_Helper {
#ifdef _WIN32
// WinApi
HINSTANCE instance;
void* console_input_handle;
void* console_output_handle;
WSADATA wsdata;
#endif
};
struct App {
struct App_Os_Helper os_helper;
struct Scalpi_Logger logger;
uint64_t tick;
};
// function prototypes
size_t __OsFallbackConsole_write__(void* unused_ctx, char* data, size_t len);
// globals
struct App global_app;
// functions
// core
// mem
// bits operations
uint8_t bits_rotl8(uint8_t value, unsigned int shift) {
shift %= 8;
return (value << shift) | (value >> (8 - shift));
}
uint16_t bits_rotl16(uint16_t value, unsigned int shift) {
shift %= 16;
return (value << shift) | (value >> (16 - shift));
}
uint32_t bits_rotl32(uint32_t value, unsigned int shift) {
shift %= 32;
return (value << shift) | (value >> (32 - shift));
}
uint64_t bits_rotl64(uint64_t value, unsigned int shift) {
shift %= 64;
return (value << shift) | (value >> (64 - shift));
}
// bytes operations
size_t Scalpi_mem_fill(char* dest, char symbol, size_t len) {
for (size_t pos = 0; pos < len; pos++) {
dest[pos] = symbol;
}
}
void __ScalpiMem_copy__(char* dest, const char* src, size_t size) {
// i use this instead memcpy becouse clang-in-zig just replace memcpy to crash-zig-bloated-version code
size_t pos;
for(pos = 0; pos < size; pos++) {
dest[pos] = src[pos];
}
}
bool Scalpi_mem_isEql(const char a[], const char b[], size_t len) {
for(size_t pos = 0; pos < len; pos ++) {
char ac = a[pos];
char bc = b[pos];
if (ac != bc) return false;
}
return true;
}
void writeWithOffset(char* dest, size_t* writed, char* data, size_t data_len) {
__ScalpiMem_copy__(&dest[*writed], data, data_len);
*writed += data_len;
}
// format_number
// copy non aligned data
void memcpy2(char* dest, char* src) {
dest[0] = src[0];
dest[1] = src[1];
}
void memcpy4(char* dest, char* src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
}
void memcpy8(char* dest, char* src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
dest[4] = src[4];
dest[5] = src[5];
dest[6] = src[6];
dest[7] = src[7];
}
// swap bytes for converting endians
void swapBytes16(char* a, char* b) {
// b is output
b[0] = a[1];
b[1] = a[0];
}
void swapBytes32(char* a, char* b) {
// b is output
b[0] = a[3];
b[1] = a[2];
b[2] = a[1];
b[3] = a[0];
}
void swapBytes64(char* a, char* b) {
// b is output
b[0] = a[7];
b[1] = a[6];
b[2] = a[5];
b[3] = a[4];
b[4] = a[3];
b[5] = a[2];
b[6] = a[1];
b[7] = a[0];
}
bool cpu_checkNumberFormat() {
char current_endians = 0;
int n = 1;
if (* (char *) &n == 1) {
current_endians = __TargetMemoryType_endiansLittle__;
} else {
current_endians = __TargetMemoryType_endiansBig__;
}
if (__target_memory_type__ == current_endians) {
return true;
} else {
printf("%d wrong MEMORY_TYPE !\r\n", __LINE__);
}
return false;
}
#if __target_memory_type__ == __TargetMemoryType_endiansBig__
#define nativeToBig16(src, dest) memcpy2(dest, src)
#define nativeToBig32(src, dest) memcpy4(dest, src)
#define nativeToBig64(src, dest) memcpy8(dest, src)
#define nativeToLittle16(src, dest) swapBytes16(src, dest)
#define nativeToLittle32(src, dest) swapBytes32(src, dest)
#define nativeToLittle64(src, dest) swapBytes64(src, dest)
#elif __target_memory_type__ == __TargetMemoryType_endiansLittle__
#define nativeToBig16(src, dest) swapBytes16(src, dest)
#define nativeToBig32(src, dest) swapBytes32(src, dest)
#define nativeToBig64(src, dest) swapBytes64(src, dest)
#define nativeToLittle16(src, dest) memcpy2(dest, src)
#define nativeToLittle32(src, dest) memcpy4(dest, src)
#define nativeToLittle64(src, dest) memcpy8(dest, src)
#else
#error "please define __target_memory_type__ with __TargetMemoryType_ (you can test endings with cpu_checkNumberFormat function)"
#endif
// read unaligned memory
// big
uint16_t readBig16(char* src) {
uint16_t ret;
nativeToBig16(src, (char*) &ret);
return ret;
}
uint32_t readBig32(char* src) {
uint32_t ret;
nativeToBig32(src, (char*) &ret);
return ret;
}
uint64_t readBig64(char* src) {
uint64_t ret;
nativeToBig64(src, (char*) &ret);
return ret;
}
// little
uint16_t readLittle16(char* src) {
uint16_t ret;
nativeToLittle16(src, (char*) &ret);
return ret;
}
uint32_t readLittle32(char* src) {
uint32_t ret;
nativeToLittle32(src, (char*) &ret);
return ret;
}
uint64_t readLittle64(char* src) {
uint64_t ret;
nativeToLittle64(src, (char*) &ret);
return ret;
}
// write unaligned memory
// big
void writeBig16(uint16_t value, char* dest) {
nativeToBig16((char*)&value, dest);
}
void writeBig32(uint32_t value, char* dest) {
nativeToBig32((char*)&value, dest);
}
void writeBig64(uint64_t value, char* dest) {
nativeToBig64((char*)&value, dest);
}
// little
void writeLittle16(uint16_t value, char* dest) {
nativeToLittle16((char*)&value, dest);
}
void writeLittle32(uint32_t value, char* dest) {
nativeToLittle32((char*)&value, dest);
}
void writeLittle64(uint64_t value, char* dest) {
nativeToLittle64((char*)&value, dest);
}
// Slice
void Slice_debug(struct Slice* slice, char* name, size_t line) {
if (slice->len == 0) {
printf("%zu: %s is NULL. \r\n", line, name);
} else {
printf("%zu: %s (%zu): \"%.*s", line, name, slice->len, (int)slice->len, slice->ptr);
}
}
bool Scalpi_mem_find(struct Slice* slice, struct Slice* desired, uintptr_t* out_pos) {
// not fast
if (slice->len >= desired->len) {
uintptr_t last_pos = slice->len - desired->len;
for (uintptr_t pos = 0; pos <= last_pos; pos++) {
size_t slice_len = slice->len - pos;
if (slice_len >= desired->len) {
if (Scalpi_mem_isEql(&slice->ptr[pos], desired->ptr, desired->len)) {
*out_pos = pos;
return true;
}
} else {
break;
}
}
} else {
// printf("%d desired is too long\r\n", __LINE__);
}
return false;
}
bool isStartWith(struct Slice* a, struct Slice* b) {
return (a->len >= b->len) && Scalpi_mem_isEql(a->ptr, b->ptr, b->len);
}
// Finder
void Finder_init(struct Finder* t, char* text, size_t text_len, char* desired, size_t desired_len) {
t->pos = 0;
t->text.ptr = text;
t->text.len = text_len;
t->desired.ptr = desired;
t->desired.len = desired_len;
}
bool Finder_next(struct Finder* t, size_t* out_pos) {
if (t->pos != t->text.len) {
struct Slice slice; // = t->text[->.pos..];
slice.ptr = &t->text.ptr[t->pos];
slice.len = t->text.len - t->pos;
size_t finded;
if (Scalpi_mem_find(&slice, &t->desired, &finded)) {
size_t new_pos = t->pos + finded;
t->pos = new_pos + t->desired.len;
*out_pos = new_pos;
return true;
}
}
return false;
}
// text Splitter
void Scalpi_Text_Splitter_init(struct Scalpi_Text_Splitter* t, char* text, size_t text_len, char* delim, size_t delim_len) {
t->stop = false;
t->last_pos = 0;
Finder_init(&t->finder, text, text_len, delim, delim_len);
}
bool Scalpi_Text_Splitter_next(struct Scalpi_Text_Splitter* t, struct Slice* out_slice) {
if (t->stop == false) {
size_t finded;
if (Finder_next(&t->finder, &finded)) {
out_slice->ptr = &t->finder.text.ptr[t->last_pos]; // slice = t->finder.text[t->last_pos..finded];
out_slice->len = finded - t->last_pos;
t->last_pos = t->finder.pos;
return true;
} else {
t->stop = true;
out_slice->ptr = &t->finder.text.ptr[t->last_pos]; // slice = t->finder.text[t->last_pos..];
out_slice->len = t->finder.text.len - t->last_pos;
t->last_pos = t->finder.pos;
return true;
}
}
return false;
}
// math
uint32_t ceilDiv32(uint32_t a, uint32_t b) {
return (a + b - 1) / b;
}
// Scalpi_Text_writeU64AsText
#define Scalpi_Text_CharsDecFromU64_MAX_LEN TEXT_LEN("18446744073709551615")
size_t Scalpi_Text_writeU64AsTextToBuffer(char buffer[], uint64_t number, size_t min_width) { // utoa utos
size_t writed = 0;
// write number to tmp
char buffer_tmp[Scalpi_Text_CharsDecFromU64_MAX_LEN];
uintptr_t tmp_ptr = (uintptr_t) &buffer_tmp[0] + Scalpi_Text_CharsDecFromU64_MAX_LEN;
for (uint64_t num = number; num > 0; num = num / 10) {
uint8_t remainder = num % 10;
tmp_ptr--;
*(char*)tmp_ptr = '0' + (char) remainder;
}
const uintptr_t writed_tmp = (uintptr_t) &buffer_tmp[0] + Scalpi_Text_CharsDecFromU64_MAX_LEN - (uintptr_t) tmp_ptr;
// fill zeroes to min_width
size_t extra_fill = 0;
if (min_width > writed_tmp) {
extra_fill = min_width - writed_tmp;
writed += Scalpi_mem_fill(&buffer[0], '0', extra_fill);
}
if (writed_tmp > 0) {
__ScalpiMem_copy__(&buffer[writed], (char*)tmp_ptr, writed_tmp);
writed += writed_tmp;
}
return writed;
}
size_t Scalpi_Text_writeU64AsTextToWriteFnVoid(__WriteFnPtrVoid__ write, void* context, uint64_t number, size_t min_width) {
char buffer_tmp[Scalpi_Text_CharsDecFromU64_MAX_LEN];
const size_t writed = Scalpi_Text_writeU64AsTextToBuffer(&buffer_tmp[0], number, min_width);
write(context, buffer_tmp, writed);
return writed;
}
// C_Text
size_t C_Text_getLen(const char text[]) {
size_t len = 0;
while(text[len] != 0) len++;
return len;
}
size_t C_Text_writeToBuffer(char buffer[], char data[]) {
const size_t len = C_Text_getLen(data);
__ScalpiMem_copy__(buffer, data, len);
return len;
}
size_t C_Text_writeToWriteFn(__WriteFnPtr__ write, void* context, const char text[]) {
const size_t len = C_Text_getLen(text);
return write(context, text, len);
}
// Os
void __OsConsoleOutput_init__(struct Os_Console_Output* t, Os_Console_Output_Handle handle) {
t->handle = handle;
}
size_t __OsConsoleOutput_write__(struct Os_Console_Output* t, const char* text, size_t _text_len) {
#ifdef _WIN32
size_t len = _text_len;
if (len == 0) {
while(text[len] != 0) len += 1;
}
unsigned long writed = 0;
WriteConsoleA(t->handle, text, len, &writed, NULL);
return writed;
#elif defined(__linux__)
// TODO
return 0;
#endif
}
size_t __OsFallbackConsole_write__(void* unused_ctx, char* data, size_t len) {
#ifdef _WIN32
struct Os_Console_Output console_output;
__OsConsoleOutput_init__(&console_output, GetStdHandle(STD_OUTPUT_HANDLE));
__OsConsoleOutput_write__(&console_output, data, len);
return len;
#elif defined(__linux__)
// TODO
return 0;
#endif
}
bool __Os_writeHome__(char* buffer, size_t space, size_t* ret_writed) {
bool ok = true;
#ifdef _WIN32
char* home_drive = getenv("HOMEDRIVE");
char* home_path = getenv("HOMEPATH");
// get len
size_t home_drive_len = C_Text_getLen(home_drive);
size_t home_path_len = C_Text_getLen(home_path);
size_t len = 0
+ home_drive_len
+ home_path_len
;
if (space >= len) {
size_t writed = 0;
__ScalpiMem_copy__(&buffer[writed], home_drive, home_drive_len);
writed += home_drive_len;
__ScalpiMem_copy__(&buffer[writed], home_path, home_path_len);
writed += home_path_len;
if (len == writed) {
*ret_writed += len;
} else {
ok = false;
// print "{line} PATH={buffer:buffer_len}\n\n\n"
Scalpi_Text_writeU64AsTextToWriteFnVoid((__WriteFnPtrVoid__)&__OsFallbackConsole_write__, NULL, __LINE__, 1);
__OsFallbackConsole_write__(NULL, " ", 3);
Scalpi_Text_writeU64AsTextToWriteFnVoid((__WriteFnPtrVoid__)&__OsFallbackConsole_write__, NULL, len, 1);
__OsFallbackConsole_write__(NULL, " ", 3);
__OsFallbackConsole_write__(NULL, "PATH=", 5);
__OsFallbackConsole_write__(NULL, buffer, len);
__OsFallbackConsole_write__(NULL, "\n\n\n", 3);
}
} else {
ok = false;
// print "{line} need {len} space\r\n"
Scalpi_Text_writeU64AsTextToWriteFnVoid((__WriteFnPtrVoid__)&__OsFallbackConsole_write__, NULL, __LINE__, 1);
__OsFallbackConsole_write__(NULL, "need ", 0);
Scalpi_Text_writeU64AsTextToWriteFnVoid((__WriteFnPtrVoid__)&__OsFallbackConsole_write__, NULL, len, 1);
__OsFallbackConsole_write__(NULL, " space\r\n ", 0);
}
#elif defined(__linux__)
char* home = getenv("HOME");
size_t len = C_Text_getLen(home);
if (space >= len) {
__ScalpiMem_copy__(buffer, home, len);
*ret_writed += len;
} else {
ok = false;
}
#endif
return ok;
}
// time
uint64_t os_getTick() {
#ifdef _WIN32
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
uint64_t ft64;
memcpy8((char*) &ft64, (void*)&ft);
return ft64 / 10000; // in ft is intervals * 100 ns. to ms need * 100 / 1000000
#endif
// TODO ME FOR LINUX
}
void Os_sleep(uint64_t ms) {
#ifdef _WIN32
Sleep(ms);
#endif
// TODO ME FOR LINUX
}
// Console
// ConsoleOutput
void Os_Console_Output_init(struct Os_Console_Output* output, Os_Console_Output_Handle handle) {
output->handle = handle;
#ifdef _WIN32
// output->handle = GetStdHandle(c.STD_OUTPUT_HANDLE);
#elif defined(__linux__)
// output->handle = stdout
output->fileno = fileno(output->handle);
#endif
}
size_t Os_Console_Output_write(struct Os_Console_Output* output, const char* text, size_t len) {
#ifdef _WIN32
size_t writed = 0;
WriteConsoleA(output->handle, text, len, &writed, 0);
#elif defined(__linux__)
//write(output->fileno, text, len);
fwrite(text, sizeof(char), len, output->handle);
#endif
return len;
}
// ConsoleIntput
void Os_Console_Input_init(struct Os_Console_Input* input, Os_Console_Input_Handle handle) {
input->handle = handle;
#ifdef _WIN32
// input->handle = GetStdHandle(c.STD_INPUT_HANDLE);
#elif defined(__linux__)
// input->handle = stdout
input->fileno = fileno(input->handle);
#endif
}
// Scalpi
// Scalpi_Logger
void Scalpi_Logger_init (struct Scalpi_Logger* t) {
for (int i = 0; i < ARRAY_LEN(t->writers); i++) {
struct __Scalpi_Writer__* w = &t->writers[i];
w->context = 0;
w->write = 0;
}
}
size_t Scalpi_Logger_writeToSelf(struct Scalpi_Logger* t, const char bytes[], size_t len) {
for (size_t i = 0; i < ARRAY_LEN(t->writers); i++) {
struct __Scalpi_Writer__* w = &t->writers[i];
if (w->write) {
size_t writed = w->write(w->context, bytes, len);
}
}
}
// App
// struct App_Os_Helper
bool App_Os_Helper_init(struct App_Os_Helper* os_helper) {
#ifdef _WIN32
os_helper->instance = GetModuleHandleA(0);
if (os_helper->instance) { // enable network
return true;
}
FreeLibrary(os_helper->instance);
return false;
#endif
// TODO ME FOR LINUX
}
void App_Os_Helper_deinit(struct App_Os_Helper* os_helper) {
#ifdef _WIN32
FreeLibrary(os_helper->instance);
#endif
// TODO ME FOR LINUX
}
void App_Os_Helper_process(struct App_Os_Helper* os_helper) {
#ifdef _WIN32
MSG msg;
size_t message_count = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
if (message_count == 0) return;
TranslateMessage(&msg);
DispatchMessageA(&msg);
#endif
// TODO ME FOR LINUX
}
// struct App
bool App_init(struct App* t) {
Scalpi_Logger_init(&t->logger); // preinit console output for debug
if (App_Os_Helper_init(&t->os_helper)) {
t->tick = os_getTick();
return true;
// fallback
// App_Os_Helper_deinit(&t->os_helper);
} else {
printf("%d app.os_helper not inited\r\n", __LINE__);
}
return false;
}
void App_deinit(struct App* app) {
App_Os_Helper_deinit(&app->os_helper);
}
bool App_process(struct App* t) {
App_Os_Helper_process(&t->os_helper);
return true;
}
void App_waitToNextFrame(struct App* t) {
uint64_t expected_frame_end_time = t->tick + App_delay_to_start_frame_target;
uint64_t resulting_frame_end_time = os_getTick();
if (resulting_frame_end_time > expected_frame_end_time + 120) {
uint64_t delta = resulting_frame_end_time - expected_frame_end_time;
printf("%d \t hitch detection: %zu delta: %zu ms \r\n", __LINE__, t->tick, delta);
}
uint64_t delay_sleep = 1;
if (resulting_frame_end_time < expected_frame_end_time) {
delay_sleep = expected_frame_end_time - resulting_frame_end_time;
}
Os_sleep(delay_sleep);
t->tick = resulting_frame_end_time + delay_sleep;
}
// main
bool tests() {
if ( true
and cpu_checkNumberFormat()
// and etc...
// and etc...
) {
return true;
} else {
printf("%d fail tests \r\n", __LINE__);
return false;
}
return true;
}
bool real_main(int args_len, char** args_ptr) {
if (tests()) {
if (App_init(&global_app)) {
while(true) {
if (!App_process(&global_app)) break;
App_waitToNextFrame(&global_app);
}
App_deinit(&global_app);
return true;
} else {
printf("%d fail: App_init\r\n", __LINE__);
}
} else {
printf("%d fail tests \r\n", __LINE__);
}
return false;
}
int main2(int args_len, char** args_ptr) {
if (real_main(args_len, args_ptr)) return 0;
return 1;
}