Add cheat engine.
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
<ClCompile Include="brightness.cpp" />
|
||||
<ClCompile Include="cfg.cpp" />
|
||||
<ClCompile Include="charrom.cpp" />
|
||||
<ClCompile Include="cheats.cpp" />
|
||||
<ClCompile Include="DiskImage.cpp" />
|
||||
<ClCompile Include="file_io.cpp" />
|
||||
<ClCompile Include="fpga_io.cpp" />
|
||||
@@ -90,6 +91,7 @@
|
||||
<ClInclude Include="brightness.h" />
|
||||
<ClInclude Include="cfg.h" />
|
||||
<ClInclude Include="charrom.h" />
|
||||
<ClInclude Include="cheats.h" />
|
||||
<ClInclude Include="debug.h" />
|
||||
<ClInclude Include="DiskImage.h" />
|
||||
<ClInclude Include="file_io.h" />
|
||||
|
||||
@@ -133,6 +133,9 @@
|
||||
<ClCompile Include="charrom.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="cheats.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="battery.h">
|
||||
@@ -267,5 +270,8 @@
|
||||
<ClInclude Include="bootcore.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="cheats.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
322
cheats.cpp
Normal file
322
cheats.cpp
Normal file
@@ -0,0 +1,322 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "hardware.h"
|
||||
#include "file_io.h"
|
||||
#include "user_io.h"
|
||||
#include "fpga_io.h"
|
||||
#include "miniz_zip.h"
|
||||
#include "osd.h"
|
||||
#include "cheats.h"
|
||||
|
||||
struct cheat_rec_t
|
||||
{
|
||||
char enabled;
|
||||
char name[256];
|
||||
};
|
||||
|
||||
typedef std::vector<cheat_rec_t> CheatVector;
|
||||
static CheatVector cheats;
|
||||
|
||||
static int iSelectedEntry = 0;
|
||||
static int iFirstEntry = 0;
|
||||
|
||||
struct CheatComp
|
||||
{
|
||||
bool operator()(const cheat_rec_t& ce1, const cheat_rec_t& ce2)
|
||||
{
|
||||
int len1 = strlen(ce1.name);
|
||||
int len2 = strlen(ce2.name);
|
||||
|
||||
int len = (len1 < len2) ? len1 : len2;
|
||||
int ret = strncasecmp(ce1.name, ce2.name, len);
|
||||
if (!ret)
|
||||
{
|
||||
return len1 < len2;
|
||||
}
|
||||
|
||||
return ret < 0;
|
||||
}
|
||||
};
|
||||
|
||||
static char cheat_zip[1024] = {};
|
||||
|
||||
void cheats_init(char *rom_path)
|
||||
{
|
||||
cheats.clear();
|
||||
cheat_zip[0] = 0;
|
||||
|
||||
if (!strcasestr(rom_path, ".zip"))
|
||||
{
|
||||
sprintf(cheat_zip, "%s/%s", getRootDir(), rom_path);
|
||||
char *p = strrchr(cheat_zip, '.');
|
||||
if (p) *p = 0;
|
||||
strcat(cheat_zip, ".zip");
|
||||
}
|
||||
|
||||
mz_zip_archive _z = {};
|
||||
if (!mz_zip_reader_init_file(&_z, cheat_zip, 0))
|
||||
{
|
||||
memset(&_z, 0, sizeof(_z));
|
||||
|
||||
char *rom_name = strrchr(rom_path, '/');
|
||||
if (!rom_name) return;
|
||||
|
||||
sprintf(cheat_zip, "%s/cheats/%s%s", getRootDir(), HomeDir, rom_name);
|
||||
char *p = strrchr(cheat_zip, '.');
|
||||
if (p) *p = 0;
|
||||
strcat(cheat_zip, ".zip");
|
||||
|
||||
if (!mz_zip_reader_init_file(&_z, cheat_zip, 0))
|
||||
{
|
||||
printf("no cheat file %s\n", cheat_zip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mz_zip_archive *z = new mz_zip_archive(_z);
|
||||
for (size_t i = 0; i < mz_zip_reader_get_num_files(z); i++)
|
||||
{
|
||||
cheat_rec_t ch = {};
|
||||
mz_zip_reader_get_filename(z, i, ch.name, sizeof(ch.name));
|
||||
|
||||
if (mz_zip_reader_is_file_a_directory(z, i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cheats.push_back(ch);
|
||||
}
|
||||
|
||||
mz_zip_reader_end(z);
|
||||
delete z;
|
||||
|
||||
std::sort(cheats.begin(), cheats.end(), CheatComp());
|
||||
|
||||
printf("cheats: %d\n", cheats_available());
|
||||
cheats_scan(SCANF_INIT);
|
||||
}
|
||||
|
||||
int cheats_available()
|
||||
{
|
||||
return cheats.size();
|
||||
}
|
||||
|
||||
void cheats_scan(int mode)
|
||||
{
|
||||
if (mode == SCANF_INIT)
|
||||
{
|
||||
iFirstEntry = 0;
|
||||
iSelectedEntry = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!cheats_available()) return;
|
||||
|
||||
if (mode == SCANF_END)
|
||||
{
|
||||
iSelectedEntry = cheats_available() - 1;
|
||||
iFirstEntry = iSelectedEntry - OsdGetSize() + 1;
|
||||
if (iFirstEntry < 0) iFirstEntry = 0;
|
||||
}
|
||||
else if (mode == SCANF_NEXT)
|
||||
{
|
||||
if (iSelectedEntry + 1 < cheats_available()) // scroll within visible items
|
||||
{
|
||||
iSelectedEntry++;
|
||||
if (iSelectedEntry > iFirstEntry + OsdGetSize() - 1) iFirstEntry = iSelectedEntry - OsdGetSize() + 1;
|
||||
}
|
||||
}
|
||||
else if (mode == SCANF_PREV)
|
||||
{
|
||||
if (iSelectedEntry > 0) // scroll within visible items
|
||||
{
|
||||
iSelectedEntry--;
|
||||
if (iSelectedEntry < iFirstEntry) iFirstEntry = iSelectedEntry;
|
||||
}
|
||||
}
|
||||
else if (mode == SCANF_NEXT_PAGE)
|
||||
{
|
||||
if (iSelectedEntry < iFirstEntry + OsdGetSize() - 1)
|
||||
{
|
||||
iSelectedEntry = iFirstEntry + OsdGetSize() - 1;
|
||||
if (iSelectedEntry >= cheats_available()) iSelectedEntry = cheats_available() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
iSelectedEntry += OsdGetSize();
|
||||
iFirstEntry += OsdGetSize();
|
||||
if (iSelectedEntry >= cheats_available())
|
||||
{
|
||||
iSelectedEntry = cheats_available() - 1;
|
||||
iFirstEntry = iSelectedEntry - OsdGetSize() + 1;
|
||||
if (iFirstEntry < 0) iFirstEntry = 0;
|
||||
}
|
||||
else if (iFirstEntry + OsdGetSize() > cheats_available())
|
||||
{
|
||||
iFirstEntry = cheats_available() - OsdGetSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mode == SCANF_PREV_PAGE)
|
||||
{
|
||||
if (iSelectedEntry != iFirstEntry)
|
||||
{
|
||||
iSelectedEntry = iFirstEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
iFirstEntry -= OsdGetSize();
|
||||
if (iFirstEntry < 0) iFirstEntry = 0;
|
||||
iSelectedEntry = iFirstEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cheats_scroll_name()
|
||||
{
|
||||
// this function is called periodically when file selection window is displayed
|
||||
// it checks if predefined period of time has elapsed and scrolls the name if necessary
|
||||
int len;
|
||||
int max_len;
|
||||
static char name[256 + 4];
|
||||
|
||||
name[0] = 32;
|
||||
name[1] = cheats[iSelectedEntry].enabled ? 0x1a : 0x1b;
|
||||
name[2] = 32;
|
||||
strcpy(name + 3, cheats[iSelectedEntry].name);
|
||||
|
||||
len = strlen(name); // get name length
|
||||
if (len > 3 && !strncasecmp(name + len - 3, ".gg", 3)) len -= 3;
|
||||
|
||||
max_len = 30;
|
||||
ScrollText(iSelectedEntry - iFirstEntry, name, 3, len, max_len, 1);
|
||||
}
|
||||
|
||||
void cheats_print()
|
||||
{
|
||||
int k;
|
||||
int len;
|
||||
|
||||
static char s[256+4];
|
||||
|
||||
ScrollReset();
|
||||
|
||||
for (int i = 0; i < OsdGetSize(); i++)
|
||||
{
|
||||
char leftchar = 0;
|
||||
if (i < cheats_available())
|
||||
{
|
||||
k = iFirstEntry + i;
|
||||
|
||||
s[0] = 32;
|
||||
s[1] = cheats[k].enabled ? 0x1a : 0x1b;
|
||||
s[2] = 32;
|
||||
strcpy(s + 3, cheats[k].name);
|
||||
|
||||
len = strlen(s); // get name length
|
||||
if (len > 3 && !strncasecmp(s + len - 3, ".gg", 3)) len -= 3;
|
||||
s[len] = 0;
|
||||
|
||||
if (len > 28)
|
||||
{
|
||||
len = 27; // trim display length if longer than 30 characters
|
||||
s[28] = 22;
|
||||
}
|
||||
|
||||
s[29] = 0;
|
||||
|
||||
if (!i && k) leftchar = 17;
|
||||
if ((i == OsdGetSize() - 1) && (k < cheats_available() - 1)) leftchar = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(s, ' ', 32);
|
||||
}
|
||||
|
||||
OsdWriteOffset(i, s, i == (iSelectedEntry - iFirstEntry), 0, 0, leftchar);
|
||||
}
|
||||
}
|
||||
|
||||
#define CHEAT_SIZE (128*16) // 128 codes max
|
||||
|
||||
static void cheats_send()
|
||||
{
|
||||
static char filename[1024];
|
||||
static uint8_t buff[CHEAT_SIZE];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < cheats_available(); i++)
|
||||
{
|
||||
fileTYPE f = {};
|
||||
if (cheats[i].enabled)
|
||||
{
|
||||
sprintf(filename, "%s/%s", cheat_zip, cheats[i].name);
|
||||
if (FileOpen(&f, filename))
|
||||
{
|
||||
int len = f.size;
|
||||
if (!len || (len & 15))
|
||||
{
|
||||
printf("Cheat file %s has incorrect length %d -> skipping.", filename, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len + pos > CHEAT_SIZE)
|
||||
{
|
||||
len = CHEAT_SIZE - pos;
|
||||
}
|
||||
|
||||
if (FileReadAdv(&f, buff + pos, len) == len)
|
||||
{
|
||||
pos += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot read cheat file %s.", filename);
|
||||
}
|
||||
}
|
||||
FileClose(&f);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Cannot open cheat file %s.", filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (pos >= CHEAT_SIZE) break;
|
||||
}
|
||||
|
||||
printf("Cheat codes: %d\n", pos/16);
|
||||
|
||||
user_io_set_index(255);
|
||||
|
||||
// prepare transmission
|
||||
EnableFpga();
|
||||
spi8(UIO_FILE_TX);
|
||||
spi8(0xff);
|
||||
DisableFpga();
|
||||
|
||||
EnableFpga();
|
||||
spi8(UIO_FILE_TX_DAT);
|
||||
spi_write(buff, pos ? pos : 2, fpga_get_fio_size());
|
||||
DisableFpga();
|
||||
|
||||
// signal end of transmission
|
||||
EnableFpga();
|
||||
spi8(UIO_FILE_TX);
|
||||
spi8(0x00);
|
||||
DisableFpga();
|
||||
}
|
||||
|
||||
void cheats_toggle()
|
||||
{
|
||||
cheats[iSelectedEntry].enabled = !cheats[iSelectedEntry].enabled;
|
||||
cheats_send();
|
||||
}
|
||||
12
cheats.h
Normal file
12
cheats.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef CHEATS_H
|
||||
#define CHEATS_H
|
||||
|
||||
void cheats_init(char *rom_path);
|
||||
int cheats_available();
|
||||
void cheats_scan(int mode);
|
||||
void cheats_scroll_name();
|
||||
void cheats_print();
|
||||
void cheats_toggle();
|
||||
|
||||
|
||||
#endif
|
||||
@@ -33,8 +33,8 @@ typedef std::vector<dirent> DirentVector;
|
||||
static const size_t YieldIterations = 128;
|
||||
|
||||
DirentVector DirItem;
|
||||
int iSelectedEntry = 0; // selected entry index
|
||||
int iFirstEntry = 0;
|
||||
static int iSelectedEntry = 0; // selected entry index
|
||||
static int iFirstEntry = 0;
|
||||
|
||||
static char full_path[2100];
|
||||
|
||||
|
||||
103
menu.cpp
103
menu.cpp
@@ -48,6 +48,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "input.h"
|
||||
#include "battery.h"
|
||||
#include "bootcore.h"
|
||||
#include "cheats.h"
|
||||
|
||||
#include "support.h"
|
||||
|
||||
@@ -110,6 +111,8 @@ enum MENU
|
||||
MENU_BTPAIR,
|
||||
MENU_WMPAIR,
|
||||
MENU_WMPAIR1,
|
||||
MENU_CHEATS1,
|
||||
MENU_CHEATS2,
|
||||
|
||||
// Mist/atari specific pages
|
||||
MENU_MIST_MAIN1,
|
||||
@@ -761,6 +764,7 @@ void HandleUI(void)
|
||||
static char drive_num = 0;
|
||||
static char flag;
|
||||
static int cr = 0;
|
||||
static uint32_t cheatsub = 0;
|
||||
|
||||
static char cp_MenuCancel;
|
||||
|
||||
@@ -1160,6 +1164,27 @@ void HandleUI(void)
|
||||
selentry++;
|
||||
}
|
||||
|
||||
// check for 'C'heats
|
||||
if (p && (p[0] == 'C'))
|
||||
{
|
||||
substrcpy(s, p, 1);
|
||||
if (strlen(s))
|
||||
{
|
||||
strcpy(s, " ");
|
||||
substrcpy(s + 1, p, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(s, " Cheats");
|
||||
}
|
||||
MenuWrite(entry, s, menusub == selentry, !cheats_available());
|
||||
|
||||
// add bit in menu mask
|
||||
menumask = (menumask << 1) | 1;
|
||||
entry++;
|
||||
selentry++;
|
||||
}
|
||||
|
||||
// check for 'T'oggle and 'R'eset (toggle and then close menu) strings
|
||||
if (p && ((p[0] == 'T') || (p[0] == 'R')))
|
||||
{
|
||||
@@ -1306,7 +1331,13 @@ void HandleUI(void)
|
||||
entry++;
|
||||
}
|
||||
|
||||
if (p[0] == 'F')
|
||||
if (p[0] == 'C' && cheats_available())
|
||||
{
|
||||
menustate = MENU_CHEATS1;
|
||||
cheatsub = menusub;
|
||||
menusub = 0;
|
||||
}
|
||||
else if (p[0] == 'F')
|
||||
{
|
||||
opensave = (p[1] == 'S');
|
||||
substrcpy(ext, p, 1);
|
||||
@@ -1363,7 +1394,6 @@ void HandleUI(void)
|
||||
menustate = MENU_8BIT_MAIN1;
|
||||
if (p[0] == 'R') menustate = MENU_NONE1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1382,6 +1412,7 @@ void HandleUI(void)
|
||||
case MENU_8BIT_MAIN_FILE_SELECTED:
|
||||
printf("File selected: %s\n", SelectedPath);
|
||||
user_io_file_tx(SelectedPath, user_io_ext_idx(SelectedPath, fs_pFileExt) << 6 | (menusub + 1), opensave);
|
||||
cheats_init(SelectedPath);
|
||||
menustate = MENU_NONE1;
|
||||
break;
|
||||
|
||||
@@ -2900,6 +2931,72 @@ void HandleUI(void)
|
||||
|
||||
break;
|
||||
|
||||
/******************************************************************/
|
||||
/* cheats menu */
|
||||
/******************************************************************/
|
||||
case MENU_CHEATS1:
|
||||
helptext = helptexts[HELPTEXT_NONE];
|
||||
OsdSetTitle("Cheats", 0);
|
||||
cheats_print();
|
||||
menustate = MENU_CHEATS2;
|
||||
parentstate = menustate;
|
||||
break;
|
||||
|
||||
case MENU_CHEATS2:
|
||||
menumask = 0;
|
||||
|
||||
if (menu)
|
||||
{
|
||||
menustate = MENU_8BIT_MAIN1;
|
||||
menusub = cheatsub;
|
||||
break;
|
||||
}
|
||||
|
||||
cheats_scroll_name();
|
||||
|
||||
if (c == KEY_HOME)
|
||||
{
|
||||
cheats_scan(SCANF_INIT);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (c == KEY_END)
|
||||
{
|
||||
cheats_scan(SCANF_END);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if ((c == KEY_PAGEUP) || (c == KEY_LEFT))
|
||||
{
|
||||
cheats_scan(SCANF_PREV_PAGE);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if ((c == KEY_PAGEDOWN) || (c == KEY_RIGHT))
|
||||
{
|
||||
cheats_scan(SCANF_NEXT_PAGE);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (down) // scroll down one entry
|
||||
{
|
||||
cheats_scan(SCANF_NEXT);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (up) // scroll up one entry
|
||||
{
|
||||
cheats_scan(SCANF_PREV);
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
|
||||
if (select)
|
||||
{
|
||||
cheats_toggle();
|
||||
menustate = MENU_CHEATS1;
|
||||
}
|
||||
break;
|
||||
|
||||
/******************************************************************/
|
||||
/* reset menu */
|
||||
/******************************************************************/
|
||||
@@ -3967,7 +4064,7 @@ void ScrollLongName(void)
|
||||
if (flist_SelectedItem()->d_type == DT_DIR)
|
||||
max_len = 25; // number of directory name characters to display
|
||||
|
||||
ScrollText(flist_iSelectedEntry()-flist_iFirstEntry(), flist_SelectedItem()->d_name, 2, len, max_len, 1);
|
||||
ScrollText(flist_iSelectedEntry()-flist_iFirstEntry(), flist_SelectedItem()->d_name, 0, len, max_len, 1);
|
||||
}
|
||||
|
||||
void PrintFileName(char *name, int row, int maxinv)
|
||||
|
||||
51
osd.cpp
51
osd.cpp
@@ -397,7 +397,7 @@ void OsdDrawLogo(int row)
|
||||
}
|
||||
|
||||
// write a null-terminated string <s> to the OSD buffer starting at line <n>
|
||||
void OSD_PrintText(unsigned char line, const char *text, unsigned long start, unsigned long width, unsigned long offset, unsigned char invert)
|
||||
void OSD_PrintText(unsigned char line, const char *hdr, const char *text, unsigned long start, unsigned long width, unsigned long offset, unsigned char invert)
|
||||
{
|
||||
// line : OSD line number (0-7)
|
||||
// text : pointer to null-terminated string
|
||||
@@ -419,45 +419,53 @@ void OSD_PrintText(unsigned char line, const char *text, unsigned long start, un
|
||||
invert = 0xff;
|
||||
|
||||
p = &titlebuffer[(osd_size - 1 - line) * 8];
|
||||
if (start>2) {
|
||||
if (start>2)
|
||||
{
|
||||
spi16(0xffff);
|
||||
start -= 2;
|
||||
}
|
||||
|
||||
i = start>16 ? 16 : start;
|
||||
for (j = 0; j<(i / 2); ++j)
|
||||
spi_n(255 ^ *p++, 2);
|
||||
for (j = 0; j<(i / 2); ++j) spi_n(255 ^ *p++, 2);
|
||||
|
||||
if (i & 1)
|
||||
spi8(255 ^ *p);
|
||||
if (i & 1) spi8(255 ^ *p);
|
||||
start -= i;
|
||||
|
||||
if (start>2) {
|
||||
if (start>2)
|
||||
{
|
||||
spi16(0xffff);
|
||||
start -= 2;
|
||||
}
|
||||
|
||||
while (start--)
|
||||
spi8(0x00);
|
||||
while (start--) spi8(0x00);
|
||||
|
||||
if (offset) {
|
||||
while(*hdr)
|
||||
{
|
||||
width -= 8;
|
||||
p = charfont[(uint)(*hdr++)];
|
||||
for (int i=0; i < 8; i++) spi8(*p++^invert);
|
||||
}
|
||||
|
||||
if (offset)
|
||||
{
|
||||
width -= 8 - offset;
|
||||
p = &charfont[(uint)(*text++)][offset];
|
||||
for (; offset < 8; offset++)
|
||||
spi8(*p++^invert);
|
||||
}
|
||||
|
||||
while (width > 8) {
|
||||
while (width > 8)
|
||||
{
|
||||
unsigned char b;
|
||||
p = &charfont[(uint)(*text++)][0];
|
||||
for (b = 0; b<8; b++) spi8(*p++^invert);
|
||||
width -= 8;
|
||||
}
|
||||
|
||||
if (width) {
|
||||
if (width)
|
||||
{
|
||||
p = &charfont[(uint)(*text++)][0];
|
||||
while (width--)
|
||||
spi8(*p++^invert);
|
||||
while (width--) spi8(*p++^invert);
|
||||
}
|
||||
|
||||
DisableOsd();
|
||||
@@ -640,12 +648,21 @@ void ScrollText(char n, const char *str, int off, int len, int max_len, unsigned
|
||||
|
||||
#define BLANKSPACE 10 // number of spaces between the end and start of repeated name
|
||||
|
||||
char s[40];
|
||||
char s[40], hdr[40];
|
||||
long offset;
|
||||
if (!max_len) max_len = 30;
|
||||
|
||||
if (str && str[0] && CheckTimer(scroll_timer)) // scroll if long name and timer delay elapsed
|
||||
{
|
||||
hdr[0] = 0;
|
||||
if (off)
|
||||
{
|
||||
strncpy(hdr, str, off);
|
||||
hdr[off] = 0;
|
||||
str += off;
|
||||
if (len > off) len -= off;
|
||||
}
|
||||
|
||||
scroll_timer = GetTimer(SCROLL_DELAY2); // reset scroll timer to repeat delay
|
||||
|
||||
scroll_offset++; // increase scroll position (1 pixel unit)
|
||||
@@ -653,7 +670,7 @@ void ScrollText(char n, const char *str, int off, int len, int max_len, unsigned
|
||||
|
||||
if (!len) len = strlen(str); // get name length
|
||||
|
||||
if (off+len > max_len) // scroll name if longer than display size
|
||||
if (off+2+len > max_len) // scroll name if longer than display size
|
||||
{
|
||||
// reset scroll position if it exceeds predefined maximum
|
||||
if (scroll_offset >= (uint)(len + BLANKSPACE) << 3) scroll_offset = 0;
|
||||
@@ -668,7 +685,7 @@ void ScrollText(char n, const char *str, int off, int len, int max_len, unsigned
|
||||
strncpy(s + len + BLANKSPACE, str, max_len - len - BLANKSPACE); // repeat the name after its end and predefined number of blank space
|
||||
}
|
||||
|
||||
OSD_PrintText(n, s, 22, (max_len - 1) << 3, (scroll_offset & 0x7), invert); // OSD print function with pixel precision
|
||||
OSD_PrintText(n, hdr, s, 22, (max_len - 1) << 3, (scroll_offset & 0x7), invert); // OSD print function with pixel precision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user