1
0
mirror of https://github.com/mist-devel/mist-firmware.git synced 2026-01-11 23:43:04 +00:00

New feature: BIGOSD

16 lines OSD (needs 2x amount of BRAM at the FGPA side)
This commit is contained in:
Gyorgy Szombathelyi 2023-10-13 14:14:12 +02:00
parent 7c56ce5d98
commit 047bbefc04
7 changed files with 146 additions and 117 deletions

View File

@ -5,6 +5,7 @@
#include "mmc.h" #include "mmc.h"
#include "fat_compat.h" #include "fat_compat.h"
#include "fpga.h" #include "fpga.h"
#include "osd.h"
#include "attrs.h" #include "attrs.h"
#include "utils.h" #include "utils.h"
@ -339,12 +340,13 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
char initial = 1; char initial = 1;
int i; int i;
unsigned char x; unsigned char x;
int maxdirentries = OsdLines();
if (mode == SCAN_INIT || mode == SCAN_INIT_FIRST) if (mode == SCAN_INIT || mode == SCAN_INIT_FIRST)
{ {
nDirEntries = 0; nDirEntries = 0;
iSelectedEntry = 0; iSelectedEntry = 0;
for (i = 0; i < MAXDIRENTRIES; i++) for (i = 0; i < maxdirentries; i++)
sort_table[i] = i; sort_table[i] = i;
if (f_opendir(&dir, ".") != FR_OK) return 0; if (f_opendir(&dir, ".") != FR_OK) return 0;
} }
@ -360,7 +362,7 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
iSelectedEntry++; iSelectedEntry++;
return 0; return 0;
} }
if (nDirEntries < MAXDIRENTRIES) if (nDirEntries < maxdirentries)
return 0; return 0;
} }
else if (mode == SCAN_PREV) else if (mode == SCAN_PREV)
@ -378,7 +380,7 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
iSelectedEntry = nDirEntries - 1; iSelectedEntry = nDirEntries - 1;
return 0; return 0;
} }
if (nDirEntries < MAXDIRENTRIES) if (nDirEntries < maxdirentries)
return 0; return 0;
} }
else if (mode == SCAN_PREV_PAGE) else if (mode == SCAN_PREV_PAGE)
@ -419,13 +421,13 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
|| (options & SCAN_SYSDIR && fil.fattrib & AM_DIR && (fil.fattrib & AM_SYS || (fil.fname[0] == '.' && fil.fname[1] == '.'))))) || (options & SCAN_SYSDIR && fil.fattrib & AM_DIR && (fil.fattrib & AM_SYS || (fil.fname[0] == '.' && fil.fname[1] == '.')))))
{ {
if (mode == SCAN_INIT) { // initial directory scan (first 8 entries) if (mode == SCAN_INIT) { // initial directory scan (first 8 entries)
if (nDirEntries < MAXDIRENTRIES) { if (nDirEntries < maxdirentries) {
//iprintf("fname=%s, altname=%s\n", fil.fname, fil.altname); //iprintf("fname=%s, altname=%s\n", fil.fname, fil.altname);
DirEntries[nDirEntries] = fil; DirEntries[nDirEntries] = fil;
nDirEntries++; nDirEntries++;
} else if (CompareDirEntries(&fil, &DirEntries[sort_table[MAXDIRENTRIES-1]]) < 0) {// compare new entry with the l } else if (CompareDirEntries(&fil, &DirEntries[sort_table[maxdirentries-1]]) < 0) {// compare new entry with the l
// replace the last entry with the new one if appropriate // replace the last entry with the new one if appropriate
DirEntries[sort_table[MAXDIRENTRIES-1]] = fil; DirEntries[sort_table[maxdirentries-1]] = fil;
} }
for (i = nDirEntries - 1; i > 0; i--) {// one pass bubble-sorting (table is already sorted, only the new item must be placed in order) for (i = nDirEntries - 1; i > 0; i--) {// one pass bubble-sorting (table is already sorted, only the new item must be placed in order)
if (CompareDirEntries(&DirEntries[sort_table[i]], &DirEntries[sort_table[i-1]])<0) // compare items if (CompareDirEntries(&DirEntries[sort_table[i]], &DirEntries[sort_table[i-1]])<0) // compare items
@ -440,7 +442,7 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
} else if (mode == SCAN_INIT_FIRST) { } else if (mode == SCAN_INIT_FIRST) {
// find a dir entry with given cluster number and store it in the buffer // find a dir entry with given cluster number and store it in the buffer
if (fil.fclust == iPreviousDirectory) { // directory entry found if (fil.fclust == iPreviousDirectory) { // directory entry found
for (i = 0; i< MAXDIRENTRIES; i++) for (i = 0; i< maxdirentries; i++)
sort_table[i] = i; // init sorting table sort_table[i] = i; // init sorting table
nDirEntries = 1; nDirEntries = 1;
@ -451,14 +453,14 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
break; break;
} }
} else if (mode == SCAN_INIT_NEXT) { } else if (mode == SCAN_INIT_NEXT) {
// scan the directory table and return next MAXDIRENTRIES-1 alphabetically sorted entries (first entry is in the buffer) // scan the directory table and return next maxdirentries-1 alphabetically sorted entries (first entry is in the buffer)
if (CompareDirEntries(&fil, &DirEntries[sort_table[0]]) > 0) {// compare new entry with the first one if (CompareDirEntries(&fil, &DirEntries[sort_table[0]]) > 0) {// compare new entry with the first one
if (nDirEntries < MAXDIRENTRIES) {// initial directory scan (first 8 entries) if (nDirEntries < maxdirentries) {// initial directory scan (first 8 entries)
DirEntries[nDirEntries] = fil; // add new entry at first empty slot in storage buffer DirEntries[nDirEntries] = fil; // add new entry at first empty slot in storage buffer
nDirEntries++; nDirEntries++;
} else { } else {
if (CompareDirEntries(&fil, &DirEntries[sort_table[MAXDIRENTRIES-1]]) < 0) {// compare new entry with the last already found if (CompareDirEntries(&fil, &DirEntries[sort_table[maxdirentries-1]]) < 0) {// compare new entry with the last already found
DirEntries[sort_table[MAXDIRENTRIES-1]] = fil; // replace the last entry with the new one if appropriate DirEntries[sort_table[maxdirentries-1]] = fil; // replace the last entry with the new one if appropriate
} }
} }
@ -473,31 +475,31 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
} }
} else if (mode == SCAN_NEXT) { } else if (mode == SCAN_NEXT) {
if (nNewEntries == 0) {// no entry higher than the last one has been found yet if (nNewEntries == 0) {// no entry higher than the last one has been found yet
if (CompareDirEntries(&fil, &DirEntries[sort_table[MAXDIRENTRIES-1]]) > 0) { // found entry higher than the if (CompareDirEntries(&fil, &DirEntries[sort_table[maxdirentries-1]]) > 0) { // found entry higher than the
nNewEntries++; nNewEntries++;
DirEntries[sort_table[0]] = fil; DirEntries[sort_table[0]] = fil;
// scroll entries' indices // scroll entries' indices
x = sort_table[0]; x = sort_table[0];
for (i = 0; i < MAXDIRENTRIES-1; i++) for (i = 0; i < maxdirentries-1; i++)
sort_table[i] = sort_table[i+1]; sort_table[i] = sort_table[i+1];
sort_table[MAXDIRENTRIES-1] = x; // last entry is the found one sort_table[maxdirentries-1] = x; // last entry is the found one
} }
} else {// higher entry already found but we need to check the remaining ones if any of them is lower then the already found one } else {// higher entry already found but we need to check the remaining ones if any of them is lower then the already found one
// check if the found entry is lower than the last one and higher than the last but one, if so then replace the last one with it // check if the found entry is lower than the last one and higher than the last but one, if so then replace the last one with it
if (CompareDirEntries(&fil, &DirEntries[sort_table[MAXDIRENTRIES-1]]) < 0) if (CompareDirEntries(&fil, &DirEntries[sort_table[maxdirentries-1]]) < 0)
if (CompareDirEntries(&fil, &DirEntries[sort_table[MAXDIRENTRIES-2]]) > 0) { if (CompareDirEntries(&fil, &DirEntries[sort_table[maxdirentries-2]]) > 0) {
DirEntries[sort_table[MAXDIRENTRIES-1]] = fil; DirEntries[sort_table[maxdirentries-1]] = fil;
} }
} }
} else if (mode == SCAN_PREV) { } else if (mode == SCAN_PREV) {
if (nNewEntries == 0) {// no entry lower than the first one has been found yet if (nNewEntries == 0) {// no entry lower than the first one has been found yet
if (CompareDirEntries(&fil, &DirEntries[sort_table[0]]) < 0) {// found entry lower than the first one if (CompareDirEntries(&fil, &DirEntries[sort_table[0]]) < 0) {// found entry lower than the first one
nNewEntries++; nNewEntries++;
if (nDirEntries < MAXDIRENTRIES) nDirEntries++; if (nDirEntries < maxdirentries) nDirEntries++;
DirEntries[sort_table[MAXDIRENTRIES-1]] = fil; DirEntries[sort_table[maxdirentries-1]] = fil;
// scroll entries' indices // scroll entries' indices
x = sort_table[MAXDIRENTRIES-1]; x = sort_table[maxdirentries-1];
for (i = MAXDIRENTRIES - 1; i > 0; i--) for (i = maxdirentries - 1; i > 0; i--)
sort_table[i] = sort_table[i-1]; sort_table[i] = sort_table[i-1];
sort_table[0] = x; // the first entry is the found one sort_table[0] = x; // the first entry is the found one
} }
@ -509,28 +511,28 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
} }
} }
} else if (mode == SCAN_NEXT_PAGE) { } else if (mode == SCAN_NEXT_PAGE) {
if (CompareDirEntries(&fil, &DirEntries[sort_table[MAXDIRENTRIES-1]]) > 0) { // compare with the last visible en if (CompareDirEntries(&fil, &DirEntries[sort_table[maxdirentries-1]]) > 0) { // compare with the last visible en
if (nNewEntries < MAXDIRENTRIES) {// initial directory scan (first 8 entries) if (nNewEntries < maxdirentries) {// initial directory scan (first 8 entries)
//iprintf("fname=%s, altname=%s\n", fil.fname, fil.altname); //iprintf("fname=%s, altname=%s\n", fil.fname, fil.altname);
t_DirEntries[nNewEntries] = fil; t_DirEntries[nNewEntries] = fil;
t_sort_table[nNewEntries] = nNewEntries; // init sorting table t_sort_table[nNewEntries] = nNewEntries; // init sorting table
nNewEntries++; nNewEntries++;
SortTempTable(-1); SortTempTable(-1);
} else if (CompareDirEntries(&fil, &t_DirEntries[t_sort_table[MAXDIRENTRIES-1]]) < 0) {// compare new entr } else if (CompareDirEntries(&fil, &t_DirEntries[t_sort_table[maxdirentries-1]]) < 0) {// compare new entr
t_DirEntries[t_sort_table[MAXDIRENTRIES-1]] = fil; t_DirEntries[t_sort_table[maxdirentries-1]] = fil;
SortTempTable(-1); SortTempTable(-1);
} }
} }
} else if (mode == SCAN_PREV_PAGE) { } else if (mode == SCAN_PREV_PAGE) {
if (CompareDirEntries(&fil, &DirEntries[sort_table[0]]) < 0) { // compare with the last visible en if (CompareDirEntries(&fil, &DirEntries[sort_table[0]]) < 0) { // compare with the last visible en
if (nNewEntries < MAXDIRENTRIES) {// initial directory scan (first 8 entries) if (nNewEntries < maxdirentries) {// initial directory scan (first 8 entries)
//iprintf("fname=%s, altname=%s\n", fil.fname, fil.altname); //iprintf("fname=%s, altname=%s\n", fil.fname, fil.altname);
t_DirEntries[nNewEntries] = fil; t_DirEntries[nNewEntries] = fil;
t_sort_table[nNewEntries] = nNewEntries; // init sorting table t_sort_table[nNewEntries] = nNewEntries; // init sorting table
nNewEntries++; nNewEntries++;
SortTempTable(1); SortTempTable(1);
} else if (CompareDirEntries(&fil, &t_DirEntries[t_sort_table[MAXDIRENTRIES-1]]) > 0) {// compare new entry } else if (CompareDirEntries(&fil, &t_DirEntries[t_sort_table[maxdirentries-1]]) > 0) {// compare new entry
t_DirEntries[t_sort_table[MAXDIRENTRIES-1]] = fil; t_DirEntries[t_sort_table[maxdirentries-1]] = fil;
SortTempTable(1); SortTempTable(1);
} }
} }
@ -543,13 +545,13 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
x = (CompareDirEntries(&fil, &DirEntries[sort_table[iSelectedEntry]]) > 0); // compare with the last visible entry x = (CompareDirEntries(&fil, &DirEntries[sort_table[iSelectedEntry]]) > 0); // compare with the last visible entry
if (x) { if (x) {
if (nNewEntries < MAXDIRENTRIES) {// initial directory scan (first 8 entries) if (nNewEntries < maxdirentries) {// initial directory scan (first 8 entries)
t_DirEntries[nNewEntries] = fil; t_DirEntries[nNewEntries] = fil;
t_sort_table[nNewEntries] = nNewEntries; // init sorting table t_sort_table[nNewEntries] = nNewEntries; // init sorting table
nNewEntries++; nNewEntries++;
SortTempTable(-1); SortTempTable(-1);
} else if (CompareDirEntries(&fil, &t_DirEntries[t_sort_table[MAXDIRENTRIES-1]]) < 0) { // compare new entry with the last already found } else if (CompareDirEntries(&fil, &t_DirEntries[t_sort_table[maxdirentries-1]]) < 0) { // compare new entry with the last already found
t_DirEntries[t_sort_table[MAXDIRENTRIES-1]] = fil; t_DirEntries[t_sort_table[maxdirentries-1]] = fil;
SortTempTable(-1); SortTempTable(-1);
} }
} }
@ -560,7 +562,7 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
if (nNewEntries) { if (nNewEntries) {
if (mode == SCAN_NEXT_PAGE) { if (mode == SCAN_NEXT_PAGE) {
unsigned char j = 8 - nNewEntries; // number of remaining old entries to scroll unsigned char j = maxdirentries - nNewEntries; // number of remaining old entries to scroll
for (i = 0; i < j; i++) { for (i = 0; i < j; i++) {
x = sort_table[i]; x = sort_table[i];
sort_table[i] = sort_table[i + nNewEntries]; sort_table[i] = sort_table[i + nNewEntries];
@ -572,7 +574,7 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
} }
} else if (mode == SCAN_PREV_PAGE) { // note: temporary buffer entries are in reverse order } else if (mode == SCAN_PREV_PAGE) { // note: temporary buffer entries are in reverse order
unsigned char j = nNewEntries - 1; unsigned char j = nNewEntries - 1;
for (i = 7; i > j; i--) { for (i = maxdirentries - 1; i > j; i--) {
x = sort_table[i]; x = sort_table[i];
sort_table[i] = sort_table[i - nNewEntries]; sort_table[i] = sort_table[i - nNewEntries];
sort_table[i - nNewEntries] = x; sort_table[i - nNewEntries] = x;
@ -582,8 +584,8 @@ char ScanDirectory(unsigned long mode, char *extension, unsigned char options) {
DirEntries[sort_table[j-i]] = t_DirEntries[t_sort_table[i]]; DirEntries[sort_table[j-i]] = t_DirEntries[t_sort_table[i]];
} }
nDirEntries += nNewEntries; nDirEntries += nNewEntries;
if (nDirEntries > MAXDIRENTRIES) if (nDirEntries > maxdirentries)
nDirEntries = MAXDIRENTRIES; nDirEntries = maxdirentries;
} else if ((mode >= '0' && mode <= '9') || (mode >= 'A' && mode <= 'Z')) { } else if ((mode >= '0' && mode <= '9') || (mode >= 'A' && mode <= 'Z')) {
if (tolower(t_DirEntries[t_sort_table[0]].fname[0]) == tolower(mode)) { if (tolower(t_DirEntries[t_sort_table[0]].fname[0]) == tolower(mode)) {
x = 1; // if we were looking for a file we couldn't find anything other x = 1; // if we were looking for a file we couldn't find anything other

View File

@ -5,7 +5,7 @@
#include "FatFs/ff.h" #include "FatFs/ff.h"
#define MAXDIRENTRIES 8 #define MAXDIRENTRIES 16
struct PartitionEntry struct PartitionEntry
{ {

View File

@ -236,7 +236,8 @@ static char GetMenuItem_8bit(uint8_t idx, char action, menu_item_t *item) {
if(action == MENU_ACT_SEL) { if(action == MENU_ACT_SEL) {
static char ext[13]; static char ext[13];
char iscue = 0; char iscue = 0;
selected_drive_slot = (p[0] == 'F') ? (menusub + 1) : 0; unsigned char firstline = OsdLines() <= 8 ? 0 : 2;
selected_drive_slot = (p[0] == 'F') ? (menusub - firstline + 1) : 0;
if (p[0]=='S' && (p[1]=='C' || (p[1] && p[1] != ',' && p[2] == 'C'))) { if (p[0]=='S' && (p[1]=='C' || (p[1] && p[1] != ',' && p[2] == 'C'))) {
// S[0-9]C - select CUE/ISO file // S[0-9]C - select CUE/ISO file
selected_drive_slot = 3; selected_drive_slot = 3;

128
menu.c
View File

@ -59,7 +59,7 @@ static uint8_t menu_last, scroll_down, scroll_up;
static uint8_t page_idx, last_page[4], last_menusub[4], last_menu_first[4], page_level; static uint8_t page_idx, last_page[4], last_menusub[4], last_menu_first[4], page_level;
static menu_item_t menu_item; static menu_item_t menu_item;
static menu_page_t menu_page; static menu_page_t menu_page;
static uint8_t menuidx[OSDNLINE]; static uint8_t menuidx[16];
const char *helptext; const char *helptext;
static const char *dialog_text; static const char *dialog_text;
@ -1004,6 +1004,8 @@ void HandleUI(void)
static long helptext_timer; static long helptext_timer;
static long page_timer; static long page_timer;
static char helpstate=0; static char helpstate=0;
int osdlines = OsdLines();
int firstline = osdlines <= 8 ? 0 : 2;
uint8_t keys[6] = {0,0,0,0,0,0}; uint8_t keys[6] = {0,0,0,0,0,0};
// get user control codes // get user control codes
@ -1106,7 +1108,7 @@ void HandleUI(void)
{ {
helptext_timer=GetTimer(FRAME_DELAY); helptext_timer=GetTimer(FRAME_DELAY);
if (menu_page.stdexit) if (menu_page.stdexit)
OsdWriteOffset(OSDNLINE-1,menu_page.stdexit == 1 ? STD_EXIT : menu_page.stdexit == 2 ? STD_SPACE_EXIT : STD_COMBO_EXIT,0,0,helpstate); OsdWriteOffset(osdlines-1,menu_page.stdexit == 1 ? STD_EXIT : menu_page.stdexit == 2 ? STD_SPACE_EXIT : STD_COMBO_EXIT,0,0,helpstate);
++helpstate; ++helpstate;
} }
} }
@ -1116,7 +1118,7 @@ void HandleUI(void)
++helpstate; ++helpstate;
} }
else else
ScrollText(OSDNLINE-1,helptext,0,0,0,0); ScrollText(osdlines-1,helptext,0,0,0,0);
} }
// Standardised menu up/down. // Standardised menu up/down.
@ -1214,37 +1216,49 @@ void HandleUI(void)
char idx, itemidx, valid, *item; char idx, itemidx, valid, *item;
menumask=0; menumask=0;
itemidx = menuidx[0]; itemidx = menuidx[0];
for(idx=0; idx<OSDNLINE; idx++) { for(idx=0; idx<osdlines; idx++) {
valid = 0; valid = 0;
item = ""; item = "";
menu_item.page = page_idx; menu_item.page = page_idx;
while(menu_item_callback(itemidx++, 0, &menu_item)) { if (idx >= firstline) {
menu_debugf("menu_ng: idx: %d, item: %d, '%s', stipple %d page %d\n",idx, itemidx-1, menu_item.item, menu_item.stipple, menu_item.page); while(menu_item_callback(itemidx++, 0, &menu_item)) {
if (menu_item.page == page_idx) { menu_debugf("menu_ng: idx: %d, item: %d, '%s', stipple %d page %d\n",idx, itemidx-1, menu_item.item, menu_item.stipple, menu_item.page);
valid = 1; if (menu_item.page == page_idx) {
if (menu_page.stdexit && idx == OSDNLINE-1) valid = 1;
if (menu_page.stdexit && idx == osdlines-1)
break;
menuidx[idx-firstline] = itemidx-1;
menu_last = idx-firstline;
if(menu_item.newpage) {
char l = 25-strlen(menu_item.item);
strcpy(s, menu_item.item);
while(l--) strcat(s, " ");
strcat(s,"\x16"); // right arrow
item = s;
} else {
item = menu_item.item;
}
if (menu_item.active) menumask |= 1<<idx;
break; break;
menuidx[idx] = itemidx-1;
menu_last = idx;
if(menu_item.newpage) {
char l = 25-strlen(menu_item.item);
strcpy(s, menu_item.item);
while(l--) strcat(s, " ");
strcat(s,"\x16"); // right arrow
item = s;
} else {
item = menu_item.item;
} }
if (menu_item.active) menumask |= 1<<idx; menu_item.page = page_idx;
break; }
} else {
if (idx == 0) {
uint8_t date[7];
menu_item.stipple = GetRTC((uint8_t*)&date);
siprintf(s, " %04d/%02d/%02d %02d:%02d:%02d %s", 1900+date[0], date[1], date[2], date[3], date[4], date[5], date[6] <= 7 ? days[date[6]-1] : "--------");
item = s;
if (!menu_page.timer) menu_page.timer = 1000;
} else {
item = "";
} }
menu_item.page = page_idx;
} }
if (menu_page.stdexit && idx == OSDNLINE-1) { if (menu_page.stdexit && idx == osdlines-1) {
switch(menu_page.stdexit) { switch(menu_page.stdexit) {
case 1: case 1:
item = STD_EXIT; item = STD_EXIT;
if (!valid) menumask |= 1<<(OSDNLINE-1); if (!valid) menumask |= 1<<(osdlines-1);
break; break;
case 2: case 2:
item = STD_SPACE_EXIT; item = STD_SPACE_EXIT;
@ -1259,7 +1273,7 @@ void HandleUI(void)
menu_item.stipple = 0; menu_item.stipple = 0;
} }
if (!(menumask & 1<<idx) && menusub == idx) menusub++; if (!(menumask & 1<<idx) && menusub == idx) menusub++;
if (!(helpstate && idx == OSDNLINE-1)) if (!(helpstate && idx == osdlines-1))
OsdWrite(idx, item, menusub == idx, menu_item.stipple); OsdWrite(idx, item, menusub == idx, menu_item.stipple);
} }
if (menu_page.timer) page_timer = GetTimer(menu_page.timer); if (menu_page.timer) page_timer = GetTimer(menu_page.timer);
@ -1281,17 +1295,17 @@ void HandleUI(void)
} }
} else if (menu_page.stdexit == MENU_STD_SPACE_EXIT) { } else if (menu_page.stdexit == MENU_STD_SPACE_EXIT) {
if (c==KEY_SPACE) stdexit = 1; if (c==KEY_SPACE) stdexit = 1;
} else if (menu || (menu_page.stdexit && select && menusub == OSDNLINE - 1)) { } else if (menu || (menu_page.stdexit && select && menusub == osdlines - 1)) {
stdexit = 1; stdexit = 1;
} }
if (c == KEY_PGDN) { if (c == KEY_PGDN) {
if (menusub < (OSDNLINE - 1 - (menu_page.stdexit?1:0))) { if (menusub < (osdlines - 1 - (menu_page.stdexit?1:0))) {
menusub = OSDNLINE - 1 - (menu_page.stdexit?1:0); menusub = osdlines - 1 - (menu_page.stdexit?1:0);
while((menumask & (1<<menusub)) == 0) menusub--; while((menumask & (1<<menusub)) == 0) menusub--;
menustate = parentstate; menustate = parentstate;
} else { } else {
scroll_down = OSDNLINE - (menu_page.stdexit?1:0); scroll_down = osdlines - (menu_page.stdexit?1:0);
} }
} }
@ -1303,8 +1317,8 @@ void HandleUI(void)
items++; items++;
if (!newidx) newidx = idx; // the next invisible item if (!newidx) newidx = idx; // the next invisible item
if (menu_item.active) { // any selectable? if (menu_item.active) { // any selectable?
menuidx[0] = items < (OSDNLINE - (menu_page.stdexit?1:0)) ? menuidx[items] : newidx; // then scroll down menuidx[0] = items < (osdlines - (menu_page.stdexit?1:0)) ? menuidx[items] : newidx; // then scroll down
menusub = OSDNLINE - 1 - (menu_page.stdexit?1:0); menusub = osdlines - 1 - (menu_page.stdexit?1:0);
if (!--scroll_down) break; if (!--scroll_down) break;
} }
} }
@ -1315,13 +1329,13 @@ void HandleUI(void)
} }
if (c == KEY_PGUP) { if (c == KEY_PGUP) {
if (menusub > 0) { if (menusub > firstline) {
menusub = 0; menusub = firstline;
while((menumask & (1<<menusub)) == 0 && menusub<OSDNLINE) menusub++; while((menumask & (1<<menusub)) == 0 && menusub<osdlines) menusub++;
if(menusub == OSDNLINE) menusub = 0; if(menusub == osdlines) menusub = firstline;
menustate = parentstate; menustate = parentstate;
} else { } else {
scroll_up = OSDNLINE - (menu_page.stdexit?1:0); scroll_up = osdlines - firstline - (menu_page.stdexit?1:0);
} }
} }
@ -1332,7 +1346,7 @@ void HandleUI(void)
while(menu_item_callback(idx, 0, &menu_item)) {// are more items there? while(menu_item_callback(idx, 0, &menu_item)) {// are more items there?
if (menu_item.page == page_idx && menu_item.active) { // any selectable? if (menu_item.page == page_idx && menu_item.active) { // any selectable?
menuidx[0] = idx; // then scroll up menuidx[0] = idx; // then scroll up
menusub = 0; menusub = firstline;
if (!--scroll_up) break; if (!--scroll_up) break;
} }
if (!idx) break; if (!idx) break;
@ -1367,7 +1381,7 @@ void HandleUI(void)
if (action != MENU_ACT_NONE) { if (action != MENU_ACT_NONE) {
menu_item.page = page_idx; menu_item.page = page_idx;
if (menu_item_callback(menuidx[menusub], action, &menu_item)) { if (menu_item_callback(menuidx[menusub-firstline], action, &menu_item)) {
if (menu_item.newpage) { if (menu_item.newpage) {
parentstate = MENU_NG; parentstate = MENU_NG;
last_menu_first[page_level] = menuidx[0]; last_menu_first[page_level] = menuidx[0];
@ -1396,32 +1410,26 @@ void HandleUI(void)
OsdSetTitle("About", 0); OsdSetTitle("About", 0);
menustate = MENU_8BIT_ABOUT2; menustate = MENU_8BIT_ABOUT2;
parentstate=MENU_8BIT_ABOUT1; parentstate=MENU_8BIT_ABOUT1;
OsdDrawLogo(0,0,1); for (int i=0; i<osdlines-2; i++) {
OsdDrawLogo(1,1,1); OsdDrawLogo(i,i,1);
OsdDrawLogo(2,2,1); }
OsdDrawLogo(3,3,1); OsdWrite(osdlines-3, "", 0, 0);
OsdDrawLogo(4,4,1); OsdWrite(osdlines-2, "", 0, 0);
OsdDrawLogo(6,6,1); OsdWrite(osdlines-1, STD_EXIT, menusub==0, 0);
OsdWrite(5, "", 0, 0);
OsdWrite(6, "", 0, 0);
OsdWrite(7, STD_EXIT, menusub==0, 0);
StarsInit(); StarsInit();
ScrollReset(); ScrollReset();
break; break;
case MENU_8BIT_ABOUT2: case MENU_8BIT_ABOUT2:
StarsUpdate(); StarsUpdate();
OsdDrawLogo(0,0,1); for (int i=0; i<osdlines-2; i++) {
OsdDrawLogo(1,1,1); if (i!=osdlines-3) OsdDrawLogo(i,i,1);
OsdDrawLogo(2,2,1); }
OsdDrawLogo(3,3,1); ScrollText(osdlines-3," MiST by Till Harbaum, based on Minimig by Dennis van Weeren and other projects. MiST hardware and software is distributed under the terms of the GNU General Public License version 3. MiST FPGA cores are the work of their respective authors under individual licensing.", 0, 0, 0, 0);
OsdDrawLogo(4,4,1);
OsdDrawLogo(6,6,1);
ScrollText(5," MiST by Till Harbaum, based on Minimig by Dennis van Weeren and other projects. MiST hardware and software is distributed under the terms of the GNU General Public License version 3. MiST FPGA cores are the work of their respective authors under individual licensing.", 0, 0, 0, 0);
// menu key closes menu // menu key closes menu
if (menu || select || left) { if (menu || select || left) {
menustate = MENU_NG; menustate = MENU_NG;
menusub = 6; menusub = 6+firstline;
} }
break; break;
/* /*
@ -1612,7 +1620,7 @@ void HandleUI(void)
break; break;
case MENU_FILE_SELECT_EXIT: case MENU_FILE_SELECT_EXIT:
menu_select_callback(menuidx[menusub], SelectedName); menu_select_callback(menuidx[menusub-firstline], SelectedName);
menustate = parentstate; menustate = parentstate;
break; break;
@ -1624,6 +1632,8 @@ void HandleUI(void)
const char *message = dialog_text; const char *message = dialog_text;
menumask = 0; menumask = 0;
parentstate = menustate; parentstate = menustate;
s[0]=0;
while (l<firstline) OsdWrite(l++, s, 0, 0);
do { do {
// line full or line break // line full or line break
@ -1636,7 +1646,7 @@ void HandleUI(void)
} }
} while(*message++); } while(*message++);
if(dialog_errorcode && (l < OSDNLINE)) { if(dialog_errorcode && (l < osdlines)) {
siprintf(s, " Code: #%d", dialog_errorcode); siprintf(s, " Code: #%d", dialog_errorcode);
OsdWrite(l++, s, 0,0); OsdWrite(l++, s, 0,0);
} }
@ -1653,7 +1663,7 @@ void HandleUI(void)
OsdWrite(l++, " no", menusub == 1,0); OsdWrite(l++, " no", menusub == 1,0);
} }
} }
while(l < OSDNLINE) OsdWrite(l++, "", 0,0); while(l < osdlines) OsdWrite(l++, "", 0,0);
menustate = MENU_DIALOG2; menustate = MENU_DIALOG2;
} }
break; break;
@ -1786,7 +1796,7 @@ static void PrintDirectory(void)
ScrollReset(); ScrollReset();
for (i = 0; i < OSDNLINE; i++) for (i = 0; i < OsdLines(); i++)
{ {
memset(s, ' ', 32); // clear line buffer memset(s, ' ', 32); // clear line buffer
if (i < nDirEntries) if (i < nDirEntries)

55
osd.c
View File

@ -85,11 +85,12 @@ static int quickrand()
void StarsInit() void StarsInit()
{ {
int i; int i;
int lines=OsdLines()*8 - 10;
for(i=0;i<64;++i) for(i=0;i<64;++i)
{ {
stars[i].x=(quickrand()%228)<<4; // X centre stars[i].x=(quickrand()%228)<<4; // X centre
stars[i].y=(quickrand()%56)<<4; // Y centre stars[i].y=(quickrand()%(lines))<<4; // Y centre
stars[i].dx=-(quickrand()&7)-3; stars[i].dx=-(quickrand()&7)-3;
stars[i].dy=0; stars[i].dy=0;
} }
} }
@ -97,15 +98,16 @@ void StarsInit()
void StarsUpdate() void StarsUpdate()
{ {
int i; int i;
int lines=OsdLines()*8 - 10;
for(i=0;i<64;++i) for(i=0;i<64;++i)
{ {
stars[i].x+=stars[i].dx; stars[i].x+=stars[i].dx;
stars[i].y+=stars[i].dy; stars[i].y+=stars[i].dy;
if((stars[i].x<0)||(stars[i].x>(228<<4)) || if((stars[i].x<0)||(stars[i].x>(228<<4)) ||
(stars[i].y<0)||(stars[i].y>(56<<4))) (stars[i].y<0)||(stars[i].y>(lines<<4)))
{ {
stars[i].x=228<<4; stars[i].x=228<<4;
stars[i].y=(quickrand()%56)<<4; stars[i].y=(quickrand()%lines)<<4;
stars[i].dx=-(quickrand()&7)-3; stars[i].dx=-(quickrand()&7)-3;
stars[i].dy=0; stars[i].dy=0;
} }
@ -124,7 +126,7 @@ static unsigned long scroll_timer=0; // file/dir name scrolling timer
extern char s[FF_LFN_BUF + 1]; extern char s[FF_LFN_BUF + 1];
static int arrow; static int arrow;
static unsigned char titlebuffer[64]; static unsigned char titlebuffer[128];
static void rotatechar(unsigned char *in,unsigned char *out) static void rotatechar(unsigned char *in,unsigned char *out)
{ {
@ -148,12 +150,13 @@ void OsdSetTitle(char *s,int a)
// Compose the title, condensing character gaps // Compose the title, condensing character gaps
arrow=a; arrow=a;
char zeros=0; char zeros=0;
char i=0,j=0; int i=0,j=0;
char outp=0; int outp=0;
int bufsize = 8*OsdLines();
while(1) while(1)
{ {
int c=s[i++]; int c=s[i++];
if(c && (outp<64)) if(c && (outp<bufsize))
{ {
unsigned char *p = &charfont[c][0]; unsigned char *p = &charfont[c][0];
for(j=0;j<8;++j) for(j=0;j<8;++j)
@ -169,21 +172,21 @@ void OsdSetTitle(char *s,int a)
titlebuffer[outp++]=0; titlebuffer[outp++]=0;
zeros=1; zeros=1;
} }
if(outp>63) if(outp>(bufsize-1))
break; break;
} }
} }
else else
break; break;
} }
for(i=outp;i<64;++i) for(i=outp;i<bufsize;++i)
{ {
titlebuffer[i]=0; titlebuffer[i]=0;
} }
// Now centre it: // Now centre it:
int c=(63-outp)/2; int c=(bufsize-1-outp)/2;
for(i=(63-c);i>=0;--i) for(i=(bufsize-1-c);i>=0;--i)
{ {
titlebuffer[i+c]=titlebuffer[i]; titlebuffer[i+c]=titlebuffer[i];
} }
@ -191,7 +194,7 @@ void OsdSetTitle(char *s,int a)
titlebuffer[i]=0; titlebuffer[i]=0;
// Finally rotate it. // Finally rotate it.
for(i=0;i<64;i+=8) for(i=0;i<bufsize;i+=8)
{ {
unsigned char tmp[8]; unsigned char tmp[8];
rotatechar(&titlebuffer[i],tmp); rotatechar(&titlebuffer[i],tmp);
@ -202,6 +205,14 @@ void OsdSetTitle(char *s,int a)
} }
} }
char OsdLines()
{
if (user_io_core_type() == CORE_TYPE_8BIT && (user_io_get_core_features() & FEAT_BIGOSD))
return 16;
else
return 8;
}
void OsdWrite(unsigned char n, char *s, unsigned char invert, unsigned char stipple) void OsdWrite(unsigned char n, char *s, unsigned char invert, unsigned char stipple)
{ {
OsdWriteOffset(n, s, invert, stipple, 0); OsdWriteOffset(n, s, invert, stipple, 0);
@ -212,7 +223,7 @@ void OsdWriteOffset(unsigned char n, char *s, unsigned char invert, unsigned cha
{ {
char *text = s; char *text = s;
char arrowline[31]; char arrowline[31];
if(n==OSDNLINE-1 && arrow) { if(n==OsdLines()-1 && arrow) {
text = arrowline; text = arrowline;
memset(arrowline, 32, sizeof(arrowline)); memset(arrowline, 32, sizeof(arrowline));
memcpy(&arrowline, s, strnlen(s, sizeof(arrowline))); memcpy(&arrowline, s, strnlen(s, sizeof(arrowline)));
@ -241,10 +252,14 @@ void OsdDrawLogo(unsigned char n, char row,char superimpose) {
else else
spi_osd_cmd32_cont(OSD_CMD_OSD_WR, n); spi_osd_cmd32_cont(OSD_CMD_OSD_WR, n);
const unsigned char *lp=logodata[row]; const unsigned char *lp;
int bytes=sizeof(logodata[0]); int bytes=sizeof(logodata[0]);
if(row>=(sizeof(logodata)/bytes)) int logoheight = (sizeof(logodata)/bytes);
int startrow = (OsdLines()-2-logoheight)/2;
if(row>=startrow+logoheight || row<startrow)
lp=0; lp=0;
else
lp=logodata[row-startrow];
i = 0; i = 0;
// send all characters in string to OSD // send all characters in string to OSD
@ -258,7 +273,7 @@ void OsdDrawLogo(unsigned char n, char row,char superimpose) {
while (bytes) { while (bytes) {
if(i==0) { // Render sidestripe if(i==0) { // Render sidestripe
p = &titlebuffer[(7-n)*8]; p = &titlebuffer[(OsdLines()-1-n)*8];
spi16(0xffff); spi16(0xffff);
for(j=0;j<8;j++) spi_n(255^*p++, 2); for(j=0;j<8;j++) spi_n(255^*p++, 2);
spi16(0xffff); spi16(0xffff);
@ -280,7 +295,7 @@ void OsdDrawLogo(unsigned char n, char row,char superimpose) {
while (bytes) { while (bytes) {
if(i==0) { // Render sidestripe if(i==0) { // Render sidestripe
unsigned char b; unsigned char b;
p = &titlebuffer[(7-n)*8]; p = &titlebuffer[(OsdLines()-1-n)*8];
spi16(0xffff); spi16(0xffff);
for(b=0;b<8;b++) spi_n(255^*p++, 2); for(b=0;b<8;b++) spi_n(255^*p++, 2);
spi16(0xffff); spi16(0xffff);
@ -336,7 +351,7 @@ void OsdPrintText(unsigned char line, char *text, unsigned long start, unsigned
if(invert) if(invert)
invert=0xff; invert=0xff;
p = &titlebuffer[(7-line)*8]; p = &titlebuffer[(OsdLines()-1-line)*8];
if(start>2) { if(start>2) {
spi16(0xffff); spi16(0xffff);
start-=2; start-=2;
@ -400,7 +415,7 @@ void OsdClear(void)
spi_osd_cmd32_cont(OSD_CMD_OSD_WR, 0x18); spi_osd_cmd32_cont(OSD_CMD_OSD_WR, 0x18);
// clear buffer // clear buffer
spi_n(0x00, OSDLINELEN * OSDNLINE); spi_n(0x00, OSDLINELEN * OsdLines());
// deselect OSD SPI device // deselect OSD SPI device
DisableOsd(); DisableOsd();

2
osd.h
View File

@ -10,7 +10,6 @@
#define OSDCTRLLEFT 0x20 /*OSD left control*/ #define OSDCTRLLEFT 0x20 /*OSD left control*/
// some constants // some constants
#define OSDNLINE 8 // number of lines of OSD
#define OSDLINELEN 256 // single line length in bytes #define OSDLINELEN 256 // single line length in bytes
// ---- old Minimig v1 constants ------- // ---- old Minimig v1 constants -------
@ -134,6 +133,7 @@ void ScrollText(char n, const char *str, int len, int max_len, unsigned char inv
void ScrollReset(); void ScrollReset();
void StarsInit(); void StarsInit();
void StarsUpdate(); void StarsUpdate();
char OsdLines();
void OsdKeySet(unsigned char); void OsdKeySet(unsigned char);
unsigned char OsdKeyGet(); unsigned char OsdKeyGet();

View File

@ -96,6 +96,7 @@
#define FEAT_IDE3_CDROM 0x0800 #define FEAT_IDE3_CDROM 0x0800
#define FEAT_IDE_MASK 0x0FF0 #define FEAT_IDE_MASK 0x0FF0
#define FEAT_PS2REP 0x1000 // typematic repeat by default #define FEAT_PS2REP 0x1000 // typematic repeat by default
#define FEAT_BIGOSD 0x2000 // 16 line tall OSD
#define JOY_RIGHT 0x01 #define JOY_RIGHT 0x01
#define JOY_LEFT 0x02 #define JOY_LEFT 0x02