Initial commit
This commit is contained in:
903
engines/saga2/document.cpp
Normal file
903
engines/saga2/document.cpp
Normal file
@@ -0,0 +1,903 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* 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
|
||||
* aint32 with this program; if not, write to the Free Software
|
||||
*
|
||||
*
|
||||
* Based on the original sources
|
||||
* Faery Tale II -- The Halls of the Dead
|
||||
* (c) 1993-1996 The Wyrmkeep Entertainment Co.
|
||||
*/
|
||||
|
||||
#include "common/keyboard.h"
|
||||
|
||||
#include "saga2/saga2.h"
|
||||
#include "saga2/document.h"
|
||||
#include "saga2/script.h"
|
||||
#include "saga2/intrface.h"
|
||||
#include "saga2/grequest.h"
|
||||
#include "saga2/mouseimg.h"
|
||||
#include "saga2/version.h"
|
||||
#include "saga2/fontlib.h"
|
||||
|
||||
namespace Saga2 {
|
||||
|
||||
/* ===================================================================== *
|
||||
About box
|
||||
* ===================================================================== */
|
||||
|
||||
#define PROGRAM_ABOUT " v" VERSION_OPSYS " " VERSION_STAMP
|
||||
|
||||
|
||||
// externs
|
||||
extern BackWindow *mainWindow;
|
||||
|
||||
// declarations
|
||||
APPFUNC(cmdDocumentQuit);
|
||||
|
||||
|
||||
/* ===================================================================== *
|
||||
scroll metrics
|
||||
* ===================================================================== */
|
||||
|
||||
// buttons
|
||||
//Rect16 closeScrollBtnRect( 184, 206, 44, 42 );
|
||||
|
||||
// options dialog window decorations
|
||||
static StaticWindow scrollDecorations[] = {
|
||||
{{202, 54, 232, 100}, nullptr, 0},
|
||||
{{212, 154, 212, 100}, nullptr, 1},
|
||||
{{202, 254, 236, 117}, nullptr, 2}
|
||||
};
|
||||
|
||||
static uint8 scrollTextColors[] = { 65, 65, 65, 65, 65, 65, 65, 66, 66, 67, 67, 67, 67, 66, 66, 66 };
|
||||
|
||||
CDocumentAppearance scrollAppearance = {
|
||||
{202, 54, 236, 317},
|
||||
1,
|
||||
kPageOrientVertical,
|
||||
scrollTextColors,
|
||||
{ {50, 64, 131, 169}, {0, 0, 0, 0} },
|
||||
{184, 206, 44, 42},
|
||||
scrollDecorations,
|
||||
ARRAYSIZE(scrollDecorations),
|
||||
MKTAG('S', 'C', 'R', 'L'),
|
||||
MKTAG('S', 'R', 'L', 0)
|
||||
};
|
||||
|
||||
/* ===================================================================== *
|
||||
Book metrics
|
||||
* ===================================================================== */
|
||||
|
||||
// options dialog window decorations
|
||||
static StaticWindow bookDecorations[] = {
|
||||
{{123, 76, 394, 88}, nullptr, 0},
|
||||
{{123, 164, 394, 80}, nullptr, 1},
|
||||
{{123, 244, 394, 77}, nullptr, 2}
|
||||
};
|
||||
|
||||
static uint8 bookTextColors[] = { 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65 };
|
||||
|
||||
CDocumentAppearance bookAppearance = {
|
||||
{123, 76, 394, 252},
|
||||
2,
|
||||
kPageOrientHorizontal,
|
||||
bookTextColors,
|
||||
{ {40, 26, 135, 205}, {218, 26, 135, 205} },
|
||||
{231, 217, 34, 27},
|
||||
bookDecorations,
|
||||
ARRAYSIZE(bookDecorations),
|
||||
MKTAG('B', 'O', 'O', 'K'),
|
||||
MKTAG('B', 'K', 'D', 0)
|
||||
};
|
||||
|
||||
/* ===================================================================== *
|
||||
Parchment metrics
|
||||
* ===================================================================== */
|
||||
|
||||
// options dialog window decorations
|
||||
static StaticWindow parchDecorations[] = {
|
||||
{{202, 54, 208, 256}, nullptr, 0}
|
||||
};
|
||||
|
||||
CDocumentAppearance parchAppearance = {
|
||||
{202, 54, 208, 256},
|
||||
1,
|
||||
kPageOrientVertical,
|
||||
bookTextColors,
|
||||
{ {27, 18, 149, 212}, {0, 0, 0, 0} },
|
||||
{164, 229, 20, 20},
|
||||
parchDecorations,
|
||||
ARRAYSIZE(parchDecorations),
|
||||
MKTAG('P', 'A', 'R', 'C'),
|
||||
MKTAG('P', 'C', 'H', 0)
|
||||
};
|
||||
|
||||
// deliminator defines
|
||||
char deliminator = '@';
|
||||
char dPageBreak[3] = { "pb" };
|
||||
char dImage[3] = { "im" };
|
||||
|
||||
/* ===================================================================== *
|
||||
Document base class
|
||||
* ===================================================================== */
|
||||
|
||||
CDocument::CDocument(CDocumentAppearance &dApp,
|
||||
char *buffer, // buffer to edit
|
||||
gFont *font, // font of the text
|
||||
uint16 ident, // control ID
|
||||
AppFunc *cmd) // application command func
|
||||
: _app(dApp), ModalWindow(dApp.windowPos, ident, cmd) {
|
||||
// resource handle
|
||||
hResContext *decRes;
|
||||
|
||||
// init the resource context handle
|
||||
decRes = resFile->newContext(_app.groupID, "docimage context");
|
||||
|
||||
// init con pointer to NULL
|
||||
_illustrationCon = nullptr;
|
||||
|
||||
// set the maxium string length
|
||||
_maxSize = kMaxPages * kMaxLines * kMaxChars;
|
||||
|
||||
// get the org text size
|
||||
_textSize = clamp(0, strlen(buffer), _maxSize);
|
||||
|
||||
// set the original text pointer
|
||||
origText = new char[_textSize + 1];
|
||||
|
||||
// and fill it
|
||||
Common::strlcpy(origText, buffer, _textSize + 1);
|
||||
|
||||
// make a working buffer
|
||||
text = new char[_textSize + 1];
|
||||
|
||||
// and fill it
|
||||
Common::strlcpy(text, origText, _textSize + 1);
|
||||
|
||||
_textFont = font;
|
||||
_textHeight = (_textFont ? _textFont->height : 0);
|
||||
_lineWidth = dApp.pageRect[0].width;
|
||||
_pageHeight = dApp.pageRect[0].height;
|
||||
_currentPage = 0;
|
||||
_totalLines = 0;
|
||||
_totalPages = 0;
|
||||
_pageBreakSet = true;
|
||||
|
||||
// null out the image pointer array
|
||||
for (int16 i = 0; i < kMaxPages; i++) {
|
||||
_images[i] = nullptr;
|
||||
}
|
||||
|
||||
makePages();
|
||||
|
||||
// attach the graphics for the book
|
||||
setDecorations(_app.decoList,
|
||||
_app.numDecos,
|
||||
decRes, _app.decoID);
|
||||
|
||||
// remove the resource handle
|
||||
if (decRes) resFile->disposeContext(decRes);
|
||||
decRes = nullptr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
CDocument::~CDocument() {
|
||||
int16 i;
|
||||
|
||||
for (i = 0; i < kMaxPages; i++) {
|
||||
if (_images[i]) {
|
||||
free(_images[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// get rid of the working text buffer
|
||||
if (text) {
|
||||
delete[] text;
|
||||
text = nullptr;
|
||||
}
|
||||
|
||||
if (origText) {
|
||||
delete[] origText;
|
||||
origText = nullptr;
|
||||
}
|
||||
|
||||
// get rid of the resource context
|
||||
if (_illustrationCon)
|
||||
resFile->disposeContext(_illustrationCon);
|
||||
}
|
||||
|
||||
void CDocument::deactivate() {
|
||||
_selected = 0;
|
||||
gPanel::deactivate();
|
||||
}
|
||||
|
||||
bool CDocument::activate(gEventType why) {
|
||||
if (why == kEventMouseDown) { // momentarily depress
|
||||
_selected = 1;
|
||||
notify(why, 0); // notify App of successful hit
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDocument::keyStroke(gPanelMessage &msg) {
|
||||
gEvent ev;
|
||||
switch (msg._key) {
|
||||
case Common::ASCII_ESCAPE:
|
||||
cmdDocumentEsc(ev);
|
||||
return true;
|
||||
case Common::KEYCODE_LEFT:
|
||||
cmdDocumentLt(ev);
|
||||
return true;
|
||||
case Common::KEYCODE_RIGHT:
|
||||
cmdDocumentRt(ev);
|
||||
return true;
|
||||
case Common::KEYCODE_UP:
|
||||
cmdDocumentUp(ev);
|
||||
return true;
|
||||
case Common::KEYCODE_DOWN:
|
||||
cmdDocumentDn(ev);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
gPanel *CDocument::keyTest(int16 key) {
|
||||
switch (key) {
|
||||
case Common::ASCII_ESCAPE:
|
||||
case Common::KEYCODE_LEFT:
|
||||
case Common::KEYCODE_RIGHT:
|
||||
case Common::KEYCODE_UP:
|
||||
case Common::KEYCODE_DOWN:
|
||||
return this;
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Cursor images for turning book pages
|
||||
void CDocument::pointerMove(gPanelMessage &msg) {
|
||||
Point16 pos = msg._pickPos;
|
||||
|
||||
if (msg._inPanel && Rect16(0, 0, _extent.width, _extent.height).ptInside(pos)) {
|
||||
if (_app.orientation == kPageOrientVertical) {
|
||||
// find out which end of the book we're on
|
||||
if (pos.y < _extent.height / 2) setMouseImage(kMousePgUpImage, -7, -7);
|
||||
else setMouseImage(kMousePgDownImage, -7, -7);
|
||||
} else {
|
||||
// find out which side of the book we're on
|
||||
if (pos.x < _extent.width / 2) setMouseImage(kMousePgLeftImage, -7, -7);
|
||||
else setMouseImage(kMousePgRightImage, -7, -7);
|
||||
}
|
||||
} else if (msg._pointerLeave) {
|
||||
setMouseImage(kMouseArrowImage, 0, 0);
|
||||
}
|
||||
|
||||
notify(kEventMouseMove, 0);
|
||||
}
|
||||
|
||||
void CDocument::pointerDrag(gPanelMessage &) {
|
||||
if (_selected) {
|
||||
notify(kEventMouseDrag, 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool CDocument::pointerHit(gPanelMessage &msg) {
|
||||
Point16 pos = msg._pickPos;
|
||||
|
||||
if (msg._inPanel && Rect16(0, 0, _extent.width, _extent.height).ptInside(pos)) {
|
||||
gEvent ev;
|
||||
if (_app.orientation == kPageOrientVertical) {
|
||||
// find out which end of the book we're on
|
||||
if (pos.y < _extent.height / 2) cmdDocumentUp(ev); //gotoPage( _currentPage - _app.numPages );
|
||||
else cmdDocumentDn(ev); //gotoPage( _currentPage + _app.numPages );
|
||||
} else {
|
||||
// find out which side of the book we're on
|
||||
if (pos.x < _extent.width / 2) cmdDocumentLt(ev); //gotoPage( _currentPage - _app.numPages );
|
||||
else cmdDocumentRt(ev); //gotoPage( _currentPage + _app.numPages );
|
||||
}
|
||||
} else {
|
||||
// mouse hit outside book area, close book
|
||||
gWindow *win;
|
||||
requestInfo *ri;
|
||||
|
||||
win = getWindow(); // get the window pointer
|
||||
ri = win ? (requestInfo *)win->_userData : nullptr;
|
||||
|
||||
if (ri) {
|
||||
ri->running = 0;
|
||||
ri->result = _id;
|
||||
|
||||
setMouseImage(kMouseArrowImage, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
activate(kEventMouseDown);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDocument::gotoPage(int8 page) {
|
||||
page = clamp(0, page, kMaxPages);
|
||||
|
||||
while (page % _app.numPages) page++;
|
||||
|
||||
if (page != _currentPage && page < _pages) {
|
||||
_currentPage = page;
|
||||
renderText();
|
||||
}
|
||||
}
|
||||
|
||||
void CDocument::pointerRelease(gPanelMessage &) {
|
||||
if (_selected) notify(kEventMouseUp, 0); // notify App of successful hit
|
||||
deactivate();
|
||||
}
|
||||
|
||||
bool CDocument::checkForPageBreak(char *string, uint16 index, int32 &offset) {
|
||||
|
||||
// get the current index into the string
|
||||
char *strIndex = string + index;
|
||||
|
||||
// page break detected
|
||||
if (strIndex[1] == dPageBreak[0] &&
|
||||
strIndex[2] == dPageBreak[1]) {
|
||||
// eat the page breaks chars
|
||||
// tie off the end
|
||||
strIndex[0] = 0;
|
||||
|
||||
size_t txtlen = strlen(&strIndex[3]);
|
||||
|
||||
// string them together
|
||||
memmove(&strIndex[0], &strIndex[3], txtlen);
|
||||
|
||||
// take the offset to the end of this line
|
||||
offset = index;
|
||||
|
||||
// and set the new page flag
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDocument::checkForImage(char *string,
|
||||
uint16 index,
|
||||
uint16 pageIndex,
|
||||
int32 &offset) {
|
||||
// get the current index into the string
|
||||
char *strIndex = string + index;
|
||||
uint16 offPageIndex = pageIndex;
|
||||
|
||||
|
||||
// if there was not just a page break
|
||||
if (!_pageBreakSet) {
|
||||
// then the images are going to end up on the next page
|
||||
offPageIndex++;
|
||||
}
|
||||
|
||||
|
||||
// image detected marker
|
||||
if (strIndex[1] == dImage[0] &&
|
||||
strIndex[2] == dImage[1]) {
|
||||
int16 numEat = 0; // number of characters to eat
|
||||
char *argv = &strIndex[2 + 1]; // array to first element
|
||||
|
||||
// delete context
|
||||
if (_illustrationCon) resFile->disposeContext(_illustrationCon);
|
||||
|
||||
// resource handle
|
||||
_illustrationCon = resFile->newContext(MKTAG(argv[0], argv[1], argv[2], argv[3]),
|
||||
"book internal resources");
|
||||
// set image for next page
|
||||
if (offPageIndex < kMaxPages) {
|
||||
// if the last entry is defined as a number
|
||||
if (argv[7] == ':') {
|
||||
// convert the text into a number
|
||||
char numSt[2] = { argv[8], 0 };
|
||||
uint8 num = atoi(numSt);
|
||||
|
||||
|
||||
if (!_images[offPageIndex]) {
|
||||
// get the image
|
||||
_images[offPageIndex] = LoadResource(_illustrationCon,
|
||||
MKTAG(argv[4], argv[5], argv[6], num),
|
||||
"book internal image");
|
||||
}
|
||||
|
||||
// number of chars to eat
|
||||
numEat = 9;
|
||||
} else {
|
||||
_images[offPageIndex] = LoadResource(_illustrationCon,
|
||||
MKTAG(argv[4], argv[5], argv[6], argv[7]),
|
||||
"book internal image");
|
||||
numEat = 8;
|
||||
}
|
||||
|
||||
// get the size of the image
|
||||
_imageSizes[offPageIndex] = ((ImageHeader *)_images[offPageIndex])->size;
|
||||
|
||||
// tie off the end
|
||||
strIndex[0] = 0;
|
||||
|
||||
// and string them together
|
||||
// strIndex is inside text buffer
|
||||
Common::strcat_s(&strIndex[0], _textSize + 1 - (&strIndex[0] - text), &strIndex[2 + 1 + numEat]);
|
||||
|
||||
// set new line length
|
||||
offset = index;
|
||||
|
||||
// set the line offset
|
||||
_lineOffset[offPageIndex] =
|
||||
_imageSizes[offPageIndex].y / (_textHeight + 1) +
|
||||
kTextPictureOffset;
|
||||
} else {
|
||||
warning("CDocument: Document overflow");
|
||||
}
|
||||
|
||||
// set the new page flag
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CDocument::makePages() {
|
||||
// copy the original text back to the working buffer
|
||||
Common::strlcpy(text, origText, _textSize + 1);
|
||||
|
||||
|
||||
char *str = text;
|
||||
int32 offset = 0;
|
||||
uint16 lineIndex = 0;
|
||||
uint16 pageIndex = 0;
|
||||
uint16 linesPerPage = _pageHeight / (_textHeight + 1);
|
||||
uint16 dummy;
|
||||
uint16 i;
|
||||
bool newPage = false;
|
||||
|
||||
|
||||
while (offset >= 0 && pageIndex < kMaxPages) {
|
||||
while (offset >= 0 &&
|
||||
lineIndex < linesPerPage &&
|
||||
!newPage) {
|
||||
offset = GTextWrap(_textFont, str, dummy, _lineWidth, 0);
|
||||
|
||||
// check for page breaks and images
|
||||
for (i = 0; i <= offset; i++) {
|
||||
// we hit a diliminator
|
||||
if (str[i] == deliminator) {
|
||||
// page break check
|
||||
if (checkForPageBreak(str, i, offset)) {
|
||||
// if a break did not just occur
|
||||
if (!_pageBreakSet) {
|
||||
newPage = true;
|
||||
_pageBreakSet = true;
|
||||
} else {
|
||||
// eat the newPage and
|
||||
// reset the flag for a just set break
|
||||
_pageBreakSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
// image check
|
||||
if (checkForImage(str, i, pageIndex, offset)) {
|
||||
// if a break did not just occur
|
||||
if (!_pageBreakSet) {
|
||||
newPage = true;
|
||||
_pageBreakSet = true;
|
||||
} else {
|
||||
// eat the newPage and
|
||||
// reset the flag for a just set break
|
||||
_pageBreakSet = false;
|
||||
}
|
||||
|
||||
lineIndex = _lineOffset[pageIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// we got token that was not a page break so reset the flag
|
||||
_pageBreakSet = false;
|
||||
}
|
||||
|
||||
// set the length of this line
|
||||
if (offset >= 0) {
|
||||
// number of characters on this line
|
||||
_lineLen[pageIndex][lineIndex] = offset;
|
||||
} else {
|
||||
// remaining number of characters in string
|
||||
_lineLen[pageIndex][lineIndex] = strlen(str);
|
||||
}
|
||||
|
||||
|
||||
// increment the str pointer and line index
|
||||
str += offset;
|
||||
lineIndex++;
|
||||
}
|
||||
|
||||
_numLines[pageIndex] = lineIndex;
|
||||
pageIndex++;
|
||||
newPage = false;
|
||||
|
||||
lineIndex = 0;
|
||||
}
|
||||
|
||||
_pages = pageIndex;
|
||||
}
|
||||
|
||||
// This function will draw the text onto the book.
|
||||
void CDocument::renderText() {
|
||||
gPort tPort;
|
||||
gPort &port = _window._windowPort;
|
||||
uint16 pageIndex;
|
||||
uint16 lineIndex;
|
||||
uint16 linesPerPage = _pageHeight / (_textHeight + 1);
|
||||
char *str = text;
|
||||
|
||||
assert(_textFont);
|
||||
|
||||
Rect16 bltRect(0, 0, _extent.width, _extent.height);
|
||||
|
||||
if (NewTempPort(tPort, bltRect.width, bltRect.height)) {
|
||||
// clear out the text buffer
|
||||
int16 i, k;
|
||||
uint8 *buffer = (uint8 *)tPort._map->_data;
|
||||
|
||||
for (i = 0; i < tPort._map->_size.x; i++) {
|
||||
for (k = 0; k < tPort._map->_size.y; k++) {
|
||||
*buffer++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// draw a new copy of the background to the temp port
|
||||
drawClipped(tPort,
|
||||
Point16(_extent.x, _extent.y),
|
||||
Rect16(0, 0, _extent.width, _extent.height));
|
||||
|
||||
tPort.setFont(_textFont); // setup the string pointer
|
||||
for (pageIndex = 0; pageIndex < _currentPage; pageIndex++) {
|
||||
if (_images[pageIndex]) {
|
||||
lineIndex = _lineOffset[pageIndex];
|
||||
|
||||
assert(lineIndex < linesPerPage);
|
||||
} else {
|
||||
lineIndex = 0;
|
||||
}
|
||||
|
||||
for (; lineIndex < _numLines[pageIndex]; lineIndex++) {
|
||||
int16 temp = _lineLen[pageIndex][lineIndex];
|
||||
|
||||
assert(pageIndex < kMaxPages);
|
||||
assert(temp < 35);
|
||||
|
||||
str += _lineLen[pageIndex][lineIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// draw the text onto the pages of the book
|
||||
for (pageIndex = _currentPage;
|
||||
pageIndex - _currentPage < _app.numPages && pageIndex < _pages;
|
||||
pageIndex++) {
|
||||
StaticRect *pageRect = &_app.pageRect[pageIndex % _app.numPages];
|
||||
|
||||
// if there is an image on this page
|
||||
if (_images[pageIndex]) {
|
||||
Point16 pos;
|
||||
|
||||
pos.x = pageRect->x + (pageRect->width - _imageSizes[pageIndex].x) / 2;
|
||||
pos.y = pageRect->y;
|
||||
|
||||
drawCompressedImage(tPort, pos, _images[pageIndex]);
|
||||
|
||||
lineIndex = _lineOffset[pageIndex];
|
||||
} else {
|
||||
lineIndex = 0;
|
||||
}
|
||||
|
||||
for (; lineIndex < _numLines[pageIndex]; lineIndex++) {
|
||||
assert(pageIndex <= kMaxPages);
|
||||
|
||||
tPort.moveTo(pageRect->x, pageRect->y + (_textHeight * lineIndex) + 1);
|
||||
tPort.setColor(_app.textColors[lineIndex]);
|
||||
tPort.drawText(str, _lineLen[pageIndex][lineIndex]);
|
||||
|
||||
// grab the next text offset
|
||||
int16 temp = _lineLen[pageIndex][lineIndex];
|
||||
|
||||
assert(temp < 35);
|
||||
|
||||
str += _lineLen[pageIndex][lineIndex];
|
||||
}
|
||||
}
|
||||
|
||||
port.setMode(kDrawModeMatte);
|
||||
|
||||
g_vm->_pointer->hide();
|
||||
|
||||
port.bltPixels(*tPort._map, 0, 0,
|
||||
bltRect.x, bltRect.y,
|
||||
bltRect.width, bltRect.height);
|
||||
|
||||
g_vm->_pointer->show();
|
||||
|
||||
DisposeTempPort(tPort); // dispose of temporary pixelmap
|
||||
}
|
||||
}
|
||||
|
||||
void CDocument::drawClipped(
|
||||
gPort &port,
|
||||
const Point16 &offset,
|
||||
const Rect16 &clipRect) {
|
||||
g_vm->_pointer->hide();
|
||||
ModalWindow::drawClipped(port, offset, clipRect);
|
||||
g_vm->_pointer->show();
|
||||
}
|
||||
|
||||
void CDocument::draw() { // redraw the window
|
||||
// draw the book image
|
||||
drawClipped(g_vm->_mainPort, Point16(0, 0), _extent);
|
||||
|
||||
// draw the text onto the book
|
||||
renderText();
|
||||
}
|
||||
|
||||
/////////
|
||||
// Notes
|
||||
|
||||
/*
|
||||
// page breaks like:
|
||||
@pb
|
||||
|
||||
// images declared like:
|
||||
@imDIALBTN:8
|
||||
@imCONTHED:0
|
||||
|
||||
*/
|
||||
|
||||
/* ===================================================================== *
|
||||
Text buffer
|
||||
* ===================================================================== */
|
||||
|
||||
const int _textSize = 4096;
|
||||
char bookText[_textSize] = { "" };
|
||||
|
||||
void appendBookText(char *string) {
|
||||
if (string) {
|
||||
Common::strlcat(bookText, string, _textSize - 1);
|
||||
bookText[_textSize - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===================================================================== *
|
||||
scroll window
|
||||
* ===================================================================== */
|
||||
|
||||
void buildText(uint16 textScript) {
|
||||
if (textScript > 0) {
|
||||
// clear out the scroll text
|
||||
Common::strlcpy(bookText, "", sizeof(bookText));
|
||||
|
||||
if (textScript == resImports->reserved[0]) {
|
||||
Common::strlcpy(bookText, PROGRAM_ABOUT, sizeof(bookText));
|
||||
}
|
||||
|
||||
// generate the text for the book
|
||||
scriptCallFrame scf;
|
||||
|
||||
scf.invokedObject = Nothing;
|
||||
scf.enactor = Nothing;
|
||||
scf.directObject = Nothing;
|
||||
scf.indirectObject = Nothing;
|
||||
scf.value = 0;
|
||||
|
||||
// Run the script
|
||||
runScript(textScript, scf);
|
||||
} else {
|
||||
Common::sprintf_s(bookText, "Invalid textScript: %d", textScript);
|
||||
}
|
||||
}
|
||||
|
||||
int16 openScroll(uint16 textScript) {
|
||||
buildText(textScript);
|
||||
|
||||
// requester info struct
|
||||
requestInfo rInfo;
|
||||
|
||||
rInfo.result = -1;
|
||||
rInfo.running = true;
|
||||
|
||||
|
||||
// point to book
|
||||
CDocument *win = nullptr;
|
||||
|
||||
// close button
|
||||
GfxCompButton *closeScroll;
|
||||
void **closeBtnImage;
|
||||
uint16 buttonResID = 0;
|
||||
hResContext *decRes;
|
||||
|
||||
// init the resource context handle
|
||||
decRes = resFile->newContext(MKTAG('S', 'C', 'R', 'L'), "book resources");
|
||||
|
||||
// get the graphics associated with the buttons
|
||||
closeBtnImage = loadButtonRes(decRes, buttonResID, kNumBtnImages);
|
||||
|
||||
// create the window
|
||||
win = new CDocument(scrollAppearance, bookText, &Script10Font, 0, nullptr);
|
||||
|
||||
// make the quit button
|
||||
closeScroll = new GfxCompButton(*win, scrollAppearance.closeRect, closeBtnImage, kNumBtnImages, 0, cmdDocumentQuit);
|
||||
|
||||
closeScroll->_accelKey = 0x1B;
|
||||
|
||||
// attach the structure to the book, open the book
|
||||
win->_userData = &rInfo;
|
||||
win->open();
|
||||
|
||||
// do stuff
|
||||
EventLoop(rInfo.running, true);
|
||||
|
||||
// remove the window all attatched controls
|
||||
delete win;
|
||||
|
||||
// unload all image arrays
|
||||
unloadImageRes(closeBtnImage, kNumBtnImages);
|
||||
|
||||
// remove the resource handle
|
||||
if (decRes)
|
||||
resFile->disposeContext(decRes);
|
||||
|
||||
// return the result code
|
||||
return rInfo.result;
|
||||
}
|
||||
|
||||
/* ===================================================================== *
|
||||
Book window
|
||||
* ===================================================================== */
|
||||
|
||||
int16 openBook(uint16 textScript) {
|
||||
|
||||
buildText(textScript);
|
||||
|
||||
// requester info struct
|
||||
requestInfo rInfo;
|
||||
|
||||
rInfo.result = -1;
|
||||
rInfo.running = true;
|
||||
|
||||
|
||||
// point to book
|
||||
CDocument *win = nullptr;
|
||||
|
||||
GfxCompButton *closeBook;
|
||||
hResContext *decRes;
|
||||
|
||||
decRes = resFile->newContext(MKTAG('S', 'C', 'R', 'L'), "book resources");
|
||||
|
||||
// create the window
|
||||
win = new CDocument(bookAppearance, bookText, &Script10Font, 0, nullptr);
|
||||
|
||||
// make the quit button
|
||||
closeBook = new GfxCompButton(*win, bookAppearance.closeRect, cmdDocumentQuit);
|
||||
closeBook->_accelKey = 0x1B;
|
||||
|
||||
// attach the structure to the book, open the book
|
||||
win->_userData = &rInfo;
|
||||
win->open();
|
||||
|
||||
// do stuff
|
||||
EventLoop(rInfo.running, true);
|
||||
|
||||
// remove the window all attatched controls
|
||||
delete win;
|
||||
|
||||
if (decRes)
|
||||
resFile->disposeContext(decRes);
|
||||
|
||||
// return the result code
|
||||
return rInfo.result;
|
||||
}
|
||||
|
||||
/* ===================================================================== *
|
||||
Parchment window
|
||||
* ===================================================================== */
|
||||
|
||||
int16 openParchment(uint16 textScript) {
|
||||
buildText(textScript);
|
||||
|
||||
// requester info struct
|
||||
requestInfo rInfo;
|
||||
|
||||
rInfo.result = -1;
|
||||
rInfo.running = true;
|
||||
|
||||
|
||||
// point to book
|
||||
CDocument *win = nullptr;
|
||||
|
||||
GfxCompButton *closeParchment;
|
||||
hResContext *decRes;
|
||||
|
||||
decRes = resFile->newContext(MKTAG('S', 'C', 'R', 'L'), "book resources");
|
||||
|
||||
// create the window
|
||||
win = new CDocument(parchAppearance, bookText, &Script10Font, 0, nullptr);
|
||||
// make the quit button
|
||||
closeParchment = new GfxCompButton(*win, parchAppearance.closeRect, cmdDocumentQuit);
|
||||
closeParchment->_accelKey = 0x1B;
|
||||
|
||||
// attach the structure to the book, open the book
|
||||
win->_userData = &rInfo;
|
||||
win->open();
|
||||
|
||||
// do stuff
|
||||
EventLoop(rInfo.running, true);
|
||||
|
||||
// remove the window all attatched controls
|
||||
delete win;
|
||||
|
||||
if (decRes)
|
||||
resFile->disposeContext(decRes);
|
||||
|
||||
// return the result code
|
||||
return rInfo.result;
|
||||
}
|
||||
|
||||
APPFUNC(cmdDocumentQuit) {
|
||||
gWindow *win;
|
||||
requestInfo *ri;
|
||||
|
||||
if (ev.panel && ev.eventType == kEventNewValue && ev.value) {
|
||||
win = ev.panel->getWindow(); // get the window pointer
|
||||
ri = win ? (requestInfo *)win->_userData : nullptr;
|
||||
|
||||
if (ri) {
|
||||
ri->running = 0;
|
||||
ri->result = ev.panel->_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
APPFUNCV(CDocument::cmdDocumentEsc) {
|
||||
requestInfo *ri = (requestInfo *)_userData;
|
||||
if (ri) {
|
||||
ri->running = 0;
|
||||
ri->result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
APPFUNCV(CDocument::cmdDocumentLt) {
|
||||
gotoPage(_currentPage - _app.numPages); //draw();
|
||||
}
|
||||
|
||||
APPFUNCV(CDocument::cmdDocumentRt) {
|
||||
gotoPage(_currentPage + _app.numPages); //draw();
|
||||
}
|
||||
|
||||
APPFUNCV(CDocument::cmdDocumentUp) {
|
||||
gotoPage(_currentPage - _app.numPages); //draw();
|
||||
}
|
||||
|
||||
APPFUNCV(CDocument::cmdDocumentDn) {
|
||||
gotoPage(_currentPage + _app.numPages); //draw();
|
||||
}
|
||||
|
||||
} // end of namespace Saga2
|
||||
Reference in New Issue
Block a user