scummvm/engines/saga2/document.cpp

906 lines
22 KiB
C++
Raw Normal View History

2021-05-17 20:47:39 +02:00
/* 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.
2021-05-17 20:47:39 +02:00
*
* 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"
2021-06-23 14:41:01 +02:00
#include "saga2/saga2.h"
2021-05-17 20:47:39 +02:00
#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"
2021-05-17 20:47:39 +02:00
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}
2021-05-17 20:47:39 +02:00
};
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,
pageOrientVertical,
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)
};
2021-05-17 20:47:39 +02:00
/* ===================================================================== *
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}
2021-05-17 20:47:39 +02:00
};
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,
pageOrientHorizontal,
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)
};
2021-05-17 20:47:39 +02:00
/* ===================================================================== *
Parchment metrics
* ===================================================================== */
// options dialog window decorations
static StaticWindow parchDecorations[] = {
{{202, 54, 208, 256}, nullptr, 0}
};
2021-05-17 20:47:39 +02:00
CDocumentAppearance parchAppearance = {
{202, 54, 208, 256},
1,
pageOrientVertical,
bookTextColors,
{ {27, 18, 149, 212}, {0, 0, 0, 0} },
2021-07-29 13:39:13 +09:00
{164, 229, 20, 20},
parchDecorations,
ARRAYSIZE(parchDecorations),
MKTAG('P', 'A', 'R', 'C'),
MKTAG('P', 'C', 'H', 0)
};
2021-05-17 20:47:39 +02:00
// 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;
2021-05-17 20:47:39 +02:00
// set the maxium string length
maxSize = maxPages * maxLines * maxChars;
// get the org text size
textSize = clamp(0, strlen(buffer), maxSize);
// set the original text pointer
2021-06-07 18:19:10 +02:00
origText = new char[textSize + 1];
2021-05-17 20:47:39 +02:00
// and fill it
Common::strlcpy(origText, buffer, textSize + 1);
2021-05-17 20:47:39 +02:00
// make a working buffer
2021-06-07 18:19:10 +02:00
text = new char[textSize + 1];
2021-05-17 20:47:39 +02:00
// and fill it
Common::strlcpy(text, origText, textSize + 1);
2021-05-17 20:47:39 +02:00
textFont = font;
textHeight = (textFont ? textFont->height : 0);
2021-06-07 18:19:10 +02:00
lineWidth = dApp.pageRect[0].width;
pageHeight = dApp.pageRect[0].height;
2021-05-17 20:47:39 +02:00
currentPage = 0;
totalLines = 0;
totalPages = 0;
2021-06-13 16:56:52 +02:00
pageBreakSet = true;
2021-05-17 20:47:39 +02:00
// null out the image pointer array
for (int16 i = 0; i < maxPages; i++) {
images[i] = nullptr;
2021-05-17 20:47:39 +02:00
}
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;
2021-05-17 20:47:39 +02:00
}
2021-09-11 12:13:35 +03:00
CDocument::~CDocument() {
2021-05-17 20:47:39 +02:00
int16 i;
for (i = 0; i < maxPages; i++) {
2021-06-07 18:19:10 +02:00
if (images[i]) {
2021-06-23 18:40:36 +09:00
free(images[i]);
2021-05-17 20:47:39 +02:00
}
}
// get rid of the working text buffer
if (text) {
2021-06-23 18:40:36 +09:00
delete[] text;
text = nullptr;
2021-05-17 20:47:39 +02:00
}
if (origText) {
2021-06-23 18:40:36 +09:00
delete[] origText;
origText = nullptr;
2021-05-17 20:47:39 +02:00
}
// get rid of the resource context
2021-06-23 18:40:36 +09:00
if (illustrationCon)
resFile->disposeContext(illustrationCon);
2021-05-17 20:47:39 +02:00
}
2021-09-11 12:13:35 +03:00
void CDocument::deactivate() {
2021-05-17 20:47:39 +02:00
selected = 0;
gPanel::deactivate();
}
bool CDocument::activate(gEventType why) {
if (why == gEventMouseDown) { // momentarily depress
selected = 1;
notify(why, 0); // notify App of successful hit
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
2021-06-13 16:56:52 +02:00
return false;
2021-05-17 20:47:39 +02:00
}
bool CDocument::keyStroke(gPanelMessage &msg) {
gEvent ev;
switch (msg.key) {
case Common::ASCII_ESCAPE:
2021-05-17 20:47:39 +02:00
cmdDocumentEsc(ev);
2021-06-13 16:56:52 +02:00
return true;
case Common::KEYCODE_LEFT:
2021-05-17 20:47:39 +02:00
cmdDocumentLt(ev);
2021-06-13 16:56:52 +02:00
return true;
case Common::KEYCODE_RIGHT:
2021-05-17 20:47:39 +02:00
cmdDocumentRt(ev);
2021-06-13 16:56:52 +02:00
return true;
case Common::KEYCODE_UP:
2021-05-17 20:47:39 +02:00
cmdDocumentUp(ev);
2021-06-13 16:56:52 +02:00
return true;
case Common::KEYCODE_DOWN:
2021-05-17 20:47:39 +02:00
cmdDocumentDn(ev);
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
default:
2021-06-13 16:56:52 +02:00
return false;
2021-05-17 20:47:39 +02:00
}
}
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:
2021-05-17 20:47:39 +02:00
return this;
default:
return nullptr;
2021-05-17 20:47:39 +02:00
}
}
// 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)) {
2021-05-17 20:47:39 +02:00
if (app.orientation == pageOrientVertical) {
// 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);
2021-05-17 20:47:39 +02:00
} 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);
2021-05-17 20:47:39 +02:00
}
} else if (msg.pointerLeave) {
setMouseImage(kMouseArrowImage, 0, 0);
2021-05-17 20:47:39 +02:00
}
notify(gEventMouseMove, 0);
}
void CDocument::pointerDrag(gPanelMessage &) {
if (selected) {
notify(gEventMouseDrag, 0);
}
}
bool CDocument::pointerHit(gPanelMessage &msg) {
Point16 pos = msg.pickPos;
if (msg.inPanel && Rect16(0, 0, _extent.width, _extent.height).ptInside(pos)) {
2021-05-17 20:47:39 +02:00
gEvent ev;
if (app.orientation == pageOrientVertical) {
// find out which end of the book we're on
if (pos.y < _extent.height / 2) cmdDocumentUp(ev); //gotoPage( currentPage - app.numPages );
2021-05-17 20:47:39 +02:00
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 );
2021-05-17 20:47:39 +02:00
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;
2021-05-17 20:47:39 +02:00
if (ri) {
ri->running = 0;
ri->result = id;
setMouseImage(kMouseArrowImage, 0, 0);
2021-05-17 20:47:39 +02:00
}
}
activate(gEventMouseDown);
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
void CDocument::gotoPage(int8 page) {
page = clamp(0, page, maxPages);
while (page % app.numPages) page++;
if (page != currentPage && page < pages) {
currentPage = page;
renderText();
}
}
void CDocument::pointerRelease(gPanelMessage &) {
if (selected) notify(gEventMouseUp, 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;
2021-07-29 04:32:56 +09:00
char *strAfter;
2021-05-17 20:47:39 +02:00
// page break detected
2021-06-07 18:19:10 +02:00
if (strIndex[1] == dPageBreak[0] &&
strIndex[2] == dPageBreak[1]) {
2021-05-17 20:47:39 +02:00
// eat the page breaks chars
// tie off the end
2021-06-24 00:03:14 +02:00
strIndex[0] = 0;
2021-07-29 04:32:56 +09:00
strAfter = new char[textSize];
Common::strlcpy(strAfter, &strIndex[3], textSize);
2021-05-17 20:47:39 +02:00
// string them together
2021-07-29 04:32:56 +09:00
strcat(&strIndex[0], strAfter);
2021-05-17 20:47:39 +02:00
// take the offset to the end of this line
offset = index;
// and set the new page flag
2021-07-29 04:32:56 +09:00
delete[] strAfter;
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
2021-06-13 16:56:52 +02:00
return false;
2021-05-17 20:47:39 +02:00
}
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
2021-06-07 18:19:10 +02:00
if (strIndex[1] == dImage[0] &&
strIndex[2] == dImage[1]) {
2021-06-23 12:20:59 +02:00
int16 numEat = 0; // number of characters to eat
2021-06-07 18:19:10 +02:00
char *argv = &strIndex[2 + 1]; // array to first element
2021-05-17 20:47:39 +02:00
// delete context
if (illustrationCon) resFile->disposeContext(illustrationCon);
// resource handle
illustrationCon = resFile->newContext(MKTAG(argv[0], argv[1], argv[2], argv[3]),
2021-05-17 20:47:39 +02:00
"book internal resources");
// set image for next page
if (offPageIndex < maxPages) {
// if the last entry is defined as a number
if (argv[7] == ':') {
// convert the text into a number
2021-06-24 00:03:14 +02:00
char numSt[2] = { argv[8], 0 };
2021-05-17 20:47:39 +02:00
uint8 num = atoi(numSt);
2021-06-07 18:19:10 +02:00
if (!images[offPageIndex]) {
2021-05-17 20:47:39 +02:00
// get the image
2021-06-07 18:19:10 +02:00
images[offPageIndex] = LoadResource(illustrationCon,
MKTAG(argv[4], argv[5], argv[6], num),
2021-05-17 20:47:39 +02:00
"book internal image");
}
// number of chars to eat
numEat = 9;
} else {
2021-06-07 18:19:10 +02:00
images[offPageIndex] = LoadResource(illustrationCon,
MKTAG(argv[4], argv[5], argv[6], argv[7]),
2021-05-17 20:47:39 +02:00
"book internal image");
numEat = 8;
}
// get the size of the image
imageSizes[offPageIndex] = ((ImageHeader *)images[offPageIndex])->size;
2021-05-17 20:47:39 +02:00
// tie off the end
strIndex[0] = 0;
2021-05-17 20:47:39 +02:00
// and string them together
strcat(&strIndex[0], &strIndex[2 + 1 + numEat]);
2021-05-17 20:47:39 +02:00
// set new line length
offset = index;
2021-05-17 20:47:39 +02:00
// set the line offset
lineOffset[offPageIndex] =
imageSizes[offPageIndex].y / (textHeight + 1) +
textPictureOffset;
} else {
warning("CDocument: Document overflow");
}
2021-05-17 20:47:39 +02:00
// set the new page flag
2021-06-13 16:56:52 +02:00
return true;
2021-05-17 20:47:39 +02:00
}
2021-06-13 16:56:52 +02:00
return false;
2021-05-17 20:47:39 +02:00
}
2021-09-11 12:13:35 +03:00
void CDocument::makePages() {
2021-05-17 20:47:39 +02:00
// copy the original text back to the working buffer
Common::strlcpy(text, origText, textSize + 1);
2021-05-17 20:47:39 +02:00
char *str = text;
int32 offset = 0;
uint16 lineIndex = 0;
uint16 pageIndex = 0;
uint16 linesPerPage = pageHeight / (textHeight + 1);
uint16 dummy;
uint16 i;
2021-06-13 16:56:52 +02:00
bool newPage = false;
2021-05-17 20:47:39 +02:00
while (offset >= 0 && pageIndex < maxPages) {
2021-05-17 20:47:39 +02:00
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
2021-06-07 18:19:10 +02:00
if (str[i] == deliminator) {
2021-05-17 20:47:39 +02:00
// page break check
if (checkForPageBreak(str, i, offset)) {
// if a break did not just occur
if (!pageBreakSet) {
2021-06-13 16:56:52 +02:00
newPage = true;
pageBreakSet = true;
2021-05-17 20:47:39 +02:00
} else {
// eat the newPage and
// reset the flag for a just set break
2021-06-13 16:56:52 +02:00
pageBreakSet = false;
2021-05-17 20:47:39 +02:00
}
}
// image check
if (checkForImage(str, i, pageIndex, offset)) {
// if a break did not just occur
if (!pageBreakSet) {
2021-06-13 16:56:52 +02:00
newPage = true;
pageBreakSet = true;
2021-05-17 20:47:39 +02:00
} else {
// eat the newPage and
// reset the flag for a just set break
2021-06-13 16:56:52 +02:00
pageBreakSet = false;
2021-05-17 20:47:39 +02:00
}
2021-06-07 18:19:10 +02:00
lineIndex = lineOffset[pageIndex];
2021-05-17 20:47:39 +02:00
}
}
// we got token that was not a page break so reset the flag
2021-06-13 16:56:52 +02:00
pageBreakSet = false;
2021-05-17 20:47:39 +02:00
}
// set the length of this line
if (offset >= 0) {
// number of characters on this line
2021-06-07 18:19:10 +02:00
lineLen[pageIndex][lineIndex] = offset;
2021-05-17 20:47:39 +02:00
} else {
// remaining number of characters in string
2021-06-07 18:19:10 +02:00
lineLen[pageIndex][lineIndex] = strlen(str);
2021-05-17 20:47:39 +02:00
}
// increment the str pointer and line index
str += offset;
lineIndex++;
}
2021-06-07 18:19:10 +02:00
numLines[pageIndex] = lineIndex;
2021-05-17 20:47:39 +02:00
pageIndex++;
2021-06-13 16:56:52 +02:00
newPage = false;
2021-05-17 20:47:39 +02:00
lineIndex = 0;
}
pages = pageIndex;
}
// This function will draw the text onto the book.
2021-09-11 12:13:35 +03:00
void CDocument::renderText() {
2021-05-17 20:47:39 +02:00
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);
2021-05-17 20:47:39 +02:00
2021-06-22 12:42:03 +02:00
if (NewTempPort(tPort, bltRect.width, bltRect.height)) {
2021-05-17 20:47:39 +02:00
// 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));
2021-05-17 20:47:39 +02:00
tPort.setFont(textFont); // setup the string pointer
for (pageIndex = 0; pageIndex < currentPage; pageIndex++) {
2021-06-07 18:19:10 +02:00
if (images[pageIndex]) {
lineIndex = lineOffset[pageIndex];
2021-05-17 20:47:39 +02:00
assert(lineIndex < linesPerPage);
} else {
lineIndex = 0;
}
2021-06-07 18:19:10 +02:00
for (; lineIndex < numLines[pageIndex]; lineIndex++) {
int16 temp = lineLen[pageIndex][lineIndex];
2021-05-17 20:47:39 +02:00
assert(pageIndex < maxPages);
assert(temp < 35);
2021-06-07 18:19:10 +02:00
str += lineLen[pageIndex][lineIndex];
2021-05-17 20:47:39 +02:00
}
}
// 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];
2021-05-17 20:47:39 +02:00
// if there is an image on this page
2021-06-07 18:19:10 +02:00
if (images[pageIndex]) {
2021-05-17 20:47:39 +02:00
Point16 pos;
2021-06-07 18:19:10 +02:00
pos.x = pageRect->x + (pageRect->width - imageSizes[pageIndex].x) / 2;
2021-05-17 20:47:39 +02:00
pos.y = pageRect->y;
2021-06-07 18:19:10 +02:00
drawCompressedImage(tPort, pos, images[pageIndex]);
2021-05-17 20:47:39 +02:00
2021-06-07 18:19:10 +02:00
lineIndex = lineOffset[pageIndex];
2021-05-17 20:47:39 +02:00
} else {
lineIndex = 0;
}
2021-06-07 18:19:10 +02:00
for (; lineIndex < numLines[pageIndex]; lineIndex++) {
2021-06-29 23:24:07 +02:00
assert(pageIndex <= maxPages);
2021-05-17 20:47:39 +02:00
tPort.moveTo(pageRect->x, pageRect->y + (textHeight * lineIndex) + 1);
2021-06-07 18:19:10 +02:00
tPort.setColor(app.textColors[lineIndex]);
tPort.drawText(str, lineLen[pageIndex][lineIndex]);
2021-05-17 20:47:39 +02:00
// grab the next text offset
2021-06-07 18:19:10 +02:00
int16 temp = lineLen[pageIndex][lineIndex];
2021-05-17 20:47:39 +02:00
assert(temp < 35);
2021-06-07 18:19:10 +02:00
str += lineLen[pageIndex][lineIndex];
2021-05-17 20:47:39 +02:00
}
}
port.setMode(drawModeMatte);
2021-07-17 05:19:47 +09:00
g_vm->_pointer->hide();
2021-05-17 20:47:39 +02:00
port.bltPixels(*tPort.map, 0, 0,
bltRect.x, bltRect.y,
bltRect.width, bltRect.height);
2021-07-17 05:19:47 +09:00
g_vm->_pointer->show();
2021-05-17 20:47:39 +02:00
DisposeTempPort(tPort); // dispose of temporary pixelmap
}
}
void CDocument::drawClipped(
gPort &port,
const Point16 &offset,
const Rect16 &clipRect) {
2021-07-17 05:19:47 +09:00
g_vm->_pointer->hide();
2021-05-17 20:47:39 +02:00
ModalWindow::drawClipped(port, offset, clipRect);
2021-07-17 05:19:47 +09:00
g_vm->_pointer->show();
2021-05-17 20:47:39 +02:00
}
2021-09-11 12:13:35 +03:00
void CDocument::draw() { // redraw the window
2021-05-17 20:47:39 +02:00
// draw the book image
drawClipped(g_vm->_mainPort, Point16(0, 0), _extent);
2021-05-17 20:47:39 +02:00
// 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;
2021-06-07 18:19:10 +02:00
char bookText[textSize] = { "" };
2021-05-17 20:47:39 +02:00
void appendBookText(char *string) {
if (string) {
2021-07-29 05:02:12 +09:00
Common::strlcat(bookText, string, textSize - 1);
2021-06-24 00:03:14 +02:00
bookText[textSize - 1] = 0;
2021-05-17 20:47:39 +02:00
}
}
/* ===================================================================== *
scroll window
* ===================================================================== */
void buildText(uint16 textScript) {
if (textScript > 0) {
// clear out the scroll text
2021-07-29 04:32:56 +09:00
Common::strlcpy(bookText, "", sizeof(bookText));
2021-05-17 20:47:39 +02:00
2021-06-07 18:19:10 +02:00
if (textScript == resImports->reserved[0]) {
2021-07-29 04:32:56 +09:00
Common::strlcpy(bookText, PROGRAM_ABOUT, sizeof(bookText));
2021-05-17 20:47:39 +02:00
}
// 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 {
sprintf(bookText, "Invalid textScript: %d", textScript);
}
}
int16 openScroll(uint16 textScript) {
buildText(textScript);
// requester info struct
requestInfo rInfo;
rInfo.result = -1;
2021-06-13 16:56:52 +02:00
rInfo.running = true;
2021-05-17 20:47:39 +02:00
// point to book
CDocument *win = nullptr;
2021-05-17 20:47:39 +02:00
// close button
2021-08-20 03:27:52 +09:00
GfxCompButton *closeScroll;
2021-05-17 20:47:39 +02:00
void **closeBtnImage;
uint16 buttonResID = 0;
hResContext *decRes;
// init the resource context handle
decRes = resFile->newContext(MKTAG('S', 'C', 'R', 'L'), "book resources");
2021-05-17 20:47:39 +02:00
// get the graphics associated with the buttons
2021-06-22 13:24:56 +02:00
closeBtnImage = loadButtonRes(decRes, buttonResID, numBtnImages);
2021-05-17 20:47:39 +02:00
// create the window
win = new CDocument(scrollAppearance, bookText, &Script10Font, 0, nullptr);
2021-05-17 20:47:39 +02:00
// make the quit button
2021-08-20 03:27:52 +09:00
closeScroll = new GfxCompButton(*win, scrollAppearance.closeRect, closeBtnImage, numBtnImages, 0, cmdDocumentQuit);
2021-05-17 20:47:39 +02:00
closeScroll->accelKey = 0x1B;
// attach the structure to the book, open the book
win->userData = &rInfo;
win->open();
// do stuff
2021-06-13 16:56:52 +02:00
EventLoop(rInfo.running, true);
2021-05-17 20:47:39 +02:00
// remove the window all attatched controls
delete win;
// unload all image arrays
unloadImageRes(closeBtnImage, numBtnImages);
// remove the resource handle
2021-07-07 05:45:16 +09:00
if (decRes)
resFile->disposeContext(decRes);
2021-05-17 20:47:39 +02:00
// return the result code
return rInfo.result;
}
/* ===================================================================== *
Book window
* ===================================================================== */
int16 openBook(uint16 textScript) {
buildText(textScript);
// requester info struct
requestInfo rInfo;
rInfo.result = -1;
2021-06-13 16:56:52 +02:00
rInfo.running = true;
2021-05-17 20:47:39 +02:00
2021-07-07 05:45:16 +09:00
2021-05-17 20:47:39 +02:00
// point to book
CDocument *win = nullptr;
2021-05-17 20:47:39 +02:00
2021-08-20 03:27:52 +09:00
GfxCompButton *closeBook;
2021-07-07 05:45:16 +09:00
hResContext *decRes;
decRes = resFile->newContext(MKTAG('S', 'C', 'R', 'L'), "book resources");
2021-05-17 20:47:39 +02:00
// create the window
win = new CDocument(bookAppearance, bookText, &Script10Font, 0, nullptr);
2021-05-17 20:47:39 +02:00
// make the quit button
2021-08-20 03:27:52 +09:00
closeBook = new GfxCompButton(*win, bookAppearance.closeRect, cmdDocumentQuit);
2021-07-07 05:45:16 +09:00
closeBook->accelKey = 0x1B;
2021-05-17 20:47:39 +02:00
// attach the structure to the book, open the book
win->userData = &rInfo;
win->open();
// do stuff
2021-06-13 16:56:52 +02:00
EventLoop(rInfo.running, true);
2021-05-17 20:47:39 +02:00
// remove the window all attatched controls
delete win;
2021-07-07 05:45:16 +09:00
if (decRes)
resFile->disposeContext(decRes);
2021-05-17 20:47:39 +02:00
// return the result code
return rInfo.result;
}
/* ===================================================================== *
Parchment window
* ===================================================================== */
int16 openParchment(uint16 textScript) {
buildText(textScript);
// requester info struct
requestInfo rInfo;
rInfo.result = -1;
2021-06-13 16:56:52 +02:00
rInfo.running = true;
2021-05-17 20:47:39 +02:00
2021-07-07 05:45:16 +09:00
2021-05-17 20:47:39 +02:00
// point to book
CDocument *win = nullptr;
2021-05-17 20:47:39 +02:00
2021-08-20 03:27:52 +09:00
GfxCompButton *closeParchment;
2021-07-07 05:45:16 +09:00
hResContext *decRes;
decRes = resFile->newContext(MKTAG('S', 'C', 'R', 'L'), "book resources");
2021-05-17 20:47:39 +02:00
// create the window
win = new CDocument(parchAppearance, bookText, &Script10Font, 0, nullptr);
2021-05-17 20:47:39 +02:00
// make the quit button
2021-08-20 03:27:52 +09:00
closeParchment = new GfxCompButton(*win, parchAppearance.closeRect, cmdDocumentQuit);
2021-07-07 05:45:16 +09:00
closeParchment->accelKey = 0x1B;
2021-05-17 20:47:39 +02:00
// attach the structure to the book, open the book
win->userData = &rInfo;
win->open();
// do stuff
2021-06-13 16:56:52 +02:00
EventLoop(rInfo.running, true);
2021-05-17 20:47:39 +02:00
// remove the window all attatched controls
delete win;
2021-07-07 05:45:16 +09:00
if (decRes)
resFile->disposeContext(decRes);
2021-05-17 20:47:39 +02:00
// return the result code
return rInfo.result;
}
APPFUNC(cmdDocumentQuit) {
gWindow *win;
requestInfo *ri;
if (ev.panel && ev.eventType == gEventNewValue && ev.value) {
win = ev.panel->getWindow(); // get the window pointer
ri = win ? (requestInfo *)win->userData : nullptr;
2021-05-17 20:47:39 +02:00
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