Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,313 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/shared/early/font_resources.h"
#include "common/algorithm.h"
namespace Ultima {
namespace Shared {
// 8x8 font copied from DosBox
static const byte INT10_FONT_08[256][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e },
{ 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e },
{ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00 },
{ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00 },
{ 0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c },
{ 0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c },
{ 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00 },
{ 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff },
{ 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00 },
{ 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff },
{ 0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78 },
{ 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18 },
{ 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0 },
{ 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0 },
{ 0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99 },
{ 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00 },
{ 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00 },
{ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18 },
{ 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00 },
{ 0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00 },
{ 0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78 },
{ 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00 },
{ 0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff },
{ 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00 },
{ 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00 },
{ 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00 },
{ 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00 },
{ 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00 },
{ 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00 },
{ 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00 },
{ 0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00 },
{ 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00 },
{ 0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00 },
{ 0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00 },
{ 0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00 },
{ 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00 },
{ 0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00 },
{ 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00 },
{ 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60 },
{ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00 },
{ 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00 },
{ 0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00 },
{ 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00 },
{ 0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00 },
{ 0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00 },
{ 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00 },
{ 0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00 },
{ 0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00 },
{ 0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00 },
{ 0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00 },
{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00 },
{ 0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60 },
{ 0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00 },
{ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00 },
{ 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00 },
{ 0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00 },
{ 0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00 },
{ 0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00 },
{ 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00 },
{ 0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00 },
{ 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00 },
{ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00 },
{ 0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00 },
{ 0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00 },
{ 0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00 },
{ 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 },
{ 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00 },
{ 0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00 },
{ 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00 },
{ 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00 },
{ 0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00 },
{ 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00 },
{ 0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00 },
{ 0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00 },
{ 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00 },
{ 0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00 },
{ 0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00 },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00 },
{ 0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00 },
{ 0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00 },
{ 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00 },
{ 0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00 },
{ 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00 },
{ 0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00 },
{ 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00 },
{ 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff },
{ 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00 },
{ 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00 },
{ 0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00 },
{ 0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00 },
{ 0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00 },
{ 0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00 },
{ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8 },
{ 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00 },
{ 0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 },
{ 0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78 },
{ 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00 },
{ 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00 },
{ 0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00 },
{ 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00 },
{ 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0 },
{ 0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e },
{ 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00 },
{ 0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00 },
{ 0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00 },
{ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00 },
{ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00 },
{ 0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00 },
{ 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00 },
{ 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8 },
{ 0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00 },
{ 0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00 },
{ 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00 },
{ 0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00 },
{ 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00 },
{ 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78 },
{ 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00 },
{ 0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00 },
{ 0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00 },
{ 0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00 },
{ 0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00 },
{ 0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00 },
{ 0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38 },
{ 0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00 },
{ 0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00 },
{ 0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00 },
{ 0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 },
{ 0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00 },
{ 0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 },
{ 0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00 },
{ 0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00 },
{ 0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00 },
{ 0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00 },
{ 0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00 },
{ 0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00 },
{ 0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00 },
{ 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8 },
{ 0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00 },
{ 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18 },
{ 0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00 },
{ 0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30 },
{ 0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7 },
{ 0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70 },
{ 0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00 },
{ 0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00 },
{ 0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00 },
{ 0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00 },
{ 0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00 },
{ 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00 },
{ 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00 },
{ 0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00 },
{ 0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00 },
{ 0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f },
{ 0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03 },
{ 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00 },
{ 0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00 },
{ 0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00 },
{ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88 },
{ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
{ 0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18 },
{ 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18 },
{ 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00 },
{ 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18 },
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18 },
{ 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36 },
{ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00 },
{ 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36 },
{ 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00 },
{ 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18 },
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00 },
{ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18 },
{ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36 },
{ 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36 },
{ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18 },
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff },
{ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0 },
{ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f },
{ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00 },
{ 0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0 },
{ 0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00 },
{ 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00 },
{ 0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00 },
{ 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00 },
{ 0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0 },
{ 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00 },
{ 0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc },
{ 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00 },
{ 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00 },
{ 0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00 },
{ 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00 },
{ 0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0 },
{ 0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00 },
{ 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00 },
{ 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00 },
{ 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00 },
{ 0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00 },
{ 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00 },
{ 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18 },
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70 },
{ 0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00 },
{ 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00 },
{ 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00 },
{ 0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c },
{ 0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00 },
{ 0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
};
/*-------------------------------------------------------------------*/
FontResources::FontResources() : LocalResourceFile("COMMON/FONTS") {
}
FontResources::FontResources(Resources *resManager) : LocalResourceFile(resManager, "COMMON/FONTS") {
Common::copy((const byte *)INT10_FONT_08, (const byte *)INT10_FONT_08 + 256 * 8, (byte *)_font8x8);
}
void FontResources::synchronize() {
syncBytes2D((byte *)_font8x8, 256, 8);
// Load in the Ultima VI font if present
Common::File f;
if (f.exists("u6.ch")) {
f.open("u6.ch");
for (int idx = 0; idx < 256; ++idx)
f.read(&_fontU6[idx][0], 8);
} else {
for (int idx = 0; idx < 256; ++idx)
Common::fill(&_fontU6[idx][0], &_fontU6[idx][8], 0);
}
}
} // End of namespace Shared
} // End of namespace Ultima

View File

@@ -0,0 +1,49 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_SHARED_EARLY_FONT_RESOURCES_H
#define ULTIMA_SHARED_EARLY_FONT_RESOURCES_H
#include "ultima/shared/engine/resources.h"
#include "ultima/shared/core/file.h"
#include "common/memstream.h"
namespace Ultima {
namespace Shared {
class FontResources : public LocalResourceFile {
protected:
/**
* Synchronize resource data
*/
void synchronize() override;
public:
byte _font8x8[256][8];
byte _fontU6[256][8];
public:
FontResources();
FontResources(Resources *resManager);
};
} // End of namespace Shared
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,141 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/shared/early/game.h"
#include "ultima/shared/early/font_resources.h"
#include "ultima/shared/maps/map.h"
#include "ultima/shared/early/ultima_early.h"
#include "ultima/shared/gfx/font.h"
#include "ultima/shared/gfx/screen.h"
#include "graphics/palette.h"
namespace Ultima {
namespace Shared {
BEGIN_MESSAGE_MAP(Game, GameBase)
ON_MESSAGE(EndOfTurnMsg)
END_MESSAGE_MAP()
Game::Game() : GameBase(), _randomSeed(0), _gameView(nullptr), _map(nullptr), _party(nullptr),
_edgeColor(0), _borderColor(0), _highlightColor(0), _textColor(0), _color1(0), _bgColor(0), _whiteColor(0) {
_fontResources = new FontResources();
_fontResources->load();
setFont(new Gfx::Font((const byte *)&_fontResources->_font8x8[0][0]));
}
Game::~Game() {
delete _fontResources;
}
void Game::setCGAPalette() {
static const byte PALETTE[4][3] = { { 0, 0, 0 },{ 0xAA, 0xAA, 0 },{ 0xAA, 0, 0xAA },{ 0xAA, 0xAA, 0xAA } };
g_vm->_screen->setPalette(&PALETTE[0][0], 0, 4);
_edgeColor = 3;
_borderColor = 3;
_highlightColor = 1;
_textColor = 3;
_color1 = 6;
_whiteColor = 3;
}
void Game::setEGAPalette() {
static const byte PALETTE[16][3] = {
{ 0, 0, 0 },{ 0x00, 0x00, 0x80 },{ 0x00, 0x80, 0x00 },{ 0x00, 0x80, 0x80 },
{ 0x80, 0x00, 0x00 },{ 0x80, 0x00, 0x80 },{ 0x80, 0x80, 0x00 },{ 0xC0, 0xC0, 0xC0 },
{ 0x80, 0x80, 0x80 },{ 0x00, 0x00, 0xFF },{ 0x00, 0xFF, 0x00 },{ 0x00, 0xFF, 0xFF },
{ 0xFF, 0x40, 0x40 },{ 0xFF, 0x00, 0xFF },{ 0xFF, 0xFF, 0x00 },{ 0xFF, 0xFF, 0xFF }
};
g_vm->_screen->setPalette(&PALETTE[0][0], 0, 16);
_edgeColor = 15;
_borderColor = 1;
_highlightColor = 12;
_textColor = 11;
_color1 = 7;
_bgColor = 0;
_whiteColor = 15;
}
void Game::setEGAPalette(const byte *palette) {
// Build up the EGA palette
byte egaPalette[64 * 3];
byte *p = &egaPalette[0];
for (int i = 0; i < 64; ++i) {
*p++ = (i >> 2 & 1) * 0xaa + (i >> 5 & 1) * 0x55;
*p++ = (i >> 1 & 1) * 0xaa + (i >> 4 & 1) * 0x55;
*p++ = (i & 1) * 0xaa + (i >> 3 & 1) * 0x55;
}
// Loop through setting palette colors based on the passed indexes
for (int idx = 0; idx < 16; ++idx) {
int palIndex = palette[idx];
assert(palIndex < 64);
const byte *pRgb = (const byte *)&egaPalette[palIndex * 3];
g_vm->_screen->setPalette(pRgb, idx, 1);
}
}
void Game::loadU6Palette() {
// Read in the palette
File f("u6pal");
byte palette[Graphics::PALETTE_SIZE];
f.read(palette, Graphics::PALETTE_SIZE);
f.close();
// Adjust the palette values from 0-63 to 0-255, and set the palette
for (int idx = 0; idx < Graphics::PALETTE_SIZE; ++idx)
palette[idx] = PALETTE_6BIT_TO_8BIT(palette[idx]);
g_vm->_screen->setPalette(&palette[0], 0, Graphics::PALETTE_COUNT);
// TODO: Set appropriate indexes
_edgeColor = 15;
_borderColor = 1;
_highlightColor = 12;
_textColor = 72;
_color1 = 7;
_bgColor = 49;
}
void Game::playFX(uint effectId) {
warning("TODO: playFX");
}
void Game::synchronize(Common::Serializer &s) {
_party->synchronize(s);
_map->synchronize(s);
}
bool Game::EndOfTurnMsg(CEndOfTurnMsg *msg) {
// Update things on the map
_map->update();
return false;
}
void Game::endOfTurn() {
CEndOfTurnMsg turnMsg;
turnMsg.execute(this);
}
} // End of namespace Shared
} // End of namespace Ultima

View File

@@ -0,0 +1,129 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_SHARED_EARLY_GAME_H
#define ULTIMA_SHARED_EARLY_GAME_H
#include "ultima/shared/early/game_base.h"
#include "ultima/shared/core/party.h"
namespace Ultima {
namespace Shared {
class GameView;
class GameState;
class FontResources;
namespace Maps {
class Map;
}
/**
* More specialized base class for earlier Ultima games
*/
class Game : public GameBase {
DECLARE_MESSAGE_MAP;
bool EndOfTurnMsg(CEndOfTurnMsg *msg);
protected:
GameView *_gameView;
FontResources *_fontResources;
protected:
/**
* Sets up EGA palette
*/
void setEGAPalette();
/**
* Loads the Ultima 6 palette
*/
void loadU6Palette();
public:
byte _edgeColor;
byte _borderColor;
byte _highlightColor;
byte _textColor;
byte _color1;
byte _bgColor;
byte _whiteColor;
/**
* Player party. In the earlier Ultima games, this is a single character
*/
Party *_party;
/**
* Pointer to the map manager for the game
*/
Maps::Map *_map;
/**
* Stores the base random seed used for generating deterministic dungeon levels
*/
uint32 _randomSeed;
public:
CLASSDEF;
/**
* Constructor
*/
Game();
/**
* Destructor
*/
~Game() override;
/**
* Play a sound effect
*/
void playFX(uint effectId);
/**
* Sets an EGA palette based on a 16-byte EGA RGB indexes
*/
void setEGAPalette(const byte *palette);
/**
* Sets up a CGA palette
*/
void setCGAPalette();
/**
* Returns the map
*/
Maps::Map *getMap() const override { return _map; }
/**
* Handles loading and saving games
*/
void synchronize(Common::Serializer &s) override;
/**
* Signal an end of turn
*/
void endOfTurn();
};
} // End of namespace Shared
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,262 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/config-manager.h"
#include "common/system.h"
#include "ultima/shared/early/ultima_early.h"
#include "ultima/shared/early/game_base.h"
#include "ultima/shared/engine/messages.h"
#include "ultima/shared/core/mouse_cursor.h"
#include "ultima/shared/gfx/font.h"
#include "ultima/shared/gfx/text_cursor.h"
#include "ultima/shared/gfx/text_input.h"
#include "ultima/shared/gfx/visual_container.h"
namespace Ultima {
namespace Shared {
GameBase::GameBase(): _currentView(nullptr), _pendingPopup(nullptr), _font(nullptr), _priorLeftDownTime(0),
_priorMiddleDownTime(0), _priorRightDownTime(0), _inputHandler(this), _inputTranslator(&_inputHandler),
_videoMode(0), _textCursor(nullptr) {
}
GameBase::~GameBase() {
delete _font;
delete _textCursor;
}
int GameBase::getSavegameSlot() {
return 0;
}
void GameBase::mouseChanged() {
}
void GameBase::onIdle() {
// Handle any drawing updates
update();
}
#define HANDLE_MESSAGE(METHOD) \
_inputTranslator.METHOD(g_vm->_events->getSpecialButtons(), mousePos); \
mouseChanged()
void GameBase::mouseMove(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
HANDLE_MESSAGE(mouseMove);
}
void GameBase::leftButtonDown(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
if ((g_vm->_events->getTicksCount() - _priorLeftDownTime) < DOUBLE_CLICK_TIME) {
_priorLeftDownTime = 0;
leftButtonDoubleClick(mousePos);
} else {
_priorLeftDownTime = g_vm->_events->getTicksCount();
HANDLE_MESSAGE(leftButtonDown);
}
}
void GameBase::leftButtonUp(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
HANDLE_MESSAGE(leftButtonUp);
}
void GameBase::leftButtonDoubleClick(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
HANDLE_MESSAGE(leftButtonDoubleClick);
}
void GameBase::middleButtonDown(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
if ((g_vm->_events->getTicksCount() - _priorMiddleDownTime) < DOUBLE_CLICK_TIME) {
_priorMiddleDownTime = 0;
middleButtonDoubleClick(mousePos);
} else {
_priorMiddleDownTime = g_vm->_events->getTicksCount();
HANDLE_MESSAGE(middleButtonDown);
}
}
void GameBase::middleButtonUp(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
HANDLE_MESSAGE(middleButtonUp);
}
void GameBase::middleButtonDoubleClick(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
HANDLE_MESSAGE(middleButtonDoubleClick);
}
void GameBase::rightButtonDown(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
if ((g_vm->_events->getTicksCount() - _priorRightDownTime) < DOUBLE_CLICK_TIME) {
_priorRightDownTime = 0;
rightButtonDoubleClick(mousePos);
} else {
_priorRightDownTime = g_vm->_events->getTicksCount();
HANDLE_MESSAGE(rightButtonDown);
}
}
void GameBase::rightButtonUp(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
HANDLE_MESSAGE(rightButtonUp);
}
void GameBase::mouseWheel(const Point &mousePos, bool wheelUp) {
if (!isMouseControlEnabled())
return;
_inputTranslator.mouseWheel(wheelUp, mousePos);
mouseChanged();
}
void GameBase::rightButtonDoubleClick(const Point &mousePos) {
if (!isMouseControlEnabled())
return;
HANDLE_MESSAGE(rightButtonDoubleClick);
}
void GameBase::keyDown(Common::KeyState keyState) {
_inputTranslator.keyDown(keyState);
}
void GameBase::setView(Gfx::VisualItem *view) {
_currentView = view;
}
void GameBase::setView(const Common::String &viewName) {
Gfx::VisualItem *view = dynamic_cast<Gfx::VisualItem *>(findByName(viewName));
if (view != _currentView) {
_currentView = view;
assert(_currentView);
// Signal the view that it's now active
CShowMsg showMsg;
showMsg.execute(_currentView);
}
}
void GameBase::setPopup(Gfx::Popup *popup) {
assert(!_pendingPopup);
_pendingPopup = popup;
}
void GameBase::update() {
if (_currentView) {
// Signal the next frame
CFrameMsg frameMsg(g_vm->_events->getTicksCount());
frameMsg.execute(_currentView);
// Draw the view
if (_currentView->isDirty()) {
_currentView->draw();
_currentView->clearDirty();
} else if (_pendingPopup) {
// There's a pending popup to display, so make it active
_currentView = _pendingPopup;
_pendingPopup = nullptr;
CShowMsg showMsg;
showMsg.execute(_currentView);
}
// Allow the text cursor to update
_textCursor->update();
}
}
void GameBase::changeView(const Common::String &name) {
Gfx::VisualItem *newView = dynamic_cast<Gfx::VisualItem *>(findByName(name));
assert(newView);
// Hide the current view
CHideMsg hideMsg(_currentView, true);
hideMsg.execute(_currentView, nullptr, MSGFLAG_SCAN);
if (hideMsg._fadeOut) {
// TODO: Fade out
}
// Show the new view
_currentView = newView;
CShowMsg showMsg(_currentView, true);
showMsg.execute(_currentView, nullptr, MSGFLAG_SCAN);
_currentView->draw();
if (showMsg._fadeIn) {
// TODO: Fade in
}
}
void GameBase::setFont(Gfx::Font *font) {
delete _font;
_font = font;
}
uint GameBase::getRandomNumber(uint max) {
return g_vm->getRandomNumber(max);
}
uint GameBase::getRandomNumber(uint min, uint max) {
return g_vm->getRandomNumber(min, max);
}
void GameBase::sleep(uint time) {
g_vm->_events->sleep(time);
}
uint32 GameBase::getMillis() const {
return g_system->getMillis();
}
void GameBase::synchronize(Common::Serializer &s) {
_priorLeftDownTime = 0;
_priorMiddleDownTime = 0;
_priorRightDownTime = 0;
}
} // End of namespace Shared
} // End of namespace Ultima

View File

@@ -0,0 +1,203 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_SHARED_EARLY_GAME_BASE_H
#define ULTIMA_SHARED_EARLY_GAME_BASE_H
#include "common/scummsys.h"
#include "common/array.h"
#include "common/serializer.h"
#include "ultima/shared/engine/events.h"
#include "ultima/shared/engine/input_handler.h"
#include "ultima/shared/engine/input_translator.h"
namespace Ultima {
namespace Shared {
class UltimaEngine;
class GameState;
namespace Gfx {
class Font;
class Popup;
class TextCursor;
class TextInput;
class VisualItem;
} // End of namespace Gfx
namespace Maps {
class Map;
} // End of namespace Maps
/**
* Base class for the game implementations
*/
class GameBase : public TreeItem, public EventTarget {
private:
/**
* Checks for the presence of any savegames and, if present,
* lets the user pick one to resume
*/
int getSavegameSlot();
void leftButtonDoubleClick(const Point &mousePos) override;
void middleButtonDoubleClick(const Point &mousePos) override;
void rightButtonDoubleClick(const Point &mousePos);
/**
* Returns true if the player can control the mouse
*/
bool isMouseControlEnabled() const { return true; }
void changeView(const Common::String &name);
protected:
uint32 _priorLeftDownTime;
uint32 _priorMiddleDownTime;
uint32 _priorRightDownTime;
Gfx::VisualItem *_currentView;
Gfx::Popup *_pendingPopup;
InputHandler _inputHandler;
InputTranslator _inputTranslator;
Gfx::Font *_font;
public:
Gfx::TextCursor *_textCursor;
uint _videoMode;
public:
/**
* Constructor
*/
GameBase();
/**
* Destructor
*/
~GameBase() override;
/**
* Called to handle any regular updates the game requires
*/
void onIdle() override;
void mouseMove(const Point &mousePos) override;
void leftButtonDown(const Point &mousePos) override;
void leftButtonUp(const Point &mousePos) override;
void middleButtonDown(const Point &mousePos) override;
void middleButtonUp(const Point &mousePos) override;
void rightButtonDown(const Point &mousePos) override;
void rightButtonUp(const Point &mousePos) override;
void mouseWheel(const Point &mousePos, bool wheelUp) override;
void keyDown(Common::KeyState keyState) override;
/**
* Called when the game starts
*/
virtual void starting(bool isLoading) {}
/**
* Returns true if the current video mode is VGA
*/
virtual bool isVGA() const { return false; }
/**
* Called once every frame to update the game and render the view
*/
void update();
/**
* Called by the event handler when a mouse event has been generated
*/
void mouseChanged();
/**
* Set the currently active view to display
*/
void setView(Gfx::VisualItem *view);
/**
* Set the currently active view to display
*/
void setView(const Common::String &viewName);
/**
* Sets a popup to be shown
*/
void setPopup(Gfx::Popup *popup);
/**
* Returns the current view
*/
Gfx::VisualItem *getView() const { return _currentView; }
/**
* Set a font to use
*/
void setFont(Gfx::Font *font);
/**
* Returns the current font
*/
Gfx::Font *getFont() const { return _font; }
/**
* Returns the map
*/
virtual Maps::Map *getMap() const { return nullptr; }
/**
* Gets a random number
*/
uint getRandomNumber(uint max);
/**
* Gets a random number
*/
uint getRandomNumber(uint min, uint max);
/**
* Wait for a given period of time
*/
void sleep(uint time);
/**
* Return the current time
*/
uint32 getMillis() const;
/**
* Returns true if a savegame can currently be loaded
*/
virtual bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) { return true; }
/**
* Returns true if the game can currently be saved
*/
virtual bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) { return false; }
/**
* Handles loading and saving games
*/
virtual void synchronize(Common::Serializer &s);
};
} // End of namespace Shared
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,164 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/scummsys.h"
#include "common/config-manager.h"
#include "common/debug-channels.h"
#include "common/system.h"
#include "common/translation.h"
#include "graphics/thumbnail.h"
#include "graphics/scaler.h"
#include "gui/saveload.h"
#include "ultima/shared/early/ultima_early.h"
#include "ultima/shared/early/game.h"
#include "ultima/shared/engine/events.h"
#include "ultima/shared/engine/resources.h"
#include "ultima/shared/core/mouse_cursor.h"
#include "ultima/shared/gfx/screen.h"
#ifndef RELEASE_BUILD
#include "ultima/ultima1/game.h"
#endif
namespace Ultima {
Shared::UltimaEarlyEngine *g_vm;
namespace Shared {
UltimaEarlyEngine::UltimaEarlyEngine(OSystem *syst, const UltimaGameDescription *gameDesc) :
Engine(syst), _gameDescription(gameDesc), _game(nullptr), _randomSource("Ultima") {
g_vm = this;
_mouseCursor = nullptr;
_screen = nullptr;
}
UltimaEarlyEngine::~UltimaEarlyEngine() {
delete _events;
delete _game;
delete _mouseCursor;
delete _screen;
}
bool UltimaEarlyEngine::initialize() {
// Call syncSoundSettings to get default volumes set
syncSoundSettings();
// Set up the resources datafile
Resources *res = new Resources();
if (!res->open()) {
GUIErrorMessage(_("Could not find correct ultima.dat datafile"));
return false;
}
SearchMan.add("ultima", res);
_events = new EventsManager(this);
_screen = new Gfx::Screen();
// Create the game, and signal to it that the game is starting
_game = createGame();
_events->addTarget(_game);
_game->starting(false);
// Load cursors
_mouseCursor = new MouseCursor();
// If requested, load a savegame instead of showing the intro
if (ConfMan.hasKey("save_slot")) {
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot >= 0 && saveSlot <= 999)
loadGameState(saveSlot);
}
return true;
}
Common::Error UltimaEarlyEngine::run() {
// Initialize the engine and play the game
if (initialize())
playGame();
// Deinitialize and free the engine
deinitialize();
return Common::kNoError;
}
bool UltimaEarlyEngine::hasFeature(EngineFeature f) const {
return
(f == kSupportsReturnToLauncher) ||
(f == kSupportsLoadingDuringRuntime) ||
(f == kSupportsChangingOptionsDuringRuntime) ||
(f == kSupportsSavingDuringRuntime);
}
void UltimaEarlyEngine::playGame() {
while (!shouldQuit()) {
_events->pollEventsAndWait();
}
}
Graphics::Screen *UltimaEarlyEngine::getScreen() const {
return _screen;
}
GameId UltimaEarlyEngine::getGameId() const {
return _gameDescription->gameId;
}
bool UltimaEarlyEngine::isEnhanced() const {
return _gameDescription->features & GF_VGA_ENHANCED;
}
Game *UltimaEarlyEngine::createGame() const {
switch (getGameId()) {
#ifndef RELEASE_BUILD
case GAME_ULTIMA1:
return new Ultima1::Ultima1Game();
#endif
default:
error("Unknown game");
}
}
Common::Error UltimaEarlyEngine::loadGameStream(Common::SeekableReadStream *stream) {
// Read in the game's data
Common::Serializer s(stream, nullptr);
_game->synchronize(s);
return Common::kNoError;
}
Common::Error UltimaEarlyEngine::saveGameStream(Common::WriteStream *stream, bool) {
// Write out the game's data
Common::Serializer s(nullptr, stream);
_game->synchronize(s);
return Common::kNoError;
}
bool UltimaEarlyEngine::canLoadGameStateCurrently(Common::U32String *msg) {
return _game->canLoadGameStateCurrently(msg);
}
bool UltimaEarlyEngine::canSaveGameStateCurrently(Common::U32String *msg) {
return _game->canSaveGameStateCurrently(msg);
}
} // End of namespace Shared
} // End of namespace Ultima

View File

@@ -0,0 +1,169 @@
/* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef ULTIMA_SHARED_EARLY_ULTIMA_EARLY_H
#define ULTIMA_SHARED_EARLY_ULTIMA_EARLY_H
#include "common/scummsys.h"
#include "common/array.h"
#include "common/endian.h"
#include "common/hash-str.h"
#include "common/serializer.h"
#include "common/random.h"
#include "common/savefile.h"
#include "common/util.h"
#include "graphics/surface.h"
#include "engines/engine.h"
#include "ultima/detection.h"
#include "ultima/shared/engine/events.h"
namespace Ultima {
struct UltimaGameDescription;
namespace Shared {
struct UltimaSavegameHeader {
uint8 _version;
uint8 _gameId;
uint8 _language;
uint8 _videoMode;
Common::String _saveName;
Graphics::Surface *_thumbnail;
int _year, _month, _day;
int _hour, _minute;
int _totalFrames;
};
class Events;
class Game;
class GameBase;
class MouseCursor;
class Resources;
namespace Gfx {
class Screen;
}
class UltimaEarlyEngine : public Engine, public EventsCallback {
private:
/**
* Initialize the engine
*/
virtual bool initialize();
/**
* Deinitialize the engine
*/
virtual void deinitialize() {}
private:
Common::RandomSource _randomSource;
protected:
const UltimaGameDescription *_gameDescription;
public:
GameBase *_game;
MouseCursor *_mouseCursor;
Gfx::Screen *_screen;
EventsManager *_events;
public:
UltimaEarlyEngine(OSystem *syst, const UltimaGameDescription *gameDesc);
~UltimaEarlyEngine() override;
/**
* Main method for running the game
*/
Common::Error run() override;
/**
* Returns supported engine features
*/
bool hasFeature(EngineFeature f) const override;
/**
* Play the game
*/
void playGame();
/**
* Get a random number
*/
uint getRandomNumber(uint maxVal) { return _randomSource.getRandomNumber(maxVal); }
/**
* Gets a random number
*/
uint getRandomNumber(uint min, uint max) {
return min + _randomSource.getRandomNumber(max - min);
}
/**
* Get the screen
*/
Graphics::Screen *getScreen() const override;
/**
* Indicates whether a game state can be loaded.
* @param isAutosave Flags whether it's an autosave check
*/
bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
/**
* Indicates whether a game state can be saved.
* @param isAutosave Flags whether it's an autosave check
*/
bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
/**
* Load a savegame
*/
Common::Error loadGameStream(Common::SeekableReadStream *stream) override;
/**
* Save a game state.
*/
Common::Error saveGameStream(Common::WriteStream *stream, bool isAutosave = false) override;
/**
* Returns the game type being played
*/
GameId getGameId() const;
/**
* Returns true if the game is running an enhanced version
* as compared to the original game
*/
bool isEnhanced() const;
/*
* Creates a new hierarchy for the game, that contains all the logic for playing that particular game.
*/
Game *createGame() const;
};
} // End of namespace Shared
extern Shared::UltimaEarlyEngine *g_vm;
} // End of namespace Ultima
#endif