Add (slow) support for HiRes graphics.
Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
parent
3da7d4ed55
commit
c1b7d96dd1
5 changed files with 136 additions and 40 deletions
63
source/frontends/qapple/graphicscache.cpp
Normal file
63
source/frontends/qapple/graphicscache.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
#include "graphicscache.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void halfScanLines(QPixmap & charset)
|
||||
{
|
||||
const int height = charset.height();
|
||||
const int width = charset.width();
|
||||
|
||||
const QColor background = charset.toImage().pixelColor(0, height - 1);
|
||||
|
||||
QPainter paint(&charset);
|
||||
paint.setPen(background);
|
||||
|
||||
for (int i = 0; i < height; i += 2)
|
||||
{
|
||||
paint.drawLine(0, i, width - 1, i);
|
||||
}
|
||||
}
|
||||
|
||||
QPixmap buildHiResMono()
|
||||
{
|
||||
const QColor black(Qt::black);
|
||||
const QColor white(Qt::white);
|
||||
|
||||
QPixmap hires(14, 128 * 2);
|
||||
hires.fill(black);
|
||||
|
||||
QPainter painter(&hires);
|
||||
|
||||
for (int i = 0; i < 128; ++i)
|
||||
{
|
||||
for (int j = 0; j < 7; ++j)
|
||||
{
|
||||
if (i & (1 << j))
|
||||
{
|
||||
painter.setPen(white);
|
||||
}
|
||||
else
|
||||
{
|
||||
painter.setPen(black);
|
||||
}
|
||||
painter.drawLine(j * 2, i * 2, j * 2 + 2, i * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return hires;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GraphicsCache::GraphicsCache()
|
||||
{
|
||||
myCharset40.load(":/resources/CHARSET4.BMP");
|
||||
halfScanLines(myCharset40);
|
||||
|
||||
myCharset80 = myCharset40.scaled(myCharset40.width() / 2, myCharset40.height());
|
||||
|
||||
myHiResMono = buildHiResMono();
|
||||
}
|
34
source/frontends/qapple/graphicscache.h
Normal file
34
source/frontends/qapple/graphicscache.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef GRAPHICSCACHE_H
|
||||
#define GRAPHICSCACHE_H
|
||||
|
||||
|
||||
#include <QPixmap>
|
||||
|
||||
class GraphicsCache
|
||||
{
|
||||
public:
|
||||
GraphicsCache();
|
||||
|
||||
const QPixmap & text40Col() const
|
||||
{
|
||||
return myCharset40;
|
||||
}
|
||||
|
||||
const QPixmap & text80Col() const
|
||||
{
|
||||
return myCharset80;
|
||||
}
|
||||
|
||||
const QPixmap & hires() const
|
||||
{
|
||||
return myHiResMono;
|
||||
}
|
||||
|
||||
private:
|
||||
QPixmap myCharset40;
|
||||
QPixmap myCharset80;
|
||||
|
||||
QPixmap myHiResMono;
|
||||
};
|
||||
|
||||
#endif // GRAPHICSCACHE_H
|
|
@ -16,11 +16,13 @@ SOURCES += main.cpp\
|
|||
qapple.cpp \
|
||||
qresources.cpp \
|
||||
emulator.cpp \
|
||||
video.cpp
|
||||
video.cpp \
|
||||
graphicscache.cpp
|
||||
|
||||
HEADERS += qapple.h \
|
||||
emulator.h \
|
||||
video.h
|
||||
video.h \
|
||||
graphicscache.h
|
||||
|
||||
FORMS += qapple.ui \
|
||||
emulator.ui
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include <QPainter>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "graphicscache.h"
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "Video.h"
|
||||
#include "Memory.h"
|
||||
|
@ -24,22 +26,6 @@ namespace
|
|||
|
||||
// bool g_bTextFlashState = false;
|
||||
|
||||
void halfScanLines(QPixmap & charset)
|
||||
{
|
||||
const int height = charset.height();
|
||||
const int width = charset.width();
|
||||
|
||||
const QColor background = charset.toImage().pixelColor(0, height - 1);
|
||||
|
||||
QPainter paint(&charset);
|
||||
paint.setPen(background);
|
||||
|
||||
for (int i = 0; i < height; i += 2)
|
||||
{
|
||||
paint.drawLine(0, i, width - 1, i);
|
||||
}
|
||||
}
|
||||
|
||||
BYTE keyCode = 0;
|
||||
bool keyWaiting = false;
|
||||
|
||||
|
@ -47,46 +33,52 @@ namespace
|
|||
|
||||
bool Video::Update40ColCell (QPainter & painter, int x, int y, int xpixel, int ypixel, int offset)
|
||||
{
|
||||
Q_UNUSED(xpixel)
|
||||
Q_UNUSED(ypixel)
|
||||
Q_UNUSED(x)
|
||||
Q_UNUSED(y)
|
||||
|
||||
BYTE ch = *(g_pTextBank0+offset);
|
||||
const BYTE ch = *(g_pTextBank0+offset);
|
||||
|
||||
const int base = g_nAltCharSetOffset ? 16 : 0;
|
||||
|
||||
const int row = ch / 16;
|
||||
const int column = ch % 16;
|
||||
|
||||
const int sx = 16 * column;
|
||||
const int sy = 16 * row;
|
||||
painter.drawPixmap(x * 14, y * 16, myCharset40, sx, sy, 14, 16);
|
||||
const int sy = 16 * (base + row);
|
||||
const QPixmap & text40Col = myGraphicsCache->text40Col();
|
||||
|
||||
painter.drawPixmap(xpixel, ypixel, text40Col, sx, sy, 14, 16);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Video::Update80ColCell(QPainter & painter, int x, int y, int xpixel, int ypixel, int offset)
|
||||
{
|
||||
Q_UNUSED(xpixel)
|
||||
Q_UNUSED(ypixel)
|
||||
Q_UNUSED(x)
|
||||
Q_UNUSED(y)
|
||||
|
||||
const QPixmap & text80Col = myGraphicsCache->text80Col();
|
||||
|
||||
{
|
||||
BYTE ch1 = *(g_pTextBank1+offset);
|
||||
const BYTE ch1 = *(g_pTextBank1+offset);
|
||||
|
||||
const int row = ch1 / 16;
|
||||
const int column = ch1 % 16;
|
||||
|
||||
const int sx = 8 * column;
|
||||
const int sy = 16 * row;
|
||||
painter.drawPixmap(x * 14, y * 16, myCharset80, sx, sy, 7, 16);
|
||||
painter.drawPixmap(xpixel, ypixel, text80Col, sx, sy, 7, 16);
|
||||
}
|
||||
|
||||
{
|
||||
BYTE ch2 = *(g_pTextBank0+offset);
|
||||
const BYTE ch2 = *(g_pTextBank0+offset);
|
||||
|
||||
const int row = ch2 / 16;
|
||||
const int column = ch2 % 16;
|
||||
|
||||
const int sx = 8 * column;
|
||||
const int sy = 16 * row;
|
||||
painter.drawPixmap(x * 14 + 7, y * 16, myCharset80, sx, sy, 7, 16);
|
||||
painter.drawPixmap(xpixel + 7, ypixel, text80Col, sx, sy, 7, 16);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -100,7 +92,7 @@ bool Video::UpdateLoResCell(QPainter & painter, int x, int y, int xpixel, int yp
|
|||
Q_UNUSED(xpixel)
|
||||
Q_UNUSED(ypixel)
|
||||
|
||||
BYTE val = *(g_pTextBank0+offset);
|
||||
const BYTE val = *(g_pTextBank0+offset);
|
||||
|
||||
Q_UNUSED(val)
|
||||
|
||||
|
@ -121,15 +113,21 @@ bool Video::UpdateDLoResCell(QPainter & painter, int x, int y, int xpixel, int y
|
|||
|
||||
bool Video::UpdateHiResCell(QPainter & painter, int x, int y, int xpixel, int ypixel, int offset)
|
||||
{
|
||||
Q_UNUSED(painter)
|
||||
Q_UNUSED(x)
|
||||
Q_UNUSED(y)
|
||||
Q_UNUSED(xpixel)
|
||||
Q_UNUSED(ypixel)
|
||||
|
||||
const BYTE * base = g_pHiresBank0 + offset;
|
||||
const QPixmap & hires = myGraphicsCache->hires();
|
||||
|
||||
Q_UNUSED(base)
|
||||
for (size_t i = 0; i < 8; ++i)
|
||||
{
|
||||
const int line = 0x0400 * i;
|
||||
const BYTE value = *(base + line);
|
||||
|
||||
const int row = value & 0x7f;
|
||||
|
||||
painter.drawPixmap(xpixel, ypixel + i * 2, hires, 0, row * 2, 14, 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -148,10 +146,7 @@ bool Video::UpdateDHiResCell(QPainter & painter, int x, int y, int xpixel, int y
|
|||
|
||||
Video::Video(QWidget *parent) : VIDEO_BASECLASS(parent)
|
||||
{
|
||||
myCharset40.load(":/resources/CHARSET4.BMP");
|
||||
halfScanLines(myCharset40);
|
||||
|
||||
myCharset80 = myCharset40.scaled(myCharset40.width() / 2, myCharset40.height());
|
||||
myGraphicsCache.reset(new GraphicsCache());
|
||||
}
|
||||
|
||||
void Video::paintEvent(QPaintEvent *)
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
#define VIDEO_H
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <memory>
|
||||
|
||||
//#define VIDEO_BASECLASS QOpenGLWidget
|
||||
#define VIDEO_BASECLASS QWidget
|
||||
|
||||
class GraphicsCache;
|
||||
|
||||
class Video : public VIDEO_BASECLASS
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -29,8 +32,7 @@ private:
|
|||
bool UpdateHiResCell(QPainter & painter, int x, int y, int xpixel, int ypixel, int offset);
|
||||
bool UpdateDHiResCell(QPainter & painter, int x, int y, int xpixel, int ypixel, int offset);
|
||||
|
||||
QPixmap myCharset40;
|
||||
QPixmap myCharset80;
|
||||
std::shared_ptr<const GraphicsCache> myGraphicsCache;
|
||||
};
|
||||
|
||||
#endif // VIDEO_H
|
||||
|
|
Loading…
Add table
Reference in a new issue