2012-04-21 00:04:34 +00:00
|
|
|
/*
|
|
|
|
epple2
|
|
|
|
Copyright (C) 2008 by Chris Mosher <chris@mosher.mine.nu>
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY, without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2013-10-10 03:23:33 +00:00
|
|
|
*/
|
2012-04-21 00:04:34 +00:00
|
|
|
#include "screenimage.h"
|
|
|
|
#include "e2const.h"
|
|
|
|
#include "applentsc.h"
|
|
|
|
#include "card.h"
|
|
|
|
#include "util.h"
|
2013-10-08 14:29:28 +00:00
|
|
|
#include <SDL2/SDL.h>
|
2013-10-10 03:23:33 +00:00
|
|
|
#include <iostream>
|
2012-04-21 00:04:34 +00:00
|
|
|
#include <ctime>
|
|
|
|
#include <sstream>
|
2013-12-16 05:21:19 +00:00
|
|
|
#include <cstdio>
|
2013-12-17 03:11:11 +00:00
|
|
|
#include <cstring>
|
2012-04-21 00:04:34 +00:00
|
|
|
|
|
|
|
static const char* power =
|
2013-10-10 03:23:33 +00:00
|
|
|
" @@@@ @@@ @ @ @ @@@@@ @@@@ "
|
|
|
|
" @ @ @ @ @ @ @ @ @ @ @"
|
|
|
|
" @ @ @ @ @ @ @ @ @ @ @"
|
|
|
|
" @@@@ @ @ @ @ @ @ @@@@@ @@@@ "
|
|
|
|
" @ @ @ @ @ @ @ @ @ @ "
|
|
|
|
" @ @ @ @ @ @ @ @ @ @ "
|
|
|
|
" @ @@@ @ @ @@@@@ @ @";
|
2012-04-21 00:04:34 +00:00
|
|
|
|
|
|
|
#define POWERD 56
|
|
|
|
#define LABEL_Y 24
|
|
|
|
#define ON_CLR 0xF0D050
|
|
|
|
#define OFF_CLR 0x807870
|
|
|
|
#define SCRW 640
|
|
|
|
#define SCRH 480
|
|
|
|
|
2013-10-10 03:23:33 +00:00
|
|
|
static const int HEIGHT = E2Const::VISIBLE_ROWS_PER_FIELD * 2;
|
|
|
|
static const int WIDTH = AppleNTSC::H - AppleNTSC::PIC_START - 2;
|
2012-04-21 00:04:34 +00:00
|
|
|
|
|
|
|
#include "font3x5.h"
|
|
|
|
|
2013-10-10 03:23:33 +00:00
|
|
|
class ScreenException {
|
2012-04-21 00:04:34 +00:00
|
|
|
};
|
|
|
|
|
2013-10-10 03:23:33 +00:00
|
|
|
ScreenImage::ScreenImage() :
|
|
|
|
fullscreen(false),
|
|
|
|
hyper(false),
|
|
|
|
buffer(true),
|
2013-10-11 02:59:38 +00:00
|
|
|
fillLines(true),
|
2013-10-10 03:23:33 +00:00
|
|
|
display(AnalogTV::MONITOR_COLOR),
|
|
|
|
slotnames(8),
|
|
|
|
cassettename(32, ' ') {
|
|
|
|
createScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenImage::toggleFullScreen() {
|
|
|
|
this->fullscreen = !this->fullscreen;
|
|
|
|
const int flags = this->fullscreen ? SDL_WINDOW_FULLSCREEN : 0;
|
|
|
|
SDL_SetWindowFullscreen(this->window, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
2015-07-15 03:07:26 +00:00
|
|
|
this->renderer = SDL_CreateRenderer(this->window, -1, 0/*SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC*/);
|
2013-10-10 03:23:33 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2013-10-11 02:59:38 +00:00
|
|
|
this->pixels = (unsigned int*) calloc(SCRW * SCRH, sizeof (unsigned int));
|
2013-10-10 03:23:33 +00:00
|
|
|
this->screen_pitch = SCRW;
|
|
|
|
|
|
|
|
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 ",
|
|
|
|
"GREEN MONITOR ",
|
2013-12-20 04:19:45 +00:00
|
|
|
"TELEVISION ",
|
2013-10-10 03:23:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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::toggleFillLinesLabel() {
|
|
|
|
this->fillLines = !this->fillLines;
|
|
|
|
invertText(76, 43, 55); // SCAN-LINES
|
|
|
|
invertText(77, 43, 55); // FILL-LINES
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenImage::drawDisplayLabel() {
|
|
|
|
const char* label = displays[(int) (this->display)];
|
|
|
|
drawText(label, 77, 17);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenImage::cycleDisplayLabel() {
|
|
|
|
this->display = (AnalogTV::DisplayType)((((int) this->display) + 1) % AnalogTV::NUM_DISPLAY_TYPES);
|
|
|
|
drawDisplayLabel();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenImage::toggleHyperLabel() {
|
|
|
|
this->hyper = !this->hyper;
|
|
|
|
invertText(77, 67, 74); // HYPER
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenImage::toggleKdbBufferLabel() {
|
|
|
|
this->buffer = !this->buffer;
|
|
|
|
invertText(77, 75, 83); // BUFFER
|
|
|
|
}
|
|
|
|
|
|
|
|
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::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::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;
|
|
|
|
|
|
|
|
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::displayHz(int hz) {
|
|
|
|
char s[20];
|
|
|
|
sprintf(s, "%4.2f MHz ", hz / 1e6);
|
|
|
|
drawText(s, 3, 141);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScreenImage::drawPower(bool on) {
|
|
|
|
unsigned int* pn = this->pixels;
|
2013-12-20 02:59:48 +00:00
|
|
|
pn += (HEIGHT + 5)*SCRW + 5;
|
2013-10-10 03:23:33 +00:00
|
|
|
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;
|
2013-12-20 02:59:48 +00:00
|
|
|
pn += SCRW;
|
2013-10-10 03:23:33 +00:00
|
|
|
}
|
|
|
|
notifyObservers();
|
|
|
|
}
|
|
|
|
|
|
|
|
ScreenImage::~ScreenImage() {
|
|
|
|
}
|
|
|
|
|
|
|
|
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::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);
|
2012-04-21 00:04:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
1 2 3 4 5 6 7 8
|
|
|
|
789012345678901234567890123456789012345678901234567890123456789012345
|
|
|
|
6: disk][ drive 1M*filename.nib T$FF drive 2M*filename.nib T$FF
|
2013-10-10 03:23:33 +00:00
|
|
|
*/
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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::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::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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2012-04-21 00:04:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
1 2 3 4 5 6 7 8
|
|
|
|
789012345678901234567890123456789012345678901234567890123456789012345678
|
|
|
|
0: language RW B2
|
2013-10-10 03:23:33 +00:00
|
|
|
*/
|
|
|
|
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';
|
2012-04-21 00:04:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
1 2 3 4 5 6 7 8
|
|
|
|
789012345678901234567890123456789012345678901234567890123456789012345678
|
|
|
|
0: firmware D F8
|
2013-10-10 03:23:33 +00:00
|
|
|
*/
|
|
|
|
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' : ' ';
|
2012-04-21 00:04:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define TIMEFORMAT "ep2_%Y%m%d%H%M%S.bmp"
|
|
|
|
|
2013-10-10 03:23:33 +00:00
|
|
|
void ScreenImage::saveBMP() {
|
|
|
|
time_t now;
|
|
|
|
::time(&now);
|
|
|
|
struct tm* nowtm = ::localtime(&now);
|
|
|
|
char time[64];
|
|
|
|
::strftime(time, sizeof (time), TIMEFORMAT, nowtm);
|
2013-10-17 01:47:59 +00:00
|
|
|
SDL_Surface* screenshot = SDL_CreateRGBSurfaceFrom(this->pixels,SCRW,SCRH,32,SCRW*4,0x00FF0000,0x0000FF00,0x000000FF,0xFF000000);
|
|
|
|
SDL_SaveBMP(screenshot, time);
|
|
|
|
SDL_FreeSurface(screenshot);
|
2012-04-21 00:04:34 +00:00
|
|
|
}
|