More support for framebuffer and terminal coexistence.

This commit is contained in:
sorgelig
2019-05-24 01:20:50 +08:00
parent 6f4cf8da33
commit ac7ba6d115
9 changed files with 356 additions and 107 deletions

View File

@@ -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

1
cfg.h
View File

@@ -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];

View File

@@ -11,6 +11,7 @@
#include <sys/stat.h>
#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);

View File

@@ -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<NUMDEV; i++) if (pool[i].fd >= 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;
}

View File

@@ -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

View File

@@ -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;
/******************************************************************/

View File

@@ -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);
}
}
}

312
video.cpp
View File

@@ -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;
}
}

View File

@@ -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