[Scummvm-cvs-logs] CVS: scummvm/sword1 control.cpp,NONE,1.1 control.h,NONE,1.1

Robert G?ffringmann lavosspawn at users.sourceforge.net
Sat Dec 20 01:19:02 CET 2003


Update of /cvsroot/scummvm/scummvm/sword1
In directory sc8-pr-cvs1:/tmp/cvs-serv14896/sword1

Added Files:
	control.cpp control.h 
Log Message:
forgot these. :)

--- NEW FILE: control.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2003 The ScummVM project
 *
 * 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/sword1/control.cpp,v 1.1 2003/12/20 09:18:43 lavosspawn Exp $
 *
 */

#include "stdafx.h"
#include "control.h"
#include "common/util.h"
#include "common/file.h"
#include "logic.h"
#include "sworddefs.h"
#include "swordres.h"
#include "resman.h"
#include "objectman.h"
#include "sword1.h"
#include "common/util.h"
#include "mouse.h"

#define SAVEFILE_WRITE true
#define SAVEFILE_READ false

enum LangStrings {
	STR_PAUSED = 0,
	STR_INSERT_CD_A,
	STR_INSERT_CD_B,
	STR_INCORRECT_CD,
	STR_SAVE,
	STR_RESTORE,
	STR_RESTART,
	STR_START,
	STR_QUIT,
	STR_SPEED,
	STR_VOLUME,
	STR_TEXT,
	STR_DONE,
	STR_OK,
	STR_CANCEL,
	STR_MUSIC,
	STR_SPEECH,
	STR_FX,
	STR_THE_END,
	STR_DRIVE_FULL
};

enum ButtonIds {
	BUTTON_DONE = 1,
	BUTTON_MAIN_PANEL,
	BUTTON_SAVE_PANEL,
	BUTTON_RESTORE_PANEL,
	BUTTON_RESTART,
	BUTTON_QUIT,
	BUTTON_SPEED,
	BUTTON_VOLUME,
	BUTTON_TEXT,
//-
	BUTTON_SCROLL_UP_FAST,
	BUTTON_SCROLL_UP_SLOW,
	BUTTON_SCROLL_DOWN_SLOW,
	BUTTON_SCROLL_DOWN_FAST,
	BUTTON_SAVE_SELECT1,
	BUTTON_SAVE_SELECT2,
	BUTTON_SAVE_SELECT3,
	BUTTON_SAVE_SELECT4,
	BUTTON_SAVE_SELECT5,
	BUTTON_SAVE_SELECT6,
	BUTTON_SAVE_SELECT7,
	BUTTON_SAVE_SELECT8,
	BUTTON_SAVE_RESTORE_OKAY,
	BUTTON_SAVE_CANCEL,
};

ControlButton::ControlButton(uint16 x, uint16 y, uint32 resId, uint8 id, ResMan *pResMan, uint8 *screenBuf, OSystem *system) {
	_x = x;
	_y = y;
	_id = id;
	_resId = resId;
	_resMan = pResMan;
	_dstBuf = screenBuf + y * SCREEN_WIDTH + x;
	_frameIdx = 0;
	_resMan->resOpen(_resId);
	FrameHeader *tmp = _resMan->fetchFrame(_resMan->fetchRes(_resId), 0);
	_width = FROM_LE_16(tmp->width);
	_height = FROM_LE_16(tmp->height);
	_system = system;
}

ControlButton::~ControlButton(void) {
	_resMan->resClose(_resId);
}

bool ControlButton::isSaveslot(void) {
	return ((_resId >= SR_SLAB1) && (_resId <= SR_SLAB4));
}

void ControlButton::draw(void) {
	FrameHeader *fHead = _resMan->fetchFrame(_resMan->fetchRes(_resId), _frameIdx);
	uint8 *src = (uint8*)fHead + sizeof(FrameHeader);
	uint8 *dst = _dstBuf;
	for (uint16 cnt = 0; cnt < FROM_LE_16(fHead->height); cnt++) {
		for (uint16 cntx = 0; cntx < FROM_LE_16(fHead->width); cntx++)
			if (src[cntx])
				dst[cntx] = src[cntx];
		dst += SCREEN_WIDTH;
		src += FROM_LE_16(fHead->width);
	}
	_system->copy_rect(_dstBuf, SCREEN_WIDTH, _x, _y, _width, _height);
}

bool ControlButton::wasClicked(uint16 mouseX, uint16 mouseY) {
	if ((_x <= mouseX) && (_y <= mouseY) && (_x + _width >= mouseX) && (_y + _height >= mouseY))
		return true;
	else
		return false;
}

void ControlButton::setSelected(uint8 selected) {
	_frameIdx = selected;
	draw();
}

SwordControl::SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, const char *savePath) {
	_resMan = pResMan;
	_objMan = pObjMan;
	_system = system;
	_mouse = pMouse;
	strcpy(_savePath, savePath);
}

uint8 SwordControl::runPanel(void) {
	_restoreBuf = NULL;
	_lStrings = _languageStrings + MIN(SwordEngine::_systemVars.language, (uint8)BS1_SPANISH) * 20;
	_keyPressed = _numButtons = 0;
	_screenBuf = (uint8*)malloc(640 * 480);
	_font = (uint8*)_resMan->openFetchRes(GAME_FONT); // todo: czech support
	_resMan->resOpen(SR_BUTTON);
	uint8 *pal = (uint8*)_resMan->openFetchRes(SR_PALETTE);
	uint8 *palOut = (uint8*)malloc(256 * 4);
	for (uint16 cnt = 1; cnt < 256; cnt++) {
		palOut[cnt * 4 + 0] = pal[cnt * 3 + 0] << 2;
		palOut[cnt * 4 + 1] = pal[cnt * 3 + 1] << 2;
		palOut[cnt * 4 + 2] = pal[cnt * 3 + 2] << 2;
	}
	palOut[0] = palOut[1] = palOut[2] = palOut[3] = 0;
	_resMan->resClose(SR_PALETTE);
	_system->set_palette(palOut, 0, 256);
	free(palOut);
	uint8 mode = 0, newMode = BUTTON_MAIN_PANEL;
	bool fullRefresh = false;
	_mouse->controlPanel(true);
	uint8 retVal = CONTROL_NOTHING_DONE;

	do {
		if (newMode) {
			mode = newMode;
			fullRefresh = true;
			destroyButtons();
			memset(_screenBuf, 0, 640 * 480);
		}
		switch (mode) {
			case BUTTON_MAIN_PANEL:
				if (fullRefresh)
					setupMainPanel();
				break;
			case BUTTON_SAVE_PANEL:
				if (fullRefresh)
					setupSaveRestorePanel(true);
				if (_keyPressed)
					handleSaveKey(_keyPressed);
				break;
			case BUTTON_RESTORE_PANEL:
				if (fullRefresh)
					setupSaveRestorePanel(false);
				break;

		}
		if (fullRefresh) {
			fullRefresh = false;
			_system->copy_rect(_screenBuf, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, 480);
		}
		_system->update_screen();
		delay(1000 / 12);
		newMode = getClicks(mode, &retVal);
	} while ((newMode != 1) && (retVal == 0));
	_resMan->resClose(SR_BUTTON);
	memset(_screenBuf, 0, 640 * 480);
	_system->copy_rect(_screenBuf, 640, 0, 0, 640, 480);
	free(_screenBuf);
	_mouse->controlPanel(false);
	return retVal;
}

uint8 SwordControl::getClicks(uint8 mode, uint8 *retVal) {
	if (!_mouseState)
		return 0;
	if (_mouseState & BS1L_BUTTON_DOWN)
		for (uint8 cnt = 0; cnt < _numButtons; cnt++)
			if (_buttons[cnt]->wasClicked(_mouseX, _mouseY)) {
				_selectedButton = cnt;
				_buttons[cnt]->setSelected(1);
			}
	if (_mouseState & BS1L_BUTTON_UP) {
		for (uint8 cnt = 0; cnt < _numButtons; cnt++)
			if (_buttons[cnt]->wasClicked(_mouseX, _mouseY))
				if (_selectedButton == cnt) {
					// saveslots stay selected after clicking
					if (!_buttons[cnt]->isSaveslot())
						_buttons[cnt]->setSelected(0);
					_selectedButton = 255;
					return handleButtonClick(_buttons[cnt]->_id, mode, retVal);
				}
		if (_selectedButton < _numButtons)
			_buttons[_selectedButton]->setSelected(0);
		_selectedButton = 255;
	}
	return 0;
}

uint8 SwordControl::handleButtonClick(uint8 id, uint8 mode, uint8 *retVal) {
	switch(mode) {
		case BUTTON_MAIN_PANEL:
			if (id == BUTTON_RESTART)
				*retVal |= CONTROL_RESTART_GAME;
			else if ((id == BUTTON_RESTORE_PANEL) || (id == BUTTON_SAVE_PANEL) ||
				(id == BUTTON_DONE))
				return id;
			else
				return 0;
		case BUTTON_SAVE_PANEL:
		case BUTTON_RESTORE_PANEL:
			if ((id >= BUTTON_SCROLL_UP_FAST) && (id <= BUTTON_SCROLL_DOWN_FAST))
				saveNameScroll(id, mode == BUTTON_SAVE_PANEL);
			else if ((id >= BUTTON_SAVE_SELECT1) && (id <= BUTTON_SAVE_SELECT8))
				saveNameSelect(id, mode == BUTTON_SAVE_PANEL);
			else if (id == BUTTON_SAVE_RESTORE_OKAY) {
				if (mode == BUTTON_SAVE_PANEL) {
					if (saveToFile()) // don't go back to main panel if save fails.
						return BUTTON_MAIN_PANEL;
				} else {
					if (restoreFromFile()) { // don't go back to main panel if restore fails.
						*retVal |= CONTROL_GAME_RESTORED;
						return BUTTON_MAIN_PANEL;
					}
				}
			} else if (id == BUTTON_SAVE_CANCEL)
				return BUTTON_MAIN_PANEL; // mode down to main panel
   	}
	return 0;
}

void SwordControl::deselectSaveslots(void) {
	for (uint8 cnt = 0; cnt < 8; cnt++)
		_buttons[cnt]->setSelected(0);
}

void SwordControl::setupMainPanel(void) {
	uint32 panelId;
	uint8 langCode = MIN(SwordEngine::_systemVars.language, (uint8)BS1_SPANISH);
	
	if (SwordEngine::_systemVars.deathScreenFlag == 1)
		panelId = SR_DEATHPANEL;
	else
		panelId = SR_PANEL_ENGLISH + langCode;

	FrameHeader *frameHead = _resMan->fetchFrame(_resMan->openFetchRes(panelId), 0);
	uint16 panelX = (640 - FROM_LE_16(frameHead->width)) / 2;
	uint16 panelY = (400 - FROM_LE_16(frameHead->height)) / 2;
	
	ControlButton *panel = new ControlButton(panelX, panelY, panelId, 0, _resMan, _screenBuf, _system);
	panel->draw();
	delete panel;
	_resMan->resClose(panelId);

	if (SwordEngine::_systemVars.deathScreenFlag)
        createButtons(_deathButtons, 3);		
	else
        createButtons(_panelButtons, 8);

	if (SwordEngine::_systemVars.deathScreenFlag == 2) // end of game
		renderText(_lStrings[STR_THE_END], -480, 188);

	if (SwordEngine::_systemVars.deathScreenFlag == 0) { // normal panel
		renderText(_lStrings[STR_SAVE], 180, 188);
		renderText(_lStrings[STR_DONE], -460, 332);
		renderText(_lStrings[STR_RESTORE], 180, 224);
		renderText(_lStrings[STR_RESTART], 180, 260);
		renderText(_lStrings[STR_QUIT], 180, 296);

		renderText(_lStrings[STR_SPEED], -460, 188);
		renderText(_lStrings[STR_VOLUME], -460, 224);
		renderText(_lStrings[STR_TEXT], -460, 260);
	} else {
		renderText(_lStrings[STR_RESTORE], 285, 224);
		if (SwordEngine::_systemVars.deathScreenFlag == 3) // just started game
			renderText(_lStrings[STR_START], 285, 260);
		else
			renderText(_lStrings[STR_RESTART], 285, 260);
		renderText(_lStrings[STR_QUIT], 285, 296);
	}
}

void SwordControl::setupSaveRestorePanel(bool saving) {
	FrameHeader *savePanel = _resMan->fetchFrame(_resMan->openFetchRes(SR_WINDOW), 0);
	uint16 panelX = (640 - FROM_LE_16(savePanel->width)) / 2;
	uint16 panelY = (480 - FROM_LE_16(savePanel->height)) / 2;
	ControlButton *panel = new ControlButton(panelX, panelY, SR_WINDOW, 0, _resMan, _screenBuf, _system);
	panel->draw();
	delete panel;
	_resMan->resClose(SR_WINDOW);
	createButtons(_saveButtons, 14);
	renderText(_lStrings[STR_CANCEL], -(_saveButtons[13].x - 10), _saveButtons[13].y);
	if (saving) {
		renderText(_lStrings[STR_SAVE], _saveButtons[12].x + 30, _saveButtons[13].y);
	} else {
		renderText(_lStrings[STR_RESTORE], _saveButtons[12].x + 30, _saveButtons[13].y);
	}
    readSavegameDescriptions();
	_selectedSavegame = 255;
	showSavegameNames();
}

bool SwordControl::keyAccepted(uint8 key) {
	// this routine needs changes for Czech keys... No idea how to do that, though.
	static const char allowedSpecials[] = "éèáàúùäöüÄÖÜß,.:-()?! \"\'";
	if (((key >= 'A') && (key <= 'Z')) ||
		((key >= 'a') && (key <= 'z')) ||
		((key >= '0') && (key <= '9')) ||
		strchr(allowedSpecials, key))
		return true;
	else
		return false;
}

void SwordControl::handleSaveKey(uint8 key) {
	if (_selectedSavegame < 255) {
		uint8 len = strlen(_saveNames[_selectedSavegame]);
		if ((key == 8) && len)  // backspace
			_saveNames[_selectedSavegame][len - 1] = '\0';
		else if (keyAccepted(key) && (len < 31)) {
			_saveNames[_selectedSavegame][len] = key;
			_saveNames[_selectedSavegame][len + 1] = '\0';
		}
		showSavegameNames();
	}
}

bool SwordControl::saveToFile(void) {
	if ((_selectedSavegame == 255) || !strlen(_saveNames[_selectedSavegame]))
		return false; // no saveslot selected or no name entered
    saveGameToFile(_selectedSavegame);
	writeSavegameDescriptions();
	return true;
}

bool SwordControl::restoreFromFile(void) {
	if (_selectedSavegame < 255) {
		restoreGameFromFile(_selectedSavegame);
		return true;
	} else
		return false;
}

void SwordControl::readSavegameDescriptions(void) {
	SaveFileManager *mgr = _system->get_savefile_manager();
	SaveFile *inf;
	inf = mgr->open_savefile("SAVEGAME.INF", _savePath, SAVEFILE_READ);
	_saveScrollPos = _saveFiles = 0;
	_selectedSavegame = 255;
	if (inf && inf->isOpen()) {
		uint8 curFileNum = 0;
		uint8 ch;
		do {
			uint8 pos = 0;
			do {
				ch = inf->readByte();
				if ((ch == 10) || (ch == 255))
					_saveNames[curFileNum][pos] = '\0';
				else
					_saveNames[curFileNum][pos] = ch;
				pos++;
			} while ((ch != 10) && (ch != 255));
			curFileNum++;
		} while (ch != 255);
        _saveFiles = curFileNum;
		for (uint8 cnt = _saveFiles; cnt < 64; cnt++)
			_saveNames[cnt][0] = '\0';
	} else
		for (uint8 cnt = 0; cnt < 64; cnt++)
			_saveNames[cnt][0] = '\0';
	delete inf;
	delete mgr;
}

void SwordControl::writeSavegameDescriptions(void) {
	SaveFileManager *mgr = _system->get_savefile_manager();
	SaveFile *outf;
	outf = mgr->open_savefile("SAVEGAME.INF", _savePath, SAVEFILE_WRITE);
	// if the player accidently clicked the last slot and then deselected it again,
	// we'd still have _saveFiles == 64, so get rid of the empty end.
	while (strlen(_saveNames[_saveFiles] - 1) == 0)
		_saveFiles--;
	for (uint8 cnt = 0; cnt < _saveFiles; cnt++) {
		outf->write(_saveNames[cnt], strlen(_saveNames[cnt]));
		if (cnt < _saveFiles - 1)
			outf->writeByte(10);
		else
			outf->writeByte(255);
	}
	delete outf;
	delete mgr;
}

void SwordControl::showSavegameNames(void) {
	for (uint8 cnt = 0; cnt < 8; cnt++) {
		_buttons[cnt]->draw();
		renderText(_saveNames[cnt + _saveScrollPos], _saveButtons[cnt].x + 6, _saveButtons[cnt].y + 2);
	}
}

void SwordControl::saveNameSelect(uint8 id, bool saving) {
	deselectSaveslots();
	_buttons[id - BUTTON_SAVE_SELECT1]->setSelected(1);
	uint8 num = (id - BUTTON_SAVE_SELECT1) + _saveScrollPos;
	if (saving && (_selectedSavegame != 255)) // the player may have entered something, clear it again
		strcpy(_saveNames[_selectedSavegame], _oldName);
	if (num < _saveFiles) {
        _selectedSavegame = num;
		strcpy(_oldName, _saveNames[num]); // save for later
	} else {
		if (!saving)
			_buttons[id - BUTTON_SAVE_SELECT1]->setSelected(0); // no save in slot, deselect it
		else {
			if (_saveFiles <= num)
				_saveFiles = num + 1;
			_selectedSavegame = num;
			_oldName[0] = '\0';
		}
	}
	showSavegameNames();
}

void SwordControl::saveNameScroll(uint8 scroll, bool saving) {
	uint16 maxScroll;
	if (saving)
		maxScroll = 64;
	else
		maxScroll = _saveFiles; // for loading, we can only scroll as far as there are savegames
	if (scroll == BUTTON_SCROLL_UP_FAST) {
		if (_saveScrollPos >= 8)
			_saveScrollPos -= 8;
		else
			_saveScrollPos = 0;
	} else if (scroll == BUTTON_SCROLL_UP_SLOW) {
		if (_saveScrollPos >= 1)
			_saveScrollPos--;
	} else if (scroll == BUTTON_SCROLL_DOWN_SLOW) {
		if (_saveScrollPos < maxScroll - 8)
			_saveScrollPos++;
	} else if (scroll == BUTTON_SCROLL_DOWN_FAST) {
		if (_saveScrollPos < maxScroll - 16)
			_saveScrollPos += 8;
		else
			_saveScrollPos = maxScroll - 8;
	}
	_selectedSavegame = 255; // deselect savegame
	deselectSaveslots();
	showSavegameNames();
}

void SwordControl::createButtons(const ButtonInfo *buttons, uint8 num) {
	for (uint8 cnt = 0; cnt < num; cnt++) {
		_buttons[cnt] = new ControlButton(buttons[cnt].x, buttons[cnt].y, buttons[cnt].resId, buttons[cnt].id, _resMan, _screenBuf, _system);
		_buttons[cnt]->draw();
	}
	_numButtons = num;
}

void SwordControl::destroyButtons(void) {
	for (uint8 cnt = 0; cnt < _numButtons; cnt++)
		delete _buttons[cnt];
	_numButtons = 0;
}

uint16 SwordControl::getTextWidth(const char *str) {
	uint16 width = 0;
	while (*str) {
		width += FROM_LE_16(_resMan->fetchFrame(_font, *str - 32)->width) - 3;
		str++;
	}
    return width;
}

void SwordControl::renderText(const char *str, int16 x, uint16 y) {
	if (x < 0) // negative x coordinate means rightbound.
		x = (-x) - getTextWidth(str);
	
	uint16 destX = x;
	while (*str) {
		uint8 *dst = _screenBuf + y * SCREEN_WIDTH + destX;

		FrameHeader *chSpr = _resMan->fetchFrame(_font, *str - 32);
		uint8 *sprData = (uint8*)chSpr + sizeof(FrameHeader);
		for (uint16 cnty = 0; cnty < FROM_LE_16(chSpr->height); cnty++) {
			for (uint16 cntx = 0; cntx < FROM_LE_16(chSpr->width); cntx++) {
				if (sprData[cntx])
					dst[cntx] = sprData[cntx];
			}
			sprData += FROM_LE_16(chSpr->width);
			dst += SCREEN_WIDTH;
		}
		destX += FROM_LE_16(chSpr->width) - 3;
		str++;
	}
	_system->copy_rect(_screenBuf + y * SCREEN_WIDTH + x, SCREEN_WIDTH, x, y, (destX - x) + 3, 28);
}

// I can hardly believe this is all it takes for loading and saving...
void SwordControl::saveGameToFile(uint8 slot) {
	char fName[15];
	sprintf(fName, "SAVEGAME.%03d", slot);
	uint16 liveBuf[TOTAL_SECTIONS];
	SaveFileManager *mgr = _system->get_savefile_manager();
	SaveFile *outf;
	outf = mgr->open_savefile(fName, _savePath, SAVEFILE_WRITE);
	if (!outf->isOpen())
		error("unable to create file %s", fName);

	_objMan->saveLiveList(liveBuf);
	for (uint16 cnt = 0; cnt < TOTAL_SECTIONS; cnt++)
		outf->writeUint16LE(liveBuf[cnt]);

	BsObject *cpt = _objMan->fetchObject(PLAYER);
	SwordLogic::_scriptVars[CHANGE_DIR] = cpt->o_dir;
	SwordLogic::_scriptVars[CHANGE_X] = cpt->o_xcoord;
	SwordLogic::_scriptVars[CHANGE_Y] = cpt->o_ycoord;
	SwordLogic::_scriptVars[CHANGE_STANCE] = STAND;
	SwordLogic::_scriptVars[CHANGE_PLACE] = cpt->o_place;

	for (uint16 cnt = 0; cnt < NUM_SCRIPT_VARS; cnt++)
		outf->writeUint32LE(SwordLogic::_scriptVars[cnt]);

	uint32 playerSize = (sizeof(BsObject) - 12000) / 4;
	uint32 *playerRaw = (uint32*)cpt;
	for (uint32 cnt = 0; cnt < playerSize; cnt++)
		outf->writeUint32LE(playerRaw[cnt]);
	delete outf;
	delete mgr;
}

void SwordControl::restoreGameFromFile(uint8 slot) {
	char fName[15];
	sprintf(fName, "SAVEGAME.%03d", slot);
	SaveFileManager *mgr = _system->get_savefile_manager();
	SaveFile *inf;
	inf = mgr->open_savefile(fName, _savePath, SAVEFILE_READ);
	if ((!inf) || (!inf->isOpen()))
		error("Unable to open file %s", fName);

	_restoreBuf = (uint8*)malloc(
		TOTAL_SECTIONS * 2 + 
		NUM_SCRIPT_VARS * 4 +
		(sizeof(BsObject) - 12000));

	uint16 *liveBuf = (uint16*)_restoreBuf;
	uint32 *scriptBuf = (uint32*)(_restoreBuf + 2 * TOTAL_SECTIONS);
	uint32 *playerBuf = (uint32*)(_restoreBuf + 2 * TOTAL_SECTIONS + 4 * NUM_SCRIPT_VARS);

	for (uint16 cnt = 0; cnt < TOTAL_SECTIONS; cnt++)
		liveBuf[cnt] = inf->readUint16LE();
	
	for (uint16 cnt = 0; cnt < NUM_SCRIPT_VARS; cnt++)
		scriptBuf[cnt] = inf->readUint32LE();

	uint32 playerSize = (sizeof(BsObject) - 12000) / 4;
	for (uint32 cnt = 0; cnt < playerSize; cnt++)
		playerBuf[cnt] = inf->readUint32LE();

	delete inf;
	delete mgr;
}

void SwordControl::doRestore(void) {
	uint8 *bufPos = _restoreBuf;
	_objMan->loadLiveList((uint16*)bufPos);
	bufPos += TOTAL_SECTIONS * 2;
	for (uint16 cnt = 0; cnt < NUM_SCRIPT_VARS; cnt++) {
		SwordLogic::_scriptVars[cnt] = *(uint32*)bufPos;
		bufPos += 4;
	}
	uint32 playerSize = (sizeof(BsObject) - 12000) / 4;
	uint32 *playerRaw = (uint32*)_objMan->fetchObject(PLAYER);
	for (uint32 cnt = 0; cnt < playerSize; cnt++) {
		*playerRaw = *(uint32*)bufPos;
		playerRaw++;
		bufPos += 4;
	}
    free(_restoreBuf);
}

void SwordControl::delay(uint32 msecs) {
	OSystem::Event event;

	uint32 endTime = _system->get_msecs() + msecs;
	_keyPressed = 0;	//reset
	_mouseState = 0;

	do {
		while (_system->poll_event(&event)) {
			switch (event.event_code) {
			case OSystem::EVENT_KEYDOWN:

				// Make sure backspace works right (this fixes a small issue on OS X)
				if (event.kbd.keycode == 8)
					_keyPressed = 8;
				else
					_keyPressed = (byte)event.kbd.ascii;
				break;
			case OSystem::EVENT_MOUSEMOVE:
				_mouseX = event.mouse.x;
				_mouseY = event.mouse.y;
				break;
			case OSystem::EVENT_LBUTTONDOWN:
				_mouseState |= BS1L_BUTTON_DOWN;
#ifdef _WIN32_WCE
				_mouseX = event.mouse.x;
				_mouseY = event.mouse.y;
#endif
				break;
			case OSystem::EVENT_LBUTTONUP:
				_mouseState |= BS1L_BUTTON_UP;
				break;
			case OSystem::EVENT_QUIT:
				_system->quit();
				break;
			default:
				break;
			}
		}
		_system->delay_msecs(10);
	} while (_system->get_msecs() < endTime);
}

const ButtonInfo SwordControl::_deathButtons[3] = {
	{250, 224, SR_BUTTON, BUTTON_RESTORE_PANEL },
	{250, 260, SR_BUTTON, BUTTON_RESTART },
	{250, 296, SR_BUTTON, BUTTON_QUIT }
};

const ButtonInfo SwordControl::_panelButtons[8] = {
	{145, 188, SR_BUTTON, BUTTON_SAVE_PANEL },
	{145, 224, SR_BUTTON, BUTTON_RESTORE_PANEL },
	{145, 260, SR_BUTTON, BUTTON_RESTART },
	{145, 296, SR_BUTTON, BUTTON_QUIT },
	{475, 188, SR_BUTTON, BUTTON_SPEED },
	{475, 224, SR_BUTTON, BUTTON_VOLUME },
	{475, 260, SR_BUTTON, BUTTON_TEXT },
	{475, 332, SR_BUTTON, BUTTON_DONE }
};

const ButtonInfo SwordControl::_saveButtons[16] = { 
	{114,  32 + 40, SR_SLAB1, BUTTON_SAVE_SELECT1 },
	{114,  68 + 40, SR_SLAB2, BUTTON_SAVE_SELECT2 },
	{114, 104 + 40, SR_SLAB3, BUTTON_SAVE_SELECT3 },
	{114, 140 + 40, SR_SLAB4, BUTTON_SAVE_SELECT4 },
	{114, 176 + 40, SR_SLAB1, BUTTON_SAVE_SELECT5 },
	{114, 212 + 40, SR_SLAB2, BUTTON_SAVE_SELECT6 },
	{114, 248 + 40, SR_SLAB3, BUTTON_SAVE_SELECT7 },
	{114, 284 + 40, SR_SLAB4, BUTTON_SAVE_SELECT8 },

	{516,  25 + 40, SR_BUTUF, BUTTON_SCROLL_UP_FAST },
	{516,  45 + 40, SR_BUTUS, BUTTON_SCROLL_UP_SLOW },
	{516, 289 + 40, SR_BUTDS, BUTTON_SCROLL_DOWN_SLOW },
	{516, 310 + 40, SR_BUTDF, BUTTON_SCROLL_DOWN_FAST },

	{125, 338 + 40, SR_BUTTON, BUTTON_SAVE_RESTORE_OKAY},
	{462, 338 + 40, SR_BUTTON, BUTTON_SAVE_CANCEL}
};

const char SwordControl::_languageStrings[8 * 20][43] = {
	// BS1_ENGLISH:
	"PAUSED",
	"PLEASE INSERT CD-",
	"THEN PRESS A KEY",
	"INCORRECT CD",
	"Save",
	"Restore",
	"Restart",
	"Start",
	"Quit",
	"Speed",
	"Volume",
	"Text",
	"Done",
	"OK",
	"Cancel",
	"Music",
	"Speech",
	"Fx",
	"The End",
	"DRIVE FULL!",
// BS1_FRENCH:
	"PAUSE",
	"INS\xC9REZ LE CD-"
	"ET APPUYES SUR UNE TOUCHE",
	"CD INCORRECT",
	"Sauvegarder",
	"Recharger",
	"Recommencer",
	"Commencer",
	"Vitesse",
	"Volume",
	"Texte",
	"Termin\xE9",
	"OK",
	"Annuler",
	"Musique",
	"Voix",
	"Fx",
	"Fin",
	"DISQUE PLEIN!",
//BS1_GERMAN:
	"PAUSE",
	"BITTE LEGEN SIE CD-",
	"EIN UND DR\xDC CKEN SIE EINE BELIEBIGE TASTE",
	"FALSCHE CD",
	"Speichern",
	"Laden",
	"Neues Spiel",
	"Start",
	"Beenden",
	"Geschwindigkeit",
	"Lautst\xE4rke",
	"Text",
	"Fertig",
	"OK",
	"Abbrechen",
	"Musik",
	"Sprache",
	"Fx",
	"Ende",
	"DRIVE FULL!",
//BS1_ITALIAN:
	"PAUSA",
	"INSERITE IL CD-",
	"E PREMETE UN TASTO",
	"CD ERRATO",
	"Salva",
	"Ripristina",
	"Ricomincia",
	"Inizio",
	"Velocit\xE0",
	"Volume",
	"Testo",
	"Fatto",
	"OK",
	"Annula",
	"Musica",
	"Parlato",
	"Fx",
	"Fine",
	"DISCO PIENO!",
//BS1_SPANISH:
	"PAUSA",
	"POR FAVOR INTRODUCE EL CD-",
	"Y PULSA UNA TECLA",
	"CD INCORRECTO",
	"Guardar",
	"Recuperar",
	"Reiniciar",
	"Empezar",
	"Abandonar",
	"Velocidad",
	"Volumen",
	"Texto",
	"Hecho",
	"OK",
	"Cancelar",
	"M\xFAsica",
	"Di\xE1logo",
	"Fx",
	"Fin",
	"DISCO LLENO",
// BS1_CZECH:
	"\xAC\x41S SE ZASTAVIL",
	"VLO\xA6TE DO MECHANIKY CD DISK",
	"PAK STISKN\xB7TE LIBOVOLNOU KL\xB5VESU",
	"TO NEBUDE TO SPR\xB5VN\x90 CD",
	"Ulo\xA7it pozici",
	"Nahr\xA0t pozici",
	"Za\x9F\xA1t znovu",
	"Start",
	"Ukon\x9Fit hru",
	"Rychlost",
	"Hlasitost",
	"Titulky",
	"Souhlas\xA1m",
	"Ano",
	"Ne",
	"Hudba",
	"Mluven, slovo",
	"Zvuky",
	"Konec",
	"Disk pln\xEC",
//BS1_PORTUGESE:
	"PAUSA",
	"FAVOR INSERIR CD",
	"E DIGITAR UMA TECLA",
	"CD INCORRETO",
	"Salvar",
	"Restaurar",
	"Reiniciar",
	"Iniciar",
	"Sair",
	"Velocidade",
	"Volume",
	"Texto",
	"Feito",
	"OK",
	"Cancelar",
	"M\xFAsica",
	"Voz",
	"Efeitos",
    "Fim",
	"UNIDADE CHEIA!",
};

--- NEW FILE: control.h ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2003 The ScummVM project
 *
 * 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/sword1/control.h,v 1.1 2003/12/20 09:18:43 lavosspawn Exp $
 *
 */

#ifndef BSCONTROL_H
#define BSCONTROL_H

#include "scummsys.h"
#include "sworddefs.h"

class ObjectMan;
class ResMan;
class OSystem;
class SwordMouse;
class SwordEngine;

#define MAX_BUTTONS 16

#define CONTROL_NOTHING_DONE 0
#define CONTROL_GAME_RESTORED 1
#define CONTROL_RESTART_GAME 2

class ControlButton {
public:
	ControlButton(uint16 x, uint16 y, uint32 resId, uint8 id, ResMan *pResMan, uint8 *screenBuf, OSystem *system);
	~ControlButton(void);
	void draw(void);
	bool wasClicked(uint16 mouseX, uint16 mouseY);
	void setSelected(uint8 selected);
	bool isSaveslot(void);
	uint8 _id;
private:
	int _frameIdx;
	uint16 _x, _y;
	uint16 _width, _height;
	uint32 _resId;
	ResMan *_resMan;
	uint8 *_dstBuf;
	OSystem *_system;
};

struct ButtonInfo {
	uint16 x, y;
	uint32 resId, id;
};

class SwordControl {
public:
	SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, const char *savePath);
	~SwordControl(void);
	uint8 runPanel(void);
	void doRestore(void);
private:
	void initData(void);
	void closeData(void);

	void saveGameToFile(uint8 slot);
	void restoreGameFromFile(uint8 slot);
	void readSavegameDescriptions(void);
	void writeSavegameDescriptions(void);
	void showSavegameNames(void);
	void deselectSaveslots(void);
	uint8 *_restoreBuf;
	uint8 _saveFiles;
	uint8 _saveScrollPos;
	uint8 _selectedSavegame;
	char _saveNames[64][32];
	char _oldName[32];

	uint8 getClicks(uint8 mode, uint8 *retVal);
	uint8 handleButtonClick(uint8 id, uint8 mode, uint8 *retVal);

	void setupMainPanel(void);
	void setupSaveRestorePanel(bool saving);
	void saveNameScroll(uint8 scroll, bool saving);
	void saveNameSelect(uint8 id, bool saving);
	bool saveToFile(void);
	bool restoreFromFile(void);
	bool keyAccepted(uint8 key);
	void handleSaveKey(uint8 key);

	uint16 getTextWidth(const char *str);
	void renderText(const char *str, int16 x, uint16 y);
	uint8 _numButtons;
	uint8 _selectedButton;
	void createButtons(const ButtonInfo *buttons, uint8 num);
	void destroyButtons(void);
	ControlButton *_buttons[MAX_BUTTONS];
	static const ButtonInfo _deathButtons[3], _panelButtons[8], _saveButtons[16];
	static const char _languageStrings[8 * 20][43];
	const char (*_lStrings)[43];
	ObjectMan *_objMan;
	ResMan *_resMan;
	OSystem *_system;
	SwordMouse *_mouse;
	SwordEngine *_engine;
	char _savePath[256];
	uint8 *_font;
	uint32 _fontId;
	uint8 *_screenBuf;
	uint8 _keyPressed;
	void delay(uint32 msecs);
	uint16 _mouseX, _mouseY, _mouseState;
};


#endif //BSCONTROL_H






More information about the Scummvm-git-logs mailing list