mirror of
https://github.com/cmosher01/Epple-II.git
synced 2024-06-24 12:29:32 +00:00
video working OK (still slow, though)
This commit is contained in:
parent
6a2b84794c
commit
13481ab90e
37
src/gui.cpp
37
src/gui.cpp
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user