diff --git a/cfg.cpp b/cfg.cpp index 62a375e..225ffe3 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -13,6 +13,7 @@ void MiSTer_ini_parse() { memset(&cfg, 0, sizeof(cfg)); cfg.bootscreen = 1; + cfg.fb_size = 1; ini_parse(&ini_cfg); } @@ -50,6 +51,7 @@ const ini_var_t ini_vars[] = { { "BOOTCORE", (void*)(&(cfg.bootcore)), STRING, 0, sizeof(cfg.bootcore) - 1, 1 }, { "BOOTCORE_TIMEOUT", (void*)(&(cfg.bootcore_timeout)), INT16, 10, 30, 1 }, { "FONT", (void*)(&(cfg.font)), STRING, 0, sizeof(cfg.font) - 1, 1 }, + { "FB_SIZE", (void*)(&(cfg.fb_size)), UINT8, 1, 4, 1 }, }; // mist ini config diff --git a/cfg.h b/cfg.h index 06f5253..e4e457d 100644 --- a/cfg.h +++ b/cfg.h @@ -34,6 +34,7 @@ typedef struct { uint8_t rbf_hide_datecode; uint8_t menu_pal; int16_t bootcore_timeout; + uint8_t fb_size; char bootcore[256]; char video_conf[1024]; char video_conf_pal[1024]; diff --git a/fpga_io.cpp b/fpga_io.cpp index a3ac44e..b30911f 100644 --- a/fpga_io.cpp +++ b/fpga_io.cpp @@ -11,6 +11,7 @@ #include #include "fpga_io.h" #include "file_io.h" +#include "input.h" #include "fpga_base_addr_ac5.h" #include "fpga_manager.h" @@ -628,6 +629,8 @@ void app_restart(const char *path) sync(); fpga_core_reset(1); + input_switch(0); + char *appname = getappname(); printf("restarting the %s\n", appname); execl(appname, appname, path, NULL); diff --git a/input.cpp b/input.cpp index aa12a78..203d313 100644 --- a/input.cpp +++ b/input.cpp @@ -1171,6 +1171,8 @@ static int mapping_set; static uint32_t tmp_axis[4]; static int tmp_axis_n = 0; +static int grabbed = 1; + void start_map_setting(int cnt, int set) { mapping_button = 0; @@ -1372,6 +1374,11 @@ static uint32_t mouse_timer = 0; #define BTN_TGL 100 #define BTN_OSD 101 +static void mouse_cb(unsigned char b, int16_t x, int16_t y) +{ + if (grabbed) user_io_mouse(b, x, y); +} + static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int bnum) { static char str[128]; @@ -1479,7 +1486,7 @@ static void joy_digital(int jnum, uint32_t mask, uint32_t code, char press, int mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - user_io_mouse(mice_btn, 0, 0); + mouse_cb(mice_btn, 0, 0); mouse_emu ^= 2; if (hasAPI1_5()) Info((mouse_emu & 2) ? "Mouse mode ON" : "Mouse mode OFF"); @@ -1551,7 +1558,7 @@ static void joy_analog(int num, int axis, int offset) { static int pos[NUMPLAYERS][2] = {}; - if (num > 0 && num < NUMPLAYERS+1) + if (grabbed && num > 0 && num < NUMPLAYERS+1) { num--; pos[num][axis] = offset; @@ -1985,7 +1992,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int default: mouse_btn = ev->value ? mouse_btn | 1 << (i - 12) : mouse_btn & ~(1 << (i - 12)); - user_io_mouse(mouse_btn | mice_btn, 0, 0); + mouse_cb(mouse_btn | mice_btn, 0, 0); break; } return; @@ -2025,7 +2032,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - user_io_mouse(mice_btn, 0, 0); + mouse_cb(mice_btn, 0, 0); } } } @@ -2113,7 +2120,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int default: mouse_btn = ev->value ? mouse_btn | 1 << (i - 12) : mouse_btn & ~(1 << (i - 12)); - user_io_mouse(mouse_btn | mice_btn, 0, 0); + mouse_cb(mouse_btn | mice_btn, 0, 0); break; } return; @@ -2138,7 +2145,7 @@ static void input_cb(struct input_event *ev, struct input_absinfo *absinfo, int mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - user_io_mouse(mice_btn, 0, 0); + mouse_cb(mice_btn, 0, 0); } return; } @@ -2365,6 +2372,8 @@ int input_test(int getchar) memset(input[n].uniq, 0, sizeof(input[n].uniq)); } + ioctl(pool[n].fd, EVIOCGRAB, (grabbed | user_io_osd_is_visible()) ? 1 : 0); + n++; if (n >= NUMDEV) break; } @@ -2410,7 +2419,11 @@ int input_test(int getchar) if ((pool[NUMDEV].revents & POLLIN) && check_devs()) { printf("Close all devices.\n"); - for (int i = 0; i= 0) close(pool[i].fd); + for (int i = 0; i < NUMDEV; i++) if (pool[i].fd >= 0) + { + ioctl(pool[i].fd, EVIOCGRAB, 0); + close(pool[i].fd); + } state = 1; return 0; } @@ -2737,7 +2750,7 @@ int input_test(int getchar) mice_btn = data[0] & 7; if (ds_mouse_emu) mice_btn = (mice_btn & 4) | ((mice_btn & 1)<<1); - user_io_mouse(mouse_btn | mice_btn, xval, yval); + mouse_cb(mouse_btn | mice_btn, xval, yval); } } } @@ -2797,7 +2810,7 @@ int input_poll(int getchar) if (dy < -2) dy = -2; } - user_io_mouse(mouse_btn | mice_btn, dx, dy); + mouse_cb(mouse_btn | mice_btn, dx, dy); prev_dx = mouse_emu_x; prev_dy = mouse_emu_y; } @@ -2832,7 +2845,7 @@ int input_poll(int getchar) if (joy[i] & autofire[i]) send = 1; } - if (send) + if (grabbed && send) { user_io_digital_joystick(i, af[i] ? joy[i] & ~autofire[i] : joy[i], newdir); } @@ -2878,5 +2891,21 @@ void input_notify_mode() mouse_btn = 0; mouse_emu_x = 0; mouse_emu_y = 0; - user_io_mouse(mice_btn, 0, 0); + mouse_cb(mice_btn, 0, 0); +} + +void input_switch(int grab) +{ + if (grab >= 0) grabbed = grab; + printf("input_switch(%d), grabbed = %d\n", grab, grabbed); + + for (int i = 0; i < NUMDEV; i++) + { + if (pool[i].fd >= 0) ioctl(pool[i].fd, EVIOCGRAB, (grabbed | user_io_osd_is_visible()) ? 1 : 0); + } +} + +int input_state() +{ + return grabbed; } diff --git a/input.h b/input.h index 1c201db..ab2fcaa 100644 --- a/input.h +++ b/input.h @@ -55,4 +55,7 @@ uint32_t get_archie_code(uint16_t key); int input_has_lightgun(); void input_lightgun_cal(uint16_t *cal); +void input_switch(int grab); +int input_state(); + #endif diff --git a/menu.cpp b/menu.cpp index d7790ea..c47acba 100644 --- a/menu.cpp +++ b/menu.cpp @@ -90,13 +90,13 @@ enum MENU MENU_LOADCONFIG_2, MENU_SAVECONFIG_1, MENU_SAVECONFIG_2, - MENU_FIRMWARE1, - MENU_FIRMWARE_CORE_FILE_SELECTED1, - MENU_FIRMWARE_CORE_FILE_SELECTED2, - MENU_FIRMWARE_CORE_FILE_CANCELED, + MENU_SYSTEM1, + MENU_SYSTEM2, + MENU_CORE_FILE_SELECTED1, + MENU_CORE_FILE_SELECTED2, + MENU_CORE_FILE_CANCELED, MENU_ERROR, MENU_INFO, - MENU_STORAGE, MENU_JOYDIGMAP, MENU_JOYDIGMAP1, MENU_JOYDIGMAP2, @@ -463,7 +463,7 @@ static uint32_t menu_key_get(void) c2 = c1; // inject a fake "MENU_KEY" if no menu is visible and the menu key is loaded - if (!user_io_osd_is_visible() && is_menu_core()) c = KEY_F12; + if (!user_io_osd_is_visible() && !video_fb_state() && is_menu_core()) c = KEY_F12; // generate repeat "key-pressed" events if ((c1 & UPSTROKE) || (!c1)) @@ -812,6 +812,7 @@ void HandleUI(void) status <<= 1; user_io_8bit_set_status(status, 0xE); FileSaveConfig(user_io_create_config_name(), &status, 4); + video_menu_bg((status >> 1) & 7); } break; @@ -836,6 +837,7 @@ void HandleUI(void) //debug case KEY_F9: video_fb_enable(!video_fb_state()); + if(video_fb_state() || !is_menu_core()) menustate = MENU_NONE1; break; // Within the menu the esc key acts as the menu key. problem: @@ -966,7 +968,7 @@ void HandleUI(void) OsdSetSize(16); if(!is_menu_core() && (get_key_mod() & (LALT | RALT))) //Alt+Menu { - SelectFile(0, SCANO_CORES, MENU_FIRMWARE_CORE_FILE_SELECTED1, MENU_NONE1); + SelectFile(0, SCANO_CORES, MENU_CORE_FILE_SELECTED1, MENU_NONE1); } else if (user_io_core_type() == CORE_TYPE_MINIMIG2) menustate = MENU_MAIN1; else if (user_io_core_type() == CORE_TYPE_MIST) menustate = MENU_MIST_MAIN1; @@ -975,7 +977,7 @@ void HandleUI(void) if (is_menu_core()) { OsdCoreNameSet(""); - SelectFile(0, SCANO_CORES, MENU_FIRMWARE_CORE_FILE_SELECTED1, MENU_FIRMWARE1); + SelectFile(0, SCANO_CORES, MENU_CORE_FILE_SELECTED1, MENU_SYSTEM1); } else { @@ -1582,7 +1584,7 @@ void HandleUI(void) switch (menusub) { case 0: - SelectFile(0, SCANO_CORES, MENU_FIRMWARE_CORE_FILE_SELECTED1, MENU_8BIT_SYSTEM1); + SelectFile(0, SCANO_CORES, MENU_CORE_FILE_SELECTED1, MENU_8BIT_SYSTEM1); menusub = 0; break; @@ -2008,7 +2010,7 @@ void HandleUI(void) finish_map_setting(menu); if (is_menu_core()) { - menustate = MENU_FIRMWARE1; + menustate = MENU_SYSTEM1; menusub = 2; } else @@ -3679,7 +3681,13 @@ void HandleUI(void) /******************************************************************/ /* firmware menu */ /******************************************************************/ - case MENU_FIRMWARE1: + case MENU_SYSTEM1: + if (video_fb_state()) + { + menustate = MENU_NONE1; + break; + } + helptext = helptexts[HELPTEXT_NONE]; parentstate = menustate; @@ -3733,25 +3741,14 @@ void HandleUI(void) OsdWrite(9, " Scripts \x16", menusub == 3, 0); sysinfo_timer = 0; - menustate = MENU_STORAGE; + menustate = MENU_SYSTEM2; - case MENU_STORAGE: + case MENU_SYSTEM2: if (menu) { - switch (user_io_core_type()) { - case CORE_TYPE_MIST: - menusub = 5; - menustate = MENU_MIST_MAIN1; - break; - case CORE_TYPE_ARCHIE: - menusub = 3; - menustate = MENU_ARCHIE_MAIN1; - break; - default: - menusub = 0; - menustate = MENU_NONE1; - break; - } + OsdCoreNameSet(""); + SelectFile(0, SCANO_CORES, MENU_CORE_FILE_SELECTED1, MENU_SYSTEM1); + break; } else if (select) { @@ -3801,7 +3798,7 @@ void HandleUI(void) } } - if(match) SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_FIRMWARE1); + if(match) SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_SYSTEM1); else { menustate = MENU_SCRIPTS_PRE; @@ -3905,13 +3902,13 @@ void HandleUI(void) break; case MENU_SCRIPTS_PRE1: - if (menu) menustate = MENU_FIRMWARE1; + if (menu) menustate = MENU_SYSTEM1; else if (select) { switch (menusub) { case 0: - menustate = MENU_FIRMWARE1; + menustate = MENU_SYSTEM1; break; case 2: @@ -3919,7 +3916,7 @@ void HandleUI(void) // fall through case 1: - SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_FIRMWARE1); + SelectFile("SH", SCANO_DIR, MENU_SCRIPTS, MENU_SYSTEM1); break; } } @@ -4004,7 +4001,7 @@ void HandleUI(void) } else { - menustate = MENU_FIRMWARE1; + menustate = MENU_SYSTEM1; menusub = 3; } } @@ -4045,12 +4042,12 @@ void HandleUI(void) if (select || menu) { finish_map_setting(menu); - menustate = MENU_FIRMWARE1; + menustate = MENU_SYSTEM1; menusub = 1; } break; - case MENU_FIRMWARE_CORE_FILE_SELECTED1: + case MENU_CORE_FILE_SELECTED1: menustate = MENU_NONE1; strcpy(SelectedRBF, SelectedPath); if (!getStorage(0)) // multiboot is only on SD card. @@ -4067,7 +4064,7 @@ void HandleUI(void) strcat(SelectedPath, ".txt"); if (FileLoad(SelectedPath, 0, 0)) { - menustate = MENU_FIRMWARE_CORE_FILE_SELECTED2; + menustate = MENU_CORE_FILE_SELECTED2; break; } } @@ -4078,8 +4075,8 @@ void HandleUI(void) strcpy(fs_pFileExt, "TXT"); fs_ExtLen = 3; fs_Options = SCANO_CORES; - fs_MenuSelect = MENU_FIRMWARE_CORE_FILE_SELECTED2; - fs_MenuCancel = MENU_FIRMWARE_CORE_FILE_CANCELED; + fs_MenuSelect = MENU_CORE_FILE_SELECTED2; + fs_MenuCancel = MENU_CORE_FILE_CANCELED; menustate = MENU_FILE_SELECT1; break; } @@ -4090,14 +4087,14 @@ void HandleUI(void) fpga_load_rbf(SelectedRBF); break; - case MENU_FIRMWARE_CORE_FILE_SELECTED2: + case MENU_CORE_FILE_SELECTED2: OsdDisable(); fpga_load_rbf(SelectedRBF, SelectedPath); menustate = MENU_NONE1; break; - case MENU_FIRMWARE_CORE_FILE_CANCELED: - SelectFile(0, SCANO_CORES, MENU_FIRMWARE_CORE_FILE_SELECTED1, cp_MenuCancel); + case MENU_CORE_FILE_CANCELED: + SelectFile(0, SCANO_CORES, MENU_CORE_FILE_SELECTED1, cp_MenuCancel); break; /******************************************************************/ diff --git a/user_io.cpp b/user_io.cpp index c89ea2c..f45733b 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -593,6 +593,12 @@ void user_io_init(const char *path) } parse_config(); + if (is_menu_core()) + { + user_io_8bit_set_status((cfg.menu_pal) ? 0x10 : 0, 0x10); + video_menu_bg((status >> 1) & 7); + } + if (is_x86_core()) { x86_config_load(); @@ -1533,6 +1539,7 @@ void user_io_send_buttons(char force) if ((key_map & BUTTON2) && !(map & BUTTON2)) { const char *name = get_rbf_name(); + OsdDisable(); fpga_load_rbf(name[0] ? name : "Archie.rbf"); } } @@ -2162,6 +2169,7 @@ void user_io_poll() if (!coldreset_req && prev_coldreset_req) { + OsdDisable(); fpga_load_rbf("menu.rbf"); } @@ -2468,6 +2476,7 @@ void user_io_osd_key_enable(char on) { printf("OSD is now %s\n", on ? "visible" : "invisible"); osd_is_visible = on; + input_switch(-1); } int get_volume() @@ -2644,7 +2653,7 @@ void user_io_kbd(uint16_t key, int press) else { if(key == KEY_MENU) key = KEY_F12; - send_keycode(key, press); + if(input_state()) send_keycode(key, press); } } } diff --git a/video.cpp b/video.cpp index e24608d..b6c878f 100644 --- a/video.cpp +++ b/video.cpp @@ -11,13 +11,14 @@ #include "file_io.h" #include "menu.h" #include "video.h" +#include "input.h" #include "support.h" -#define FB_SIZE (1024*1024*8) // 8MB x 3 +#define FB_SIZE (1024*1024*8) // 8MB #define FB_ADDR (0x20000000 + (32*1024*1024)) // 512mb + 32mb(Core's fb) #define FB_FMT 2 // 0 - 16bit, 1 - 24bit(not supported), 2 - 32bit -#define FB_HDRSZ (256/(FB_FMT+2)) +#define FB_RxB 1 #if(FB_FMT == 2) static volatile uint32_t *fb_base = 0; @@ -29,6 +30,8 @@ static int fb_enabled = 0; static int fb_width = 0; static int fb_height = 0; static int fb_stride = 0; +static int fb_num = 0; +static int menu_bg = 0; struct vmode_t { @@ -264,6 +267,8 @@ static void loadScalerCfg() } } +static char fb_reset_cmd[128] = {}; + static void set_video(vmode_custom_t *v, double Fpix) { loadScalerCfg(); @@ -288,7 +293,7 @@ static void set_video(vmode_custom_t *v, double Fpix) for (int i = 9; i < 21; i++) { printf("0x%X, ", v_cur.item[i]); - if (i & 1) spi_w(v_cur.item[i] | ((i == 9 && (is_menu_core() ? cfg.menu_pal : (Fpix && cfg.vsync_adjust == 2))) ? 0x8000 : 0)); + if (i & 1) spi_w(v_cur.item[i] | ((i == 9 && Fpix && cfg.vsync_adjust == 2 && !is_menu_core()) ? 0x8000 : 0)); else { spi_w(v_cur.item[i]); @@ -298,6 +303,19 @@ static void set_video(vmode_custom_t *v, double Fpix) printf("Fpix=%f\n", v_cur.Fpix); DisableIO(); + + if (cfg.fb_size < 1) cfg.fb_size = 1; + else if (cfg.fb_size == 3) cfg.fb_size = 2; + else if (cfg.fb_size > 4) cfg.fb_size = 4; + + fb_width = v_cur.item[1] / cfg.fb_size; + fb_height = v_cur.item[5] / cfg.fb_size; + fb_stride = ((fb_width * (FB_FMT ? 4 : 2)) + 255) & ~255; + + if (fb_enabled) video_fb_enable(1, fb_num); + + sprintf(fb_reset_cmd, "taskset 1 echo %d %d %d %d %d >/sys/module/MiSTer_fb/parameters/mode", FB_FMT ? 8888 : 1555, FB_RxB, fb_width, fb_height, fb_stride); + system(fb_reset_cmd); } static int parse_custom_video_mode(char* vcfg, vmode_custom_t *v) @@ -377,10 +395,8 @@ static void fb_init() { if (!fb_base) { - static int fd; - fb_base = 0; - - if ((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) return; + int fd = open("/dev/mem", O_RDWR | O_SYNC); + if (fd == -1) return; #if(FB_FMT == 2) fb_base = (volatile uint32_t*)mmap(0, FB_SIZE * 3, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FB_ADDR); @@ -391,9 +407,10 @@ static void fb_init() { printf("Unable to mmap FB!\n"); fb_base = 0; - close(fd); } + close(fd); } + spi_uio_cmd16(UIO_SET_FBUF, 0); } void video_mode_load() @@ -555,81 +572,268 @@ void video_mode_adjust() } } -static void fill_fb() -{ - int pos = 0; - for (int y = 0; y < fb_height; y++) - { - pos = y * fb_stride + FB_HDRSZ; - int base_color = (y / 32) & 7; - for (int x = 0; x < fb_width; x++) - { -#if(FB_FMT == 2) - int gray = (256 * x) / fb_width; - uint32_t color = 0; - if (base_color & 1) color |= gray; - if (base_color & 2) color |= gray << 8; - if (base_color & 4) color |= gray << 16; -#else - int gray = (32 * x) / fb_width; - uint16_t color = 0; - if (base_color & 1) color |= gray; - if (base_color & 2) color |= gray << 5; - if (base_color & 4) color |= gray << 10; -#endif - fb_base[pos++] = color; - } - } -} - -void video_fb_enable(int enable) +void video_fb_enable(int enable, int n) { if (fb_base) { int res = spi_uio_cmd_cont(UIO_SET_FBUF); if (res) { + if (is_menu_core() && !enable && menu_bg) + { + enable = 1; + n = 1; + } + if (enable) { - fb_width = (v_cur.item[1] >= 1440) ? v_cur.item[1] / 2 : v_cur.item[1]; - fb_height = (v_cur.item[5] >= 1080) ? v_cur.item[5] / 2 : v_cur.item[5]; + uint32_t fb_addr = FB_ADDR + (FB_SIZE*n); + fb_num = n; printf("Switch to HPS frame buffer\n"); - spi_w(0x8000 | (FB_FMT & 3) << 12); // enable flag, format, fixed height - spi_w((uint16_t)FB_ADDR); // base address low word - spi_w(FB_ADDR >> 16); // base address high word - spi_w(fb_width-1); // frame width - spi_w(fb_height-1); // frame height - spi_w(0); // Aspect ratio X/Y (0 - full screen) + spi_w((FB_FMT << 1) | (FB_RxB << 3) | 1); // format, enable flag + spi_w((uint16_t)fb_addr); // base address low word + spi_w(fb_addr >> 16); // base address high word + spi_w(fb_width); // frame width + spi_w(fb_height); // frame height + spi_w(0); // scaled left + spi_w(v_cur.item[1] - 1); // scaled right + spi_w(0); // scaled top + spi_w(v_cur.item[5] - 1); // scaled bottom -#if(FB_FMT == 2) - fb_stride = (((fb_width * 4 + 255) / 256) * 256)/4; -#else - fb_stride = (((fb_width * 2 + 255) / 256) * 256)/2; -#endif - - printf("HPS frame buffer: %dx%d, stride = %d items\n", fb_width, fb_height, fb_stride); - - fill_fb(); + printf("HPS frame buffer: %dx%d, stride = %d bytes\n", fb_width, fb_height, fb_stride); + if (!fb_num) + { + system(fb_reset_cmd); + input_switch(0); + } + else + { + input_switch(1); + } } else { printf("Switch to core frame buffer\n"); spi_w(0); // enable flag + input_switch(1); } + fb_enabled = enable; } else { printf("Core doesn't support HPS frame buffer\n"); + input_switch(1); } DisableIO(); } - } int video_fb_state() { + if (is_menu_core()) + { + return fb_enabled && !fb_num; + } + return fb_enabled; } + +static void draw_checkers() +{ + volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + int stride = fb_stride / (FB_FMT + 2); + + uint32_t col1 = 0xCCCCCC; + uint32_t col2 = 0x888888; + int sz = 16; + + int pos = 0; + for (int y = 0; y < fb_height; y++) + { + int c1 = (y / sz) & 1; + pos = y * stride; + for (int x = 0; x < fb_width; x++) + { + int c2 = c1 ^ ((x / sz) & 1); + buf[pos++] = c2 ? col2 : col1; + } + } +} + +static void draw_hbars1() +{ + volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + int stride = fb_stride / (FB_FMT + 2); + int old_base = 0; + int gray = 255; + + for (int y = 0; y < fb_height; y++) + { + int pos = y * stride; + int base_color = 7-((7 * y) / fb_height); + if (old_base != base_color) + { + gray = 255; + old_base = base_color; + } + + for (int x = 0; x < fb_width; x++) + { + uint32_t color = 0; + if (base_color & 4) color |= gray; + if (base_color & 2) color |= gray << 8; + if (base_color & 1) color |= gray << 16; + buf[pos++] = color; + } + + gray -= 3; + if (gray < 0) gray = 0; + } +} + +static void draw_hbars2() +{ + volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + int stride = fb_stride / (FB_FMT + 2); + + for (int y = 0; y < fb_height; y++) + { + int pos = y * stride; + int base_color = ((14 * y) / fb_height); + int inv = base_color & 1; + base_color >>= 1; + base_color = (inv ? base_color : 6 - base_color) + 1; + for (int x = 0; x < fb_width; x++) + { + int gray = (256 * x) / fb_width; + if (inv) gray = 255 - gray; + uint32_t color = 0; + if (base_color & 4) color |= gray; + if (base_color & 2) color |= gray << 8; + if (base_color & 1) color |= gray << 16; + buf[pos++] = color; + } + } +} + +static void draw_vbars1() +{ + volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + int stride = fb_stride / (FB_FMT + 2); + + for (int y = 0; y < fb_height; y++) + { + int pos = y * stride; + int old_base = 0; + int gray = 255; + for (int x = 0; x < fb_width; x++) + { + int base_color = 7-((7 * x) / fb_width); + if (old_base != base_color) + { + gray = 255; + old_base = base_color; + } + uint32_t color = 0; + if (base_color & 4) color |= gray; + if (base_color & 2) color |= gray << 8; + if (base_color & 1) color |= gray << 16; + buf[pos++] = color; + gray -= 2; + if (gray < 0) gray = 0; + } + } +} + +static void draw_vbars2() +{ + volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + int stride = fb_stride / (FB_FMT + 2); + + for (int y = 0; y < fb_height; y++) + { + int pos = y * stride; + for (int x = 0; x < fb_width; x++) + { + int gray = 255 - ((256 * y) / fb_height); + int base_color = ((14 * x) / fb_width); + int inv = base_color & 1; + base_color >>= 1; + base_color = (inv ? base_color : 6 - base_color) + 1; + + if (inv) gray = 255 - gray; + uint32_t color = 0; + if (base_color & 4) color |= gray; + if (base_color & 2) color |= gray << 8; + if (base_color & 1) color |= gray << 16; + buf[pos++] = color; + } + } +} + +static void draw_spectrum() +{ + volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + int stride = fb_stride / (FB_FMT + 2); + + for (int y = 0; y < fb_height; y++) + { + int pos = y * stride; + int blue = ((256 * y) / fb_height); + for (int x = 0; x < fb_width; x++) + { + int red = ((256 * x) / fb_width) - blue / 2; + int green = 255 - red - blue / 2; + if (red < 0) red = 0; + if (green < 0) green = 0; + + buf[pos++] = (red<<16) | (green<<8) | blue; + } + } +} + +static void draw_black() +{ + volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + int stride = fb_stride / (FB_FMT + 2); + + for (int y = 0; y < fb_height; y++) + { + int pos = y * stride; + for (int x = 0; x < fb_width; x++) buf[pos++] = 0; + } +} + +void video_menu_bg(int n) +{ + menu_bg = n; + video_fb_enable(0); + + switch (n) + { + case 1: + draw_checkers(); + break; + case 2: + draw_hbars1(); + break; + case 3: + draw_hbars2(); + break; + case 4: + draw_vbars1(); + break; + case 5: + draw_vbars2(); + break; + case 6: + draw_spectrum(); + break; + case 7: + draw_black(); + break; + } +} diff --git a/video.h b/video.h index 94ad918..67015ea 100644 --- a/video.h +++ b/video.h @@ -11,7 +11,8 @@ void video_mode_adjust(); int hasAPI1_5(); -void video_fb_enable(int enable); +void video_fb_enable(int enable, int n = 0); int video_fb_state(); +void video_menu_bg(int n); #endif // VIDEO_H