video working OK (still slow, though)

This commit is contained in:
Christopher Mosher 2013-10-09 23:23:33 -04:00
parent 6a2b84794c
commit 13481ab90e
3 changed files with 474 additions and 508 deletions

View File

@ -14,35 +14,38 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <iostream>
#include "gui.h"
#include <SDL2/SDL.h>
// Create, initialize, and cable together the UI objects to serve this
// program
GUI::GUI()
{
const int result = SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO);
// Create, initialize, and cable together the UI objects to serve this
// program
if (result != 0)
{
throw GUI::NotInitException();
}
GUI::GUI() {
const int result = SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO);
if (result != 0) {
throw GUI::NotInitException();
}
SDL_ShowCursor(0);
const SDL_bool ok = SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2");
if (ok != SDL_TRUE) {
std::cerr << "could not set opengles2 rendering" << std::endl;
// maybe it's OK, so don't throw GUI::NotInitException();
}
SDL_ShowCursor(0);
}
GUI::~GUI()
{
SDL_Quit();
GUI::~GUI() {
SDL_Quit();
}
GUI::NotInitException::NotInitException() :
runtime_error("Unable to initialize SDL")
{
SDL_GetError();
runtime_error("Unable to initialize SDL") {
SDL_GetError();
}

View File

@ -14,24 +14,25 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "screenimage.h"
#include "e2const.h"
#include "applentsc.h"
#include "card.h"
#include "util.h"
#include <SDL2/SDL.h>
#include <iostream>
#include <ctime>
#include <sstream>
static const char* power =
" @@@@ @@@ @ @ @ @@@@@ @@@@ "
" @ @ @ @ @ @ @ @ @ @ @"
" @ @ @ @ @ @ @ @ @ @ @"
" @@@@ @ @ @ @ @ @ @@@@@ @@@@ "
" @ @ @ @ @ @ @ @ @ @ "
" @ @ @ @ @ @ @ @ @ @ "
" @ @@@ @ @ @@@@@ @ @";
" @@@@ @@@ @ @ @ @@@@@ @@@@ "
" @ @ @ @ @ @ @ @ @ @ @"
" @ @ @ @ @ @ @ @ @ @ @"
" @@@@ @ @ @ @ @ @ @@@@@ @@@@ "
" @ @ @ @ @ @ @ @ @ @ "
" @ @ @ @ @ @ @ @ @ @ "
" @ @@@ @ @ @@@@@ @ @";
#define POWERD 56
#define LABEL_Y 24
@ -40,522 +41,479 @@ static const char* power =
#define SCRW 640
#define SCRH 480
static const int HEIGHT = E2Const::VISIBLE_ROWS_PER_FIELD*2;
static const int WIDTH = AppleNTSC::H-AppleNTSC::PIC_START-2;
static const int HEIGHT = E2Const::VISIBLE_ROWS_PER_FIELD * 2;
static const int WIDTH = AppleNTSC::H - AppleNTSC::PIC_START - 2;
#include "font3x5.h"
class ScreenException { };
ScreenImage::ScreenImage():
fullscreen(false),
hyper(false),
buffer(true),
fillLines(false),
display(AnalogTV::MONITOR_COLOR),
slotnames(8),
cassettename(32,' ')
{
createScreen();
}
void ScreenImage::toggleFullScreen()
{
this->fullscreen = !this->fullscreen;
createScreen();
}
void ScreenImage::createScreen()
{
// TODO this->screen = SDL_SetVideoMode(SCRW,SCRH,32,SDL_HWSURFACE|SDL_HWPALETTE|(this->fullscreen?SDL_FULLSCREEN:0));
if (this->screen == NULL)
{
printf("Unable to set video mode: %s\n",SDL_GetError());
throw ScreenException();
};
if (this->screen->pitch/4 != SCRW)
{
printf("Cannot set video screen pitch to 640*4 pixels (gets set to %d)\n",this->screen->pitch);
throw ScreenException();
};
drawLabels();
notifyObservers();
}
void ScreenImage::drawLabels()
{
drawText("EPPLE ][",0,141);
drawSlots();
drawCassette();
drawFnKeys();
}
void ScreenImage::drawSlots()
{
int r(65);
int c(17);
drawText("SLOTS:",r++,c);
for (int slot(0); slot < 8; ++slot)
{
drawSlot(slot,r++,c);
}
}
void ScreenImage::drawSlot(int slot, int r, int c)
{
drawChar('0'+slot,r,c++);
drawChar(':',r,c++);
drawChar(' ',r,c++);
drawText(this->slotnames[slot],r,c);
const int len = this->slotnames[slot].length();
if (len < 100)
{
drawText(std::string(100-len,' '),r,c+len);
}
}
void ScreenImage::drawCassette()
{
int r(65);
int c(85);
drawText("CASSETTE:",r,c);
c += 9;
drawText(this->cassettename,r,c);
const int len = this->cassettename.length();
if (len < 40)
{
drawText(std::string(40-len,' '),r,c+len);
}
}
static const char* displays[] =
{
"COLOR MONITOR ",
"WHITE MONITOR ",
"GREEN MONITOR ",
"ORANGE MONITOR",
"OLD COLOR TV ",
"OLD B & W TV ",
"NEW COLOR TV ",
"NEW B & W TV ",
class ScreenException {
};
void ScreenImage::drawFnKeys()
{
int r(76);
int c(1);
drawText(
" FULLSCRN SCAN-LINES KEYBOARD",r++,c);
drawText(
" XXXXXXXXXXXXXX WINDOW FILL-LINES CMD REPT HYPER BUFFER RESET PASTE SAVE BMP QUIT!",r++,c);
drawText(
" F1 F2 F3 F4 F5 F10 F11 F12 Break Insert PrintScreen End",r++,c);
if (this->fullscreen)
invertText(76,32,42); // FULLSCRN
else
invertText(77,32,40); // WINDOW
if (this->fillLines)
invertText(77,43,55); // FILL-LINES
else
invertText(76,43,55); // SCAN-LINES
if (this->hyper)
invertText(77,67,74); // HYPER
if (this->buffer)
invertText(77,75,83); // BUFFER
drawDisplayLabel();
ScreenImage::ScreenImage() :
fullscreen(false),
hyper(false),
buffer(true),
fillLines(false),
display(AnalogTV::MONITOR_COLOR),
slotnames(8),
cassettename(32, ' ') {
createScreen();
}
void ScreenImage::toggleFillLinesLabel()
{
this->fillLines = !this->fillLines;
invertText(76,43,55); // SCAN-LINES
invertText(77,43,55); // FILL-LINES
void ScreenImage::toggleFullScreen() {
this->fullscreen = !this->fullscreen;
const int flags = this->fullscreen ? SDL_WINDOW_FULLSCREEN : 0;
SDL_SetWindowFullscreen(this->window, flags);
}
void ScreenImage::drawDisplayLabel()
{
const char* label = displays[(int)(this->display)];
drawText(label,77,17);
void ScreenImage::createScreen() {
this->window= SDL_CreateWindow("Epple ][", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCRW, SCRH, SDL_WINDOW_SHOWN);
if (this->window == NULL) {
printf("Unable to create window: %s\n", SDL_GetError());
throw ScreenException();
}
this->renderer = SDL_CreateRenderer(this->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (this->renderer == NULL) {
std::cerr << SDL_GetError() << std::endl;
throw ScreenException();
}
this->texture = SDL_CreateTexture(this->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, SCRW, SCRH);
if (this->texture == NULL) {
std::cerr << SDL_GetError() << std::endl;
throw ScreenException();
}
this->pixels = (unsigned int*) malloc(SCRW * SCRH * sizeof (unsigned int));
this->screen_pitch = SCRW;
drawLabels();
notifyObservers();
}
void ScreenImage::cycleDisplayLabel()
{
this->display = (AnalogTV::DisplayType)((((int)this->display)+1)%AnalogTV::NUM_DISPLAY_TYPES);
drawDisplayLabel();
void ScreenImage::drawLabels() {
drawText("EPPLE ][", 0, 141);
drawSlots();
drawCassette();
drawFnKeys();
}
void ScreenImage::toggleHyperLabel()
{
this->hyper = !this->hyper;
invertText(77,67,74); // HYPER
void ScreenImage::drawSlots() {
int r(65);
int c(17);
drawText("SLOTS:", r++, c);
for (int slot(0); slot < 8; ++slot) {
drawSlot(slot, r++, c);
}
}
void ScreenImage::toggleKdbBufferLabel()
{
this->buffer = !this->buffer;
invertText(77,75,83); // BUFFER
void ScreenImage::drawSlot(int slot, int r, int c) {
drawChar('0' + slot, r, c++);
drawChar(':', r, c++);
drawChar(' ', r, c++);
drawText(this->slotnames[slot], r, c);
const int len = this->slotnames[slot].length();
if (len < 100) {
drawText(std::string(100 - len, ' '), r, c + len);
}
}
void ScreenImage::invertText(int row, int begincol, int endcol)
{
unsigned int* pn = (unsigned int*)this->screen->pixels;
pn += row*FONTH*SCRW+begincol*FONTW;
const int dc = (endcol-begincol)*FONTW;
for (int ir = 0; ir < FONTH; ++ir)
{
for (int ic = 0; ic < dc; ++ic)
{
*pn = ~*pn;
++pn;
}
pn -= dc;
pn += SCRW;
}
void ScreenImage::drawCassette() {
int r(65);
int c(85);
drawText("CASSETTE:", r, c);
c += 9;
drawText(this->cassettename, r, c);
const int len = this->cassettename.length();
if (len < 40) {
drawText(std::string(40 - len, ' '), r, c + len);
}
}
void ScreenImage::drawText(const std::string& text, int row, int col, int color, int bgcolor)
{
for (std::string::const_iterator i = text.begin(); i != text.end(); ++i)
{
char c = (*i) & 0x7F;
if (0 <= c && c < 0x20)
c += 0x40;
drawChar(c,row,col++,color,bgcolor);
}
static const char* displays[] = {
"COLOR MONITOR ",
"WHITE MONITOR ",
"GREEN MONITOR ",
"ORANGE MONITOR",
"OLD COLOR TV ",
"OLD B & W TV ",
"NEW COLOR TV ",
"NEW B & W TV ",
};
void ScreenImage::drawFnKeys() {
int r(76);
int c(1);
drawText(
" FULLSCRN SCAN-LINES KEYBOARD", r++, c);
drawText(
" XXXXXXXXXXXXXX WINDOW FILL-LINES CMD REPT HYPER BUFFER RESET PASTE SAVE BMP QUIT!", r++, c);
drawText(
" F1 F2 F3 F4 F5 F10 F11 F12 Break Insert PrintScreen End", r++, c);
if (this->fullscreen)
invertText(76, 32, 42); // FULLSCRN
else
invertText(77, 32, 40); // WINDOW
if (this->fillLines)
invertText(77, 43, 55); // FILL-LINES
else
invertText(76, 43, 55); // SCAN-LINES
if (this->hyper)
invertText(77, 67, 74); // HYPER
if (this->buffer)
invertText(77, 75, 83); // BUFFER
drawDisplayLabel();
}
void ScreenImage::drawChar(const char ch, int row, int col, int color, int bgcolor)
{
if (!(0 <= row && row < SCRH/6 && 0 <= col && col < SCRW/4))
{
printf("bad text plotting (r %d, c %d): \"%c\"\n",row,col,ch);
}
unsigned int* pn = (unsigned int*)this->screen->pixels;
pn += row*FONTH*SCRW+col*FONTW;
const char* pt = font3x5+FONTH*FONTW*(ch-0x20);
for (int r = 0; r < FONTH; ++r)
{
for (int c = 0; c < FONTW; ++c)
{
*pn++ = *pt++ == '@' ? color : bgcolor;
}
pn -= FONTW;
pn += SCRW;
}
// TODO SDL_UpdateRect(this->screen,col*FONTW,row*FONTH,(col+1)*FONTW,(row+1)*FONTH);
void ScreenImage::toggleFillLinesLabel() {
this->fillLines = !this->fillLines;
invertText(76, 43, 55); // SCAN-LINES
invertText(77, 43, 55); // FILL-LINES
}
void ScreenImage::displayHz(int hz)
{
char s[20];
sprintf(s,"%4.2f MHz ",hz/1e6);
drawText(s,3,141);
void ScreenImage::drawDisplayLabel() {
const char* label = displays[(int) (this->display)];
drawText(label, 77, 17);
}
void ScreenImage::drawPower(bool on)
{
unsigned int* pn = (unsigned int*)this->screen->pixels;
pn += (HEIGHT+5)*(this->screen->pitch/4)+5;
for (int r = 0; r < POWERD; ++r)
{
if (r < LABEL_Y || LABEL_Y+7 <= r)
{
for (int c = 0; c < POWERD; ++c)
{
*pn++ = on ? ON_CLR : OFF_CLR;
}
}
else
{
{
for (int c = 0; c < 8; ++c)
{
*pn++ = on ? ON_CLR : OFF_CLR;
}
}
for (const char* ppow = power+(r-(LABEL_Y))*40; ppow < power+(r-(LABEL_Y-1))*40; ++ppow)
{
if (*ppow == '@')
*pn++ = 0;
else
*pn++ = on ? ON_CLR : OFF_CLR;
}
{
for (int c = 0; c < 8; ++c)
{
*pn++ = on ? ON_CLR : OFF_CLR;
}
}
}
pn -= POWERD;
pn += this->screen->pitch/4;
}
// TODO SDL_UpdateRect(this->screen,0,HEIGHT,POWERD,HEIGHT+POWERD);
void ScreenImage::cycleDisplayLabel() {
this->display = (AnalogTV::DisplayType)((((int) this->display) + 1) % AnalogTV::NUM_DISPLAY_TYPES);
drawDisplayLabel();
}
ScreenImage::~ScreenImage()
{
void ScreenImage::toggleHyperLabel() {
this->hyper = !this->hyper;
invertText(77, 67, 74); // HYPER
}
void ScreenImage::notifyObservers()
{
// TODO SDL_UpdateRect(this->screen,0,0,SCRW,SCRH);
void ScreenImage::toggleKdbBufferLabel() {
this->buffer = !this->buffer;
invertText(77, 75, 83); // BUFFER
}
void ScreenImage::setElem(unsigned int i, const unsigned int val)
{
unsigned int* pn = (unsigned int*)this->screen->pixels;
i += (i/WIDTH)*(SCRW-WIDTH);
pn += i;
*pn = val;
void ScreenImage::invertText(int row, int begincol, int endcol) {
unsigned int* pn = this->pixels;
pn += row * FONTH * SCRW + begincol*FONTW;
const int dc = (endcol - begincol) * FONTW;
for (int ir = 0; ir < FONTH; ++ir) {
for (int ic = 0; ic < dc; ++ic) {
*pn = ~*pn;
++pn;
}
pn -= dc;
pn += SCRW;
}
}
void ScreenImage::blank()
{
for (int r = 0; r < HEIGHT; ++r)
{
memset((char*)(this->screen->pixels)+r*SCRW*4,0,WIDTH*4);
}
void ScreenImage::drawText(const std::string& text, int row, int col, int color, int bgcolor) {
for (std::string::const_iterator i = text.begin(); i != text.end(); ++i) {
char c = (*i) & 0x7F;
if (0 <= c && c < 0x20)
c += 0x40;
drawChar(c, row, col++, color, bgcolor);
}
}
void ScreenImage::enterCommandMode()
{
int r(76);
int c(1);
unsigned int* pn = (unsigned int*)this->screen->pixels;
pn += r*FONTH*SCRW+c*FONTW;
void ScreenImage::drawChar(const char ch, int row, int col, int color, int bgcolor) {
if (!(0 <= row && row < SCRH / 6 && 0 <= col && col < SCRW / 4)) {
printf("bad text plotting (r %d, c %d): \"%c\"\n", row, col, ch);
}
unsigned int* pn = this->pixels;
pn += row * FONTH * SCRW + col*FONTW;
memset((char*)pn,0,SCRW*4*FONTH*3);
drawText("command: ",78,1);
this->cmdpos = 9;
notifyObservers();
const char* pt = font3x5 + FONTH * FONTW * (ch - 0x20);
for (int r = 0; r < FONTH; ++r) {
for (int c = 0; c < FONTW; ++c) {
*pn++ = *pt++ == '@' ? color : bgcolor;
}
pn -= FONTW;
pn += SCRW;
}
// TODO
// const int e = SDL_UpdateTexture(this->texture, NULL, this->pixels, SCRW * sizeof (unsigned int));
// if (e) {
// std::cerr << SDL_GetError() << std::endl;
// }
// TODO SDL_UpdateRect(this->screen,col*FONTW,row*FONTH,(col+1)*FONTW,(row+1)*FONTH);
}
void ScreenImage::exitCommandMode()
{
drawFnKeys();
notifyObservers();
void ScreenImage::displayHz(int hz) {
char s[20];
sprintf(s, "%4.2f MHz ", hz / 1e6);
drawText(s, 3, 141);
}
void ScreenImage::addkeyCommand(unsigned char key)
{
++this->cmdpos;
drawChar((char)key,78,this->cmdpos);
void ScreenImage::drawPower(bool on) {
unsigned int* pn = this->pixels;
pn += (HEIGHT + 5)*(this->screen_pitch / 4) + 5;
for (int r = 0; r < POWERD; ++r) {
if (r < LABEL_Y || LABEL_Y + 7 <= r) {
for (int c = 0; c < POWERD; ++c) {
*pn++ = on ? ON_CLR : OFF_CLR;
}
} else {
{
for (int c = 0; c < 8; ++c) {
*pn++ = on ? ON_CLR : OFF_CLR;
}
}
for (const char* ppow = power + (r - (LABEL_Y))*40; ppow < power + (r - (LABEL_Y - 1))*40; ++ppow) {
if (*ppow == '@')
*pn++ = 0;
else
*pn++ = on ? ON_CLR : OFF_CLR;
}
{
for (int c = 0; c < 8; ++c) {
*pn++ = on ? ON_CLR : OFF_CLR;
}
}
}
pn -= POWERD;
pn += this->screen_pitch / 4;
}
notifyObservers();
}
void ScreenImage::backspaceCommand()
{
drawChar(' ',78,this->cmdpos);
--this->cmdpos;
ScreenImage::~ScreenImage() {
}
void ScreenImage::updateSlotName(const int slot, Card* card)
{
int r(66+slot);
int c(20);
const std::string& name = card->getName();
this->slotnames[slot] = name;
drawText(std::string(80,' '),r,c);
drawText(name,r,c);
void ScreenImage::notifyObservers() {
const int e = SDL_UpdateTexture(this->texture, NULL, this->pixels, SCRW * sizeof (unsigned int));
if (e) {
std::cerr << SDL_GetError() << std::endl;
}
SDL_RenderClear(this->renderer);
SDL_RenderCopy(this->renderer,this->texture,NULL,NULL);
SDL_RenderPresent(this->renderer);
}
void ScreenImage::removeCard(const int slot, Card* card /* empty */)
{
updateSlotName(slot,card);
void ScreenImage::setElem(unsigned int i, const unsigned int val) {
unsigned int* pn = this->pixels;
i += (i / WIDTH)*(SCRW - WIDTH);
pn += i;
*pn = val;
}
void ScreenImage::blank() {
for (int r = 0; r < HEIGHT; ++r) {
memset((char*) (this->pixels) + r * SCRW * 4, 0, WIDTH * 4);
}
}
void ScreenImage::enterCommandMode() {
int r(76);
int c(1);
unsigned int* pn = this->pixels;
pn += r * FONTH * SCRW + c*FONTW;
memset((char*) pn, 0, SCRW * 4 * FONTH * 3);
drawText("command: ", 78, 1);
this->cmdpos = 9;
notifyObservers();
}
void ScreenImage::exitCommandMode() {
drawFnKeys();
notifyObservers();
}
void ScreenImage::addkeyCommand(unsigned char key) {
++this->cmdpos;
drawChar((char) key, 78, this->cmdpos);
}
void ScreenImage::backspaceCommand() {
drawChar(' ', 78, this->cmdpos);
--this->cmdpos;
}
void ScreenImage::updateSlotName(const int slot, Card* card) {
int r(66 + slot);
int c(20);
const std::string& name = card->getName();
this->slotnames[slot] = name;
drawText(std::string(80, ' '), r, c);
drawText(name, r, c);
}
void ScreenImage::removeCard(const int slot, Card* card /* empty */) {
updateSlotName(slot, card);
}
/*
1 2 3 4 5 6 7 8
789012345678901234567890123456789012345678901234567890123456789012345
6: disk][ drive 1M*filename.nib T$FF drive 2M*filename.nib T$FF
*/
void ScreenImage::setDiskFile(int slot, int drive, const std::string& filepath)
{
std::string f = truncateFilePath(filepath);
int r(66+slot);
int c(37+32*drive);
drawText(f,r,c);
*/
void ScreenImage::setDiskFile(int slot, int drive, const std::string& filepath) {
std::string f = truncateFilePath(filepath);
int r(66 + slot);
int c(37 + 32 * drive);
drawText(f, r, c);
const int dlen = 12 - f.length();
if (dlen > 0)
{
std::string d(dlen,' ');
drawText(d,r,c+f.length());
}
const int dlen = 12 - f.length();
if (dlen > 0) {
std::string d(dlen, ' ');
drawText(d, r, c + f.length());
}
this->slotnames[slot].replace(c-20,12,12,' ');
this->slotnames[slot].replace(c-20,f.length(),f);
this->slotnames[slot].replace(c - 20, 12, 12, ' ');
this->slotnames[slot].replace(c - 20, f.length(), f);
}
std::string ScreenImage::truncateFilePath(const std::string& filepath)
{
std::string f(filepath);
size_t slash = f.find_last_of("/\\");
if (slash != std::string::npos)
{
f = f.substr(slash+1);
}
if (f.length() > 12)
{
f = f.substr(0,12);
}
return f;
std::string ScreenImage::truncateFilePath(const std::string& filepath) {
std::string f(filepath);
size_t slash = f.find_last_of("/\\");
if (slash != std::string::npos) {
f = f.substr(slash + 1);
}
if (f.length() > 12) {
f = f.substr(0, 12);
}
return f;
}
void ScreenImage::clearCurrentDrive(int slot, int drive)
{
int r(66+slot);
int c(35+32*drive);
drawChar(' ',r,c);
this->slotnames[slot][c-20] = ' ';
c += 15;
drawText(" ",r,c);
this->slotnames[slot].replace(c-20,4,4,' ');
void ScreenImage::clearCurrentDrive(int slot, int drive) {
int r(66 + slot);
int c(35 + 32 * drive);
drawChar(' ', r, c);
this->slotnames[slot][c - 20] = ' ';
c += 15;
drawText(" ", r, c);
this->slotnames[slot].replace(c - 20, 4, 4, ' ');
}
void ScreenImage::setCurrentDrive(int slot, int drive, int track, bool on)
{
int r(66+slot);
int c(35+32*drive);
drawChar(' ',r,c,0xFFFFFF,on?0xFF0000:0);
c += 15;
drawChar('T',r,c);
this->slotnames[slot][c-20] = 'T';
++c;
drawChar('$',r,c);
this->slotnames[slot][c-20] = '$';
++c;
char nibh = Util::hexDigit((((unsigned char)track) >> 4) & 0xF);
drawChar(nibh,r,c);
this->slotnames[slot][c-20] = nibh;
++c;
char nibl = Util::hexDigit((unsigned char)track & 0xF);
drawChar(nibl,r,c);
this->slotnames[slot][c-20] = nibl;
void ScreenImage::setCurrentDrive(int slot, int drive, int track, bool on) {
int r(66 + slot);
int c(35 + 32 * drive);
drawChar(' ', r, c, 0xFFFFFF, on ? 0xFF0000 : 0);
c += 15;
drawChar('T', r, c);
this->slotnames[slot][c - 20] = 'T';
++c;
drawChar('$', r, c);
this->slotnames[slot][c - 20] = '$';
++c;
char nibh = Util::hexDigit((((unsigned char) track) >> 4) & 0xF);
drawChar(nibh, r, c);
this->slotnames[slot][c - 20] = nibh;
++c;
char nibl = Util::hexDigit((unsigned char) track & 0xF);
drawChar(nibl, r, c);
this->slotnames[slot][c - 20] = nibl;
}
void ScreenImage::setTrack(int slot, int drive, int track)
{
int r(66+slot);
int c(52+32*drive);
char nibh = Util::hexDigit((((unsigned char)track) >> 4) & 0xF);
drawChar(nibh,r,c);
this->slotnames[slot][c-20] = nibh;
++c;
char nibl = Util::hexDigit((unsigned char)track & 0xF);
drawChar(nibl,r,c);
this->slotnames[slot][c-20] = nibl;
void ScreenImage::setTrack(int slot, int drive, int track) {
int r(66 + slot);
int c(52 + 32 * drive);
char nibh = Util::hexDigit((((unsigned char) track) >> 4) & 0xF);
drawChar(nibh, r, c);
this->slotnames[slot][c - 20] = nibh;
++c;
char nibl = Util::hexDigit((unsigned char) track & 0xF);
drawChar(nibl, r, c);
this->slotnames[slot][c - 20] = nibl;
}
void ScreenImage::setIO(int slot, int drive, bool on)
{
int r(66+slot);
int c(35+32*drive);
drawChar(' ',r,c,0xFFFFFF,on?0xFF0000:0);
void ScreenImage::setIO(int slot, int drive, bool on) {
int r(66 + slot);
int c(35 + 32 * drive);
drawChar(' ', r, c, 0xFFFFFF, on ? 0xFF0000 : 0);
}
void ScreenImage::setDirty(int slot, int drive, bool dirty)
{
int r(66+slot);
int c(36+32*drive);
drawChar(dirty?'*':' ',r,c);
this->slotnames[slot][c-20] = dirty?'*':' ';
void ScreenImage::setDirty(int slot, int drive, bool dirty) {
int r(66 + slot);
int c(36 + 32 * drive);
drawChar(dirty ? '*' : ' ', r, c);
this->slotnames[slot][c - 20] = dirty ? '*' : ' ';
}
void ScreenImage::setCassetteFile(const std::string& filepath)
{
std::string f = truncateFilePath(filepath);
int r(65);
int c(85+11);
drawText(f,r,c);
void ScreenImage::setCassetteFile(const std::string& filepath) {
std::string f = truncateFilePath(filepath);
int r(65);
int c(85 + 11);
drawText(f, r, c);
const int dlen = 12 - f.length();
if (dlen > 0)
{
std::string d(dlen,' ');
drawText(d,r,c+f.length());
}
const int dlen = 12 - f.length();
if (dlen > 0) {
std::string d(dlen, ' ');
drawText(d, r, c + f.length());
}
this->cassettename.replace(c-94,12,12,' ');
this->cassettename.replace(c-94,f.length(),f);
this->cassettename.replace(c - 94, 12, 12, ' ');
this->cassettename.replace(c - 94, f.length(), f);
}
void ScreenImage::setCassetteDirty(bool dirty)
{
int r(65);
int c(85+10);
drawChar(dirty?'*':' ',r,c);
this->cassettename[c-94] = dirty?'*':' ';
void ScreenImage::setCassetteDirty(bool dirty) {
int r(65);
int c(85 + 10);
drawChar(dirty ? '*' : ' ', r, c);
this->cassettename[c - 94] = dirty ? '*' : ' ';
}
void ScreenImage::setCassettePos(int pos, int siz)
{
int r(65);
int c(110);
std::ostringstream os;
os << pos << '/' << siz << " ";
drawText(os.str(),r,c);
void ScreenImage::setCassettePos(int pos, int siz) {
int r(65);
int c(110);
std::ostringstream os;
os << pos << '/' << siz << " ";
drawText(os.str(), r, c);
}
/*
1 2 3 4 5 6 7 8
789012345678901234567890123456789012345678901234567890123456789012345678
0: language RW B2
*/
void ScreenImage::setLangCard(int slot, bool readEnable, bool writeEnable, int bank)
{
int r(66+slot);
int c(29);
drawChar(readEnable?'R':' ',r,c);
this->slotnames[slot][c-20] = readEnable?'R':' ';
++c;
drawChar(writeEnable?'W':' ',r,c);
this->slotnames[slot][c-20] = writeEnable?'W':' ';
++c;
++c;
drawChar('B',r,c);
this->slotnames[slot][c-20] = 'B';
++c;
drawChar(bank==0?'1':'2',r,c);
this->slotnames[slot][c-20] = bank==0?'1':'2';
*/
void ScreenImage::setLangCard(int slot, bool readEnable, bool writeEnable, int bank) {
int r(66 + slot);
int c(29);
drawChar(readEnable ? 'R' : ' ', r, c);
this->slotnames[slot][c - 20] = readEnable ? 'R' : ' ';
++c;
drawChar(writeEnable ? 'W' : ' ', r, c);
this->slotnames[slot][c - 20] = writeEnable ? 'W' : ' ';
++c;
++c;
drawChar('B', r, c);
this->slotnames[slot][c - 20] = 'B';
++c;
drawChar(bank == 0 ? '1' : '2', r, c);
this->slotnames[slot][c - 20] = bank == 0 ? '1' : '2';
}
/*
1 2 3 4 5 6 7 8
789012345678901234567890123456789012345678901234567890123456789012345678
0: firmware D F8
*/
void ScreenImage::setFirmCard(int slot, bool bank, bool F8)
{
int r(66+slot);
int c(29);
drawChar(bank?'D':' ',r,c);
this->slotnames[slot][c-20] = bank?'D':' ';
++c;
++c;
drawChar(F8?'F':' ',r,c);
this->slotnames[slot][c-20] = F8?'F':' ';
++c;
drawChar(F8?'8':' ',r,c);
this->slotnames[slot][c-20] = F8?'8':' ';
*/
void ScreenImage::setFirmCard(int slot, bool bank, bool F8) {
int r(66 + slot);
int c(29);
drawChar(bank ? 'D' : ' ', r, c);
this->slotnames[slot][c - 20] = bank ? 'D' : ' ';
++c;
++c;
drawChar(F8 ? 'F' : ' ', r, c);
this->slotnames[slot][c - 20] = F8 ? 'F' : ' ';
++c;
drawChar(F8 ? '8' : ' ', r, c);
this->slotnames[slot][c - 20] = F8 ? '8' : ' ';
}
#define TIMEFORMAT "ep2_%Y%m%d%H%M%S.bmp"
void ScreenImage::saveBMP()
{
time_t now;
::time(&now);
struct tm* nowtm = ::localtime(&now);
char time[64];
::strftime(time,sizeof(time),TIMEFORMAT,nowtm);
SDL_SaveBMP(this->screen,time);
void ScreenImage::saveBMP() {
time_t now;
::time(&now);
struct tm* nowtm = ::localtime(&now);
char time[64];
::strftime(time, sizeof (time), TIMEFORMAT, nowtm);
// TODO fix screenshot SDL_SaveBMP(this->screen, time);
}

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#ifndef SCREENIMAGE_H
#define SCREENIMAGE_H
@ -23,72 +23,77 @@
#include <string>
class Card;
struct SDL_Surface;
struct SDL_Texture;
struct SDL_Renderer;
struct SDL_Window;
class ScreenImage
{
class ScreenImage {
private:
SDL_Surface* screen;
bool fullscreen;
bool hyper;
bool buffer;
bool fillLines;
AnalogTV::DisplayType display;
unsigned int cmdpos;
void createScreen();
std::vector<std::string> slotnames;
std::string cassettename;
SDL_Window* window;
SDL_Renderer* renderer;
SDL_Texture* texture;
unsigned int* pixels;
int screen_pitch;
bool fullscreen;
bool hyper;
bool buffer;
bool fillLines;
AnalogTV::DisplayType display;
unsigned int cmdpos;
void createScreen();
std::vector<std::string> slotnames;
std::string cassettename;
static std::string truncateFilePath(const std::string& filepath);
static std::string truncateFilePath(const std::string& filepath);
// TODO some of these methods should be private
// TODO some of these methods should be private
public:
ScreenImage();
~ScreenImage();
ScreenImage();
~ScreenImage();
void toggleFullScreen();
void drawPower(bool on);
void notifyObservers();
void setElem(const unsigned int i, const unsigned int val);
void blank();
void drawText(const std::string& text, int row, int col, int color = 0xFFFFFF, int bgcolor = 0);
void drawChar(const char ch, int row, int col, int color = 0xFFFFFF, int bgcolor = 0);
void drawLabels();
void drawSlots();
void drawSlot(int slot, int r, int c);
void drawCassette();
void drawFnKeys();
void toggleHyperLabel();
void toggleKdbBufferLabel();
void cycleDisplayLabel();
void displayHz(int hz);
void toggleFillLinesLabel();
void invertText(int row, int begincol, int endcol);
void drawDisplayLabel();
void updateSlotName(const int slot, Card* card);
void removeCard(const int slot, Card* card /* empty */);
void toggleFullScreen();
void drawPower(bool on);
void notifyObservers();
void setElem(const unsigned int i, const unsigned int val);
void blank();
void drawText(const std::string& text, int row, int col, int color = 0xFFFFFF, int bgcolor = 0);
void drawChar(const char ch, int row, int col, int color = 0xFFFFFF, int bgcolor = 0);
void drawLabels();
void drawSlots();
void drawSlot(int slot, int r, int c);
void drawCassette();
void drawFnKeys();
void toggleHyperLabel();
void toggleKdbBufferLabel();
void cycleDisplayLabel();
void displayHz(int hz);
void toggleFillLinesLabel();
void invertText(int row, int begincol, int endcol);
void drawDisplayLabel();
void updateSlotName(const int slot, Card* card);
void removeCard(const int slot, Card* card /* empty */);
void enterCommandMode();
void exitCommandMode();
void addkeyCommand(unsigned char key);
void backspaceCommand();
void enterCommandMode();
void exitCommandMode();
void addkeyCommand(unsigned char key);
void backspaceCommand();
void setDiskFile(int slot, int drive, const std::string& filename);
void setDiskFile(int slot, int drive, const std::string& filename);
void clearCurrentDrive(int slt, int drv);
void setCurrentDrive(int slt, int drv, int track, bool on);
void setTrack(int slot, int drive, int track);
void setIO(int slot, int drive, bool on);
void setDirty(int slot, int drive, bool dirty);
void clearCurrentDrive(int slt, int drv);
void setCurrentDrive(int slt, int drv, int track, bool on);
void setTrack(int slot, int drive, int track);
void setIO(int slot, int drive, bool on);
void setDirty(int slot, int drive, bool dirty);
void setCassetteFile(const std::string& filepath);
void setCassetteDirty(bool dirty);
void setCassettePos(int pos, int siz);
void setCassetteFile(const std::string& filepath);
void setCassetteDirty(bool dirty);
void setCassettePos(int pos, int siz);
void setLangCard(int slot, bool readEnable, bool writeEnable, int bank);
void setFirmCard(int slot, bool bank, bool F8);
void setLangCard(int slot, bool readEnable, bool writeEnable, int bank);
void setFirmCard(int slot, bool bank, bool F8);
void saveBMP();
void saveBMP();
};
#endif