CBM font usable on LCD display
Put "i2cLcdUseCBMChar = 1" to the option.txt file. You have to use the Chargen rom too
This commit is contained in:
parent
cb04179fc9
commit
8b3dc69bac
11 changed files with 78 additions and 28 deletions
|
@ -94,6 +94,7 @@ GraphIEC = 1
|
|||
//i2cLcdFlip = 1 // Rotate i2c LCD screen 180 degrees
|
||||
//i2cLcdOnContrast = 127 // Allows you to adjust the contrast on your i2c LCD screen
|
||||
//i2cScan = 1 // scan i2c bus and display addresses on screen
|
||||
//i2cLcdUseCBMChar = 0 // set it to 1 to use CBM font on LCD. Small but fun !
|
||||
|
||||
//QuickBoot = 0 // faster startup
|
||||
//ShowOptions = 0 // display some options on startup screen
|
||||
|
|
|
@ -82,7 +82,7 @@ void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, b
|
|||
if (entryIndex < list->entries.size())
|
||||
{
|
||||
FileBrowser::BrowsableList::Entry* entry = &list->entries[entryIndex];
|
||||
if (screen->IsMonocrome())
|
||||
if (screen->IsLCD())
|
||||
{
|
||||
// pre-clear line on OLED
|
||||
memset(buffer1, ' ', columnsMax);
|
||||
|
@ -114,9 +114,9 @@ void FileBrowser::BrowsableListView::RefreshLine(u32 entryIndex, u32 x, u32 y, b
|
|||
int len = strlen(buffer2 + highlightScrollOffset);
|
||||
strncpy(buffer1, buffer2 + highlightScrollOffset, sizeof(buffer1));
|
||||
|
||||
if (!screen->IsMonocrome())
|
||||
if (!screen->IsLCD())
|
||||
{
|
||||
// space pad the remainder of the line (but not on OLED==monochrome)
|
||||
// space pad the remainder of the line (but not on OLED)
|
||||
while (len < (int)columnsMax)
|
||||
buffer1[len++] = ' ';
|
||||
buffer1[columnsMax] = 0;
|
||||
|
@ -524,7 +524,7 @@ FileBrowser::FileBrowser(InputMappings* inputMappings, DiskCaddy* diskCaddy, ROM
|
|||
if (screenLCD)
|
||||
{
|
||||
columns = screenLCD->Width() / 8;
|
||||
rows = screenLCD->Height() / 16;
|
||||
rows = screenLCD->Height() / screenLCD->GetFontHeight();
|
||||
positionX = 0;
|
||||
positionY = 0;
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ static inline u8 ascii2petscii(u8 ch)
|
|||
if (ch > 64 && ch < 91) ch += 128;
|
||||
else if (ch > 96 && ch < 123) ch -= 32;
|
||||
else if (ch > 192 && ch < 219) ch -= 128;
|
||||
else if (ch == 95) ch = 164; // to handle underscore
|
||||
return ch;
|
||||
}
|
||||
static inline u8 petscii2ascii(u8 ch)
|
||||
|
|
|
@ -19,12 +19,15 @@
|
|||
#include "SSD1306.h"
|
||||
#include "debug.h"
|
||||
#include <string.h>
|
||||
#include "Petscii.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "xga_font_data.h"
|
||||
}
|
||||
|
||||
extern unsigned char* CBMFont;
|
||||
|
||||
SSD1306::SSD1306(int BSCMaster, u8 address, unsigned width, unsigned height, int flip, LCD_MODEL type)
|
||||
: BSCMaster(BSCMaster)
|
||||
, address(address)
|
||||
|
@ -142,13 +145,13 @@ void SSD1306::RefreshScreen()
|
|||
}
|
||||
}
|
||||
|
||||
// assumes a text row is 16 bit high
|
||||
// assumes a text row is 8 bit high
|
||||
void SSD1306::RefreshTextRows(u32 start, u32 amountOfRows)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
start <<= 1;
|
||||
amountOfRows <<= 1;
|
||||
//start <<= 1;
|
||||
//amountOfRows <<= 1;
|
||||
for (i = start; i < start+amountOfRows; i++)
|
||||
{
|
||||
RefreshPage(i);
|
||||
|
@ -230,14 +233,14 @@ void SSD1306::SetVCOMDeselect(u8 value)
|
|||
SendCommand( (value & 7) << 4 );
|
||||
}
|
||||
|
||||
void SSD1306::PlotText(int x, int y, char* str, bool inverse)
|
||||
void SSD1306::PlotText(bool useCBMFont, bool petscii, int x, int y, char* str, bool inverse)
|
||||
{
|
||||
// assumes 16 character width
|
||||
int i;
|
||||
i = 0;
|
||||
while (str[i] && x < 16)
|
||||
{
|
||||
PlotCharacter(x++, y, str[i++], inverse);
|
||||
PlotCharacter(useCBMFont, petscii, x++, y, str[i++], inverse);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,13 +271,25 @@ void transpose8(unsigned char* B, const unsigned char* A, bool inverse)
|
|||
B[4] = y >> 24; B[5] = y >> 16; B[6] = y >> 8; B[7] = y;
|
||||
}
|
||||
|
||||
void SSD1306::PlotCharacter(int x, int y, char c, bool inverse)
|
||||
void SSD1306::PlotCharacter(bool useCBMFont, bool petscii, int x, int y, char c, bool inverse)
|
||||
{
|
||||
unsigned char a[8], b[8];
|
||||
transpose8(a, avpriv_vga16_font + (c * 16), inverse);
|
||||
transpose8(b, avpriv_vga16_font + (c * 16) + 8, inverse);
|
||||
memcpy(frame + (y * 256) + (x * 8), a, 8);
|
||||
memcpy(frame + (y * 256) + (x * 8) + 128, b, 8);
|
||||
if (useCBMFont && CBMFont)
|
||||
{
|
||||
if (! petscii)
|
||||
c = ascii2petscii(c);
|
||||
c = petscii2screen(c);
|
||||
transpose8(a, CBMFont + ((c+256) * 8), inverse); // 256 byte shift to use the maj/min bank
|
||||
memcpy(frame + (y * 128) + (x * 8), a, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
transpose8(a, avpriv_vga16_font + (c * 16), inverse);
|
||||
transpose8(b, avpriv_vga16_font + (c * 16) + 8, inverse);
|
||||
memcpy(frame + (y * 256) + (x * 8), a, 8);
|
||||
memcpy(frame + (y * 256) + (x * 8) + 128, b, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SSD1306::PlotPixel(int x, int y, int c)
|
||||
|
|
|
@ -77,8 +77,8 @@ public:
|
|||
// 128x64 0x3D or 0x3C (if SA0 is grounded)
|
||||
SSD1306(int BSCMaster = 1, u8 address = 0x3C, unsigned width = 128, unsigned height = 64, int flip = 0, LCD_MODEL type=LCD_UNKNOWN);
|
||||
|
||||
void PlotCharacter(int x, int y, char ascii, bool inverse);
|
||||
void PlotText(int x, int y, char* str, bool inverse);
|
||||
void PlotCharacter(bool useCBMFont, bool petscii, int x, int y, char ascii, bool inverse);
|
||||
void PlotText(bool useCBMFont, bool petscii, int x, int y, char* str, bool inverse);
|
||||
|
||||
void InitHardware();
|
||||
void DisplayOn();
|
||||
|
|
|
@ -74,6 +74,9 @@ public:
|
|||
virtual void SwapBuffers() = 0;
|
||||
virtual void RefreshRows(u32 start, u32 amountOfRows) {}
|
||||
|
||||
virtual bool IsLCD() { return false; };
|
||||
virtual bool UseCBMFont() { return false; };
|
||||
|
||||
bool IsMonocrome() const { return bpp == 1; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
#include "debug.h"
|
||||
#include "ssd_logo.h"
|
||||
|
||||
void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType)
|
||||
extern unsigned char* CBMFont;
|
||||
|
||||
void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType, bool luseCBMFont)
|
||||
{
|
||||
bpp = 1;
|
||||
|
||||
|
@ -38,7 +40,8 @@ void ScreenLCD::Open(u32 widthDesired, u32 heightDesired, u32 colourDepth, int B
|
|||
|
||||
width = widthDesired;
|
||||
height = heightDesired;
|
||||
|
||||
useCBMFont = luseCBMFont;
|
||||
|
||||
ssd1306 = new SSD1306(BSCMaster, LCDAddress, width, height, LCDFlip, LCDType);
|
||||
ssd1306->ClearScreen();
|
||||
ssd1306->RefreshScreen();
|
||||
|
@ -100,7 +103,7 @@ void ScreenLCD::PlotRawImage(const u8* image, int x, int y, int w, int h)
|
|||
u32 ScreenLCD::PrintText(bool petscii, u32 x, u32 y, char *ptr, RGBA TxtColour, RGBA BkColour, bool measureOnly, u32* width, u32* height)
|
||||
{
|
||||
int len = 0;
|
||||
ssd1306->PlotText(x >> 3, y >> 4, ptr, (BkColour & 0xffffff) != 0);
|
||||
ssd1306->PlotText(UseCBMFont(), petscii, x >> 3, y >> 4, ptr, (BkColour & 0xffffff) != 0);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
@ -111,7 +114,10 @@ u32 ScreenLCD::MeasureText(bool petscii, char *ptr, u32* width, u32* height)
|
|||
|
||||
u32 ScreenLCD::GetFontHeight()
|
||||
{
|
||||
return 16;
|
||||
if (CBMFont && useCBMFont)
|
||||
return 8;
|
||||
else
|
||||
return 16;
|
||||
}
|
||||
|
||||
void ScreenLCD::RefreshScreen()
|
||||
|
@ -127,5 +133,20 @@ void ScreenLCD::SwapBuffers()
|
|||
void ScreenLCD::RefreshRows(u32 start, u32 amountOfRows)
|
||||
{
|
||||
if (ssd1306)
|
||||
{
|
||||
if (UseCBMFont())
|
||||
ssd1306->RefreshTextRows(start, amountOfRows);
|
||||
else
|
||||
ssd1306->RefreshTextRows(start*2, amountOfRows*2);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScreenLCD::IsLCD()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScreenLCD::UseCBMFont()
|
||||
{
|
||||
return (CBMFont && useCBMFont);
|
||||
}
|
|
@ -33,7 +33,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
void Open(u32 width, u32 height, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType);
|
||||
void Open(u32 width, u32 height, u32 colourDepth, int BSCMaster, int LCDAddress, int LCDFlip, LCD_MODEL LCDType, bool luseCBMFont);
|
||||
|
||||
void DrawRectangle(u32 x1, u32 y1, u32 x2, u32 y2, RGBA colour);
|
||||
void Clear(RGBA colour);
|
||||
|
@ -59,9 +59,11 @@ public:
|
|||
void RefreshScreen();
|
||||
|
||||
void RefreshRows(u32 start, u32 amountOfRows);
|
||||
|
||||
bool IsLCD();
|
||||
bool UseCBMFont();
|
||||
private:
|
||||
SSD1306* ssd1306 = 0;
|
||||
bool useCBMFont;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
14
src/main.cpp
14
src/main.cpp
|
@ -117,6 +117,7 @@ u16 pc;
|
|||
|
||||
unsigned int screenWidth = 1024;
|
||||
unsigned int screenHeight = 768;
|
||||
int i2cLcdUseCBMChar = 0;
|
||||
|
||||
const char* termainalTextRed = "\E[31m";
|
||||
const char* termainalTextNormal = "\E[0m";
|
||||
|
@ -250,6 +251,7 @@ void InitialiseLCD()
|
|||
int i2cLcdOnContrast = options.I2CLcdOnContrast();
|
||||
int i2cLcdDimContrast = options.I2CLcdDimContrast();
|
||||
int i2cLcdDimTime = options.I2CLcdDimTime();
|
||||
i2cLcdUseCBMChar = options.I2cLcdUseCBMChar();
|
||||
LCD_MODEL i2cLcdModel = options.I2CLcdModel();
|
||||
|
||||
if (i2cLcdModel)
|
||||
|
@ -259,7 +261,7 @@ void InitialiseLCD()
|
|||
if (i2cLcdModel == LCD_1306_128x32)
|
||||
height = 32;
|
||||
screenLCD = new ScreenLCD();
|
||||
screenLCD->Open(width, height, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel);
|
||||
screenLCD->Open(width, height, 1, i2cBusMaster, i2cLcdAddress, i2cLcdFlip, i2cLcdModel, i2cLcdUseCBMChar);
|
||||
screenLCD->SetContrast(i2cLcdOnContrast);
|
||||
screenLCD->ClearInit(0); // sh1106 needs this
|
||||
|
||||
|
@ -268,7 +270,7 @@ void InitialiseLCD()
|
|||
{
|
||||
screenLCD->PlotRawImage(logo_ssd_1541ii, 0, 0, width, height);
|
||||
snprintf(tempBuffer, tempBufferSize, "Pi1541 V%d.%02d", versionMajor, versionMinor);
|
||||
screenLCD->PrintText(0, 16, 0, tempBuffer, 0xffffffff);
|
||||
screenLCD->PrintText(false, 16, 0, tempBuffer, 0xffffffff);
|
||||
logo_done = true;
|
||||
}
|
||||
else if (( height == 64) && (strcasecmp(options.GetLcdLogoName(), "1541classic") == 0) )
|
||||
|
@ -297,7 +299,7 @@ void InitialiseLCD()
|
|||
snprintf(tempBuffer, tempBufferSize, "Pi1541 V%d.%02d", versionMajor, versionMinor);
|
||||
int x = (width - 8*strlen(tempBuffer) ) /2;
|
||||
int y = (height-16)/2;
|
||||
screenLCD->PrintText(0, x, y, tempBuffer, 0x0);
|
||||
screenLCD->PrintText(false, x, y, tempBuffer, 0x0);
|
||||
}
|
||||
screenLCD->RefreshScreen();
|
||||
}
|
||||
|
@ -345,7 +347,7 @@ void UpdateScreen()
|
|||
int top, top2, top3;
|
||||
int bottom;
|
||||
int graphX = 0;
|
||||
//bool refreshUartStatusDisplay;
|
||||
//bool refreshUartStatusDisplay;
|
||||
|
||||
top = screenHeight - height / 2;
|
||||
bottom = screenHeight - 1;
|
||||
|
@ -1051,7 +1053,7 @@ void emulator()
|
|||
|
||||
m_IEC_Commands.SetAutoBootFB128(options.AutoBootFB128());
|
||||
m_IEC_Commands.Set128BootSectorName(options.Get128BootSectorName());
|
||||
m_IEC_Commands.SetLowercaseBrowseModeFilenames(options.LowercaseBrowseModeFilenames());
|
||||
m_IEC_Commands.SetLowercaseBrowseModeFilenames(options.LowercaseBrowseModeFilenames());
|
||||
|
||||
emulating = IEC_COMMANDS;
|
||||
|
||||
|
@ -1343,6 +1345,8 @@ void DisplayOptions(int y_pos)
|
|||
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
|
||||
snprintf(tempBuffer, tempBufferSize, "AutoBaseName = %s\r\n", options.GetAutoBaseName());
|
||||
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
|
||||
snprintf(tempBuffer, tempBufferSize, "I2cLcdUseCBMChar = %d\r\n", i2cLcdUseCBMChar);
|
||||
screen.PrintText(false, 0, y_pos += 16, tempBuffer, COLOUR_WHITE, COLOUR_BLACK);
|
||||
}
|
||||
|
||||
void DisplayI2CScan(int y_pos)
|
||||
|
|
|
@ -148,6 +148,7 @@ Options::Options(void)
|
|||
, i2cLcdFlip(0)
|
||||
, i2cLcdOnContrast(127)
|
||||
, i2cLcdModel(LCD_UNKNOWN)
|
||||
, i2cLcdUseCBMChar(0)
|
||||
, scrollHighlightRate(0.125f)
|
||||
, keyboardBrowseLCDScreen(0)
|
||||
, buttonEnter(1)
|
||||
|
@ -235,6 +236,7 @@ void Options::Process(char* buffer)
|
|||
ELSE_CHECK_DECIMAL_OPTION(i2cLcdOnContrast)
|
||||
ELSE_CHECK_DECIMAL_OPTION(i2cLcdDimContrast)
|
||||
ELSE_CHECK_DECIMAL_OPTION(i2cLcdDimTime)
|
||||
ELSE_CHECK_DECIMAL_OPTION(i2cLcdUseCBMChar)
|
||||
ELSE_CHECK_FLOAT_OPTION(scrollHighlightRate)
|
||||
ELSE_CHECK_DECIMAL_OPTION(keyboardBrowseLCDScreen)
|
||||
ELSE_CHECK_DECIMAL_OPTION(buttonEnter)
|
||||
|
|
|
@ -75,7 +75,6 @@ public:
|
|||
|
||||
inline unsigned int LowercaseBrowseModeFilenames() const { return lowercaseBrowseModeFilenames; }
|
||||
|
||||
|
||||
inline unsigned int ScreenWidth() const { return screenWidth; }
|
||||
inline unsigned int ScreenHeight() const { return screenHeight; }
|
||||
|
||||
|
@ -86,6 +85,7 @@ public:
|
|||
inline unsigned int I2CLcdOnContrast() const { return i2cLcdOnContrast; }
|
||||
inline unsigned int I2CLcdDimContrast() const { return i2cLcdDimContrast; }
|
||||
inline unsigned int I2CLcdDimTime() const { return i2cLcdDimTime; }
|
||||
inline unsigned int I2cLcdUseCBMChar() const { return i2cLcdUseCBMChar; }
|
||||
inline LCD_MODEL I2CLcdModel() const { return i2cLcdModel; }
|
||||
|
||||
inline const char* GetLcdLogoName() const { return LcdLogoName; }
|
||||
|
@ -141,6 +141,7 @@ private:
|
|||
unsigned int i2cLcdOnContrast;
|
||||
unsigned int i2cLcdDimContrast;
|
||||
unsigned int i2cLcdDimTime;
|
||||
unsigned int i2cLcdUseCBMChar;
|
||||
LCD_MODEL i2cLcdModel = LCD_UNKNOWN;
|
||||
|
||||
float scrollHighlightRate;
|
||||
|
|
Loading…
Reference in a new issue