mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
cf47fb1c69
svn-id: r10781
1207 lines
35 KiB
C++
1207 lines
35 KiB
C++
/* 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$
|
|
*
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "queen/graphics.h"
|
|
#include "queen/resource.h"
|
|
|
|
|
|
namespace Queen {
|
|
|
|
|
|
const uint8 Graphics::FONT[] = {
|
|
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
|
|
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80,
|
|
0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0,
|
|
0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00,
|
|
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
|
|
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80,
|
|
0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0,
|
|
0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00,
|
|
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
|
|
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80,
|
|
0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0,
|
|
0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00,
|
|
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
|
|
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80,
|
|
0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0,
|
|
0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00,
|
|
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
|
|
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80,
|
|
0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0,
|
|
0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00,
|
|
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
|
|
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80,
|
|
0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0,
|
|
0xC0, 0x00, 0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00,
|
|
0xF8, 0xB0, 0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0xF8, 0xB0,
|
|
0xB0, 0x80, 0xB0, 0xB0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0,
|
|
0xC0, 0x00, 0xD8, 0xD8, 0x00, 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, 0x68, 0x36, 0xDC, 0xCC,
|
|
0x76, 0x00, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x30, 0x60, 0xC0, 0xC0, 0xC0, 0x60, 0x30, 0x00, 0xC0, 0x60,
|
|
0x30, 0x30, 0x30, 0x60, 0xC0, 0x00, 0x00, 0x6C, 0x38, 0xFE,
|
|
0x38, 0x6C, 0x00, 0x00, 0x00, 0x30, 0x30, 0xFC, 0x30, 0x30,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0xC0,
|
|
0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x03, 0x06, 0x0C, 0x18,
|
|
0x30, 0x60, 0xC0, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
|
0x78, 0x00, 0x30, 0x70, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x00,
|
|
0x78, 0xCC, 0x0C, 0x78, 0xC0, 0xC0, 0xFC, 0x00, 0x78, 0xCC,
|
|
0x0C, 0x38, 0x0C, 0xCC, 0x78, 0x00, 0x1C, 0x3C, 0x6C, 0xCC,
|
|
0xFC, 0x0C, 0x0C, 0x00, 0xFC, 0xC0, 0xF8, 0x0C, 0x0C, 0xCC,
|
|
0x78, 0x00, 0x78, 0xCC, 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, 0xCC, 0x78, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0,
|
|
0xC0, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x60, 0xC0,
|
|
0x18, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x00,
|
|
0xFC, 0x00, 0xFC, 0x00, 0x00, 0x00, 0xC0, 0x60, 0x30, 0x18,
|
|
0x30, 0x60, 0xC0, 0x00, 0x78, 0xCC, 0x0C, 0x18, 0x30, 0x00,
|
|
0x30, 0x00, 0x6C, 0xFE, 0xFE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
|
|
0x38, 0x7C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0xF8, 0xCC,
|
|
0xCC, 0xF8, 0xCC, 0xCC, 0xF8, 0x00, 0x78, 0xCC, 0xC0, 0xC0,
|
|
0xC0, 0xCC, 0x78, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC,
|
|
0xF8, 0x00, 0xFC, 0xC0, 0xC0, 0xF0, 0xC0, 0xC0, 0xFC, 0x00,
|
|
0xFC, 0xC0, 0xC0, 0xF0, 0xC0, 0xC0, 0xC0, 0x00, 0x78, 0xCC,
|
|
0xC0, 0xDC, 0xCC, 0xCC, 0x7C, 0x00, 0xCC, 0xCC, 0xCC, 0xFC,
|
|
0xCC, 0xCC, 0xCC, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60,
|
|
0xF0, 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0x78, 0x00,
|
|
0xC6, 0xCC, 0xD8, 0xF8, 0xD8, 0xCC, 0xC6, 0x00, 0xC0, 0xC0,
|
|
0xC0, 0xC0, 0xC0, 0xC0, 0xFC, 0x00, 0x82, 0xC6, 0xEE, 0xFE,
|
|
0xD6, 0xC6, 0xC6, 0x00, 0xC6, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6,
|
|
0xC6, 0x00, 0x78, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x78, 0x00,
|
|
0xF8, 0xCC, 0xCC, 0xF8, 0xC0, 0xC0, 0xC0, 0x00, 0x78, 0xCC,
|
|
0xCC, 0xCC, 0xCC, 0xDC, 0x78, 0x0C, 0xF8, 0xCC, 0xCC, 0xF8,
|
|
0xD8, 0xCC, 0xCC, 0x00, 0x78, 0xCC, 0xC0, 0x78, 0x0C, 0xCC,
|
|
0x78, 0x00, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00,
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x00, 0xC6, 0xC6,
|
|
0x6C, 0x6C, 0x38, 0x38, 0x10, 0x00, 0xC6, 0xC6, 0xC6, 0xD6,
|
|
0xFE, 0xEE, 0xC6, 0x00, 0xC6, 0x6C, 0x38, 0x10, 0x38, 0x6C,
|
|
0xC6, 0x00, 0xCC, 0xCC, 0xCC, 0x78, 0x30, 0x30, 0x30, 0x00,
|
|
0xFC, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xFC, 0x00, 0xF0, 0xC0,
|
|
0xC0, 0xC0, 0xC0, 0xC0, 0xF0, 0x00, 0xC0, 0x60, 0x30, 0x18,
|
|
0x0C, 0x06, 0x03, 0x00, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x30,
|
|
0xF0, 0x00, 0xE8, 0x4D, 0x4A, 0x48, 0x00, 0x00, 0x00, 0x00,
|
|
0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0,
|
|
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C,
|
|
0x7C, 0xCC, 0x7C, 0x00, 0xC0, 0xC0, 0xF8, 0xCC, 0xCC, 0xCC,
|
|
0xF8, 0x00, 0x00, 0x00, 0x78, 0xCC, 0xC0, 0xCC, 0x78, 0x00,
|
|
0x0C, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x7C, 0x00, 0x00, 0x00,
|
|
0x78, 0xCC, 0xFC, 0xC0, 0x78, 0x00, 0x38, 0x6C, 0x60, 0xF8,
|
|
0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x7C, 0xCC, 0xCC, 0x7C,
|
|
0x0C, 0x78, 0xC0, 0xC0, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00,
|
|
0xC0, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x0C, 0x00,
|
|
0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0x78, 0xC0, 0xC0, 0xCC, 0xD8,
|
|
0xF0, 0xD8, 0xCC, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
|
|
0xC0, 0x00, 0x00, 0x00, 0xCC, 0xEE, 0xD6, 0xC6, 0xC6, 0x00,
|
|
0x00, 0x00, 0xF8, 0xCC, 0xCC, 0xCC, 0xCC, 0x00, 0x00, 0x00,
|
|
0x78, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00, 0xF8, 0xCC,
|
|
0xCC, 0xF8, 0xC0, 0xC0, 0x00, 0x00, 0x7C, 0xCC, 0xCC, 0x7C,
|
|
0x0C, 0x0C, 0x00, 0x00, 0xF8, 0xCC, 0xC0, 0xC0, 0xC0, 0x00,
|
|
0x00, 0x00, 0x7C, 0xC0, 0x78, 0x0C, 0x78, 0x00, 0x30, 0x30,
|
|
0xFC, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0xCC, 0xCC,
|
|
0xCC, 0xCC, 0x7C, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0x78,
|
|
0x30, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xD6, 0x6C, 0x6C, 0x00,
|
|
0x00, 0x00, 0xCC, 0x78, 0x30, 0x78, 0xCC, 0x00, 0x00, 0x00,
|
|
0xCC, 0xCC, 0xCC, 0x78, 0x30, 0xE0, 0x00, 0x00, 0xFC, 0x18,
|
|
0x30, 0x60, 0xFC, 0x00, 0x38, 0x60, 0x60, 0xC0, 0x60, 0x60,
|
|
0x38, 0x00, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0xC0, 0x00,
|
|
0xE0, 0x30, 0x30, 0x18, 0x30, 0x30, 0xE0, 0x00, 0x38, 0x44,
|
|
0xBA, 0xAA, 0xBA, 0x44, 0x38, 0x00, 0x00, 0x98, 0x30, 0x60,
|
|
0xC8, 0x98, 0x30, 0x00, 0x1E, 0x30, 0x60, 0x60, 0x30, 0x1E,
|
|
0x0C, 0x18, 0x00, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x00,
|
|
0x0C, 0x18, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0x18, 0x66,
|
|
0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x3C, 0x06, 0x3E, 0x66,
|
|
0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x1E, 0x30, 0x60, 0x60, 0x30, 0x1E, 0x0C, 0x18, 0x18, 0x66,
|
|
0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0x66, 0x00, 0x3C, 0x66,
|
|
0x7E, 0x60, 0x3C, 0x00, 0x30, 0x18, 0x3C, 0x66, 0x7E, 0x60,
|
|
0x3C, 0x00, 0x00, 0x66, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
|
|
0x18, 0x66, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x30, 0x18,
|
|
0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x18, 0x30, 0xFC, 0xC0, 0xF0, 0xC0, 0xFC, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0x3C,
|
|
0x66, 0x66, 0x3C, 0x00, 0x00, 0x66, 0x00, 0x3C, 0x66, 0x66,
|
|
0x3C, 0x00, 0x30, 0x18, 0x00, 0x3C, 0x66, 0x66, 0x3C, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
|
|
0x00, 0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x18, 0x30, 0x78, 0x0C, 0x7C, 0xCC, 0x7C, 0x00, 0x0C, 0x18,
|
|
0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x30, 0x00, 0x78,
|
|
0xCC, 0xCC, 0x78, 0x00, 0x18, 0x30, 0x00, 0xCC, 0xCC, 0xCC,
|
|
0x7C, 0x00, 0x71, 0x8E, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x00,
|
|
0x71, 0xCE, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0x00, 0x18, 0x18,
|
|
0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x3C, 0x60, 0x3C, 0x66,
|
|
0x3C, 0x06, 0x3C, 0x00, 0x18, 0x00, 0x18, 0x0C, 0x06, 0x66,
|
|
0x3C, 0x00, 0x3F, 0x40, 0x4E, 0x58, 0x4E, 0x40, 0x3F, 0x00,
|
|
0x1C, 0xA4, 0xC4, 0xBC, 0x80, 0xFE, 0x00, 0x00, 0x00, 0x33,
|
|
0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, 0x3E, 0x06, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0xC0,
|
|
0xC0, 0x00, 0x81, 0xB9, 0xA5, 0xB9, 0xA5, 0x81, 0x7E, 0x00,
|
|
0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xCC,
|
|
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xFC, 0x30,
|
|
0x30, 0x00, 0xFC, 0x00, 0xF0, 0x18, 0x30, 0x60, 0xF8, 0x00,
|
|
0x00, 0x00, 0xF0, 0x18, 0x30, 0x18, 0xF0, 0x00, 0x00, 0x00,
|
|
0x30, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xCC, 0xCC, 0xCC, 0xCC, 0xFE, 0xC0, 0x3E, 0x7A, 0x7A, 0x3A,
|
|
0x0A, 0x0A, 0x0A, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60,
|
|
0x60, 0xE0, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x38, 0x44,
|
|
0x44, 0x38, 0x00, 0x7C, 0x00, 0x00, 0x00, 0xCC, 0x66, 0x33,
|
|
0x66, 0xCC, 0x00, 0x00, 0x40, 0xC6, 0x4C, 0x58, 0x32, 0x66,
|
|
0xCF, 0x02, 0x40, 0xC6, 0x4C, 0x58, 0x3E, 0x62, 0xC4, 0x0E,
|
|
0xC0, 0x23, 0x66, 0x2C, 0xD9, 0x33, 0x67, 0x01, 0x18, 0x00,
|
|
0x18, 0x30, 0x60, 0x66, 0x3C, 0x00, 0x60, 0x30, 0x7C, 0xC6,
|
|
0xFE, 0xC6, 0xC6, 0x00, 0x0C, 0x18, 0x7C, 0xC6, 0xFE, 0xC6,
|
|
0xC6, 0x00, 0x38, 0xC6, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00,
|
|
0x71, 0x8E, 0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x6C, 0x00,
|
|
0x7C, 0xC6, 0xFE, 0xC6, 0xC6, 0x00, 0x38, 0x44, 0x7C, 0xC6,
|
|
0xFE, 0xC6, 0xC6, 0x00, 0x1F, 0x3C, 0x3C, 0x6F, 0x7C, 0xCC,
|
|
0xCF, 0x00, 0x1E, 0x30, 0x60, 0x60, 0x30, 0x1E, 0x0C, 0x18,
|
|
0x60, 0x30, 0xFC, 0xC0, 0xF0, 0xC0, 0xFC, 0x00, 0x18, 0x30,
|
|
0xFC, 0xC0, 0xF0, 0xC0, 0xFC, 0x00, 0x30, 0xCC, 0xFC, 0xC0,
|
|
0xF0, 0xC0, 0xFC, 0x00, 0xCC, 0x00, 0xFC, 0xC0, 0xF0, 0xC0,
|
|
0xFC, 0x00, 0x60, 0x30, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00,
|
|
0x18, 0x30, 0x78, 0x30, 0x30, 0x30, 0x78, 0x00, 0x30, 0xCC,
|
|
0x78, 0x30, 0x30, 0x30, 0x78, 0x00, 0xCC, 0x00, 0x78, 0x30,
|
|
0x30, 0x30, 0x78, 0x00, 0x78, 0x6C, 0x66, 0xF6, 0x66, 0x6C,
|
|
0x78, 0x00, 0x71, 0xCE, 0xE6, 0xF6, 0xDE, 0xCE, 0xC6, 0x00,
|
|
0x30, 0x18, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x0C, 0x18,
|
|
0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, 0x18, 0x66, 0x3C, 0x66,
|
|
0x66, 0x66, 0x3C, 0x00, 0x71, 0x8E, 0x3C, 0x66, 0x66, 0x66,
|
|
0x3C, 0x00, 0xC3, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
|
0x00, 0xC6, 0x6C, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x3F, 0x66,
|
|
0x6E, 0x7E, 0x76, 0x66, 0xFC, 0x00, 0x30, 0x18, 0x66, 0x66,
|
|
0x66, 0x66, 0x3E, 0x00, 0x0C, 0x18, 0x66, 0x66, 0x66, 0x66,
|
|
0x3E, 0x00, 0x18, 0x24, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00,
|
|
0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, 0x06, 0x08,
|
|
0xC3, 0x66, 0x3C, 0x18, 0x18, 0x00, 0x60, 0x60, 0x7E, 0x63,
|
|
0x7E, 0x60, 0x60, 0x00, 0x3C, 0x66, 0x66, 0x6C, 0x66, 0x66,
|
|
0x6C, 0x60, 0x30, 0x18, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00,
|
|
0x0C, 0x18, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, 0x18, 0x66,
|
|
0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, 0x71, 0x8E, 0x3C, 0x06,
|
|
0x3E, 0x66, 0x3E, 0x00, 0x66, 0x00, 0x3C, 0x06, 0x3E, 0x66,
|
|
0x3E, 0x00, 0x18, 0x24, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00,
|
|
0x00, 0x00, 0x7E, 0x1B, 0x7F, 0xD8, 0x77, 0x00, 0x00, 0x00,
|
|
0x3C, 0x60, 0x60, 0x60, 0x3C, 0x18, 0x30, 0x18, 0x3C, 0x66,
|
|
0x7E, 0x60, 0x3C, 0x00, 0x0C, 0x18, 0x3C, 0x66, 0x7E, 0x60,
|
|
0x3C, 0x00, 0x18, 0x66, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00,
|
|
0x66, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, 0x30, 0x18,
|
|
0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x0C, 0x18, 0x00, 0x18,
|
|
0x18, 0x18, 0x18, 0x00, 0x18, 0x66, 0x00, 0x18, 0x18, 0x18,
|
|
0x18, 0x00, 0x00, 0x66, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00,
|
|
0x60, 0xFC, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x71, 0x8E,
|
|
0x00, 0x7C, 0x66, 0x66, 0x66, 0x00, 0x30, 0x18, 0x00, 0x3C,
|
|
0x66, 0x66, 0x3C, 0x00, 0x0C, 0x18, 0x00, 0x3C, 0x66, 0x66,
|
|
0x3C, 0x00, 0x18, 0x66, 0x00, 0x3C, 0x66, 0x66, 0x3C, 0x00,
|
|
0x71, 0x8E, 0x00, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x66,
|
|
0x00, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x18, 0x00, 0x7E,
|
|
0x00, 0x18, 0x00, 0x00, 0x00, 0x02, 0x7C, 0xCE, 0xD6, 0xE6,
|
|
0x7C, 0x80, 0x30, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x00,
|
|
0x0C, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x00, 0x18, 0x66,
|
|
0x00, 0x66, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x66, 0x00, 0x66,
|
|
0x66, 0x66, 0x3E, 0x00, 0x0C, 0x18, 0x00, 0x66, 0x66, 0x3C,
|
|
0x18, 0x30, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60,
|
|
0x00, 0x66, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x30, 0xFF
|
|
};
|
|
|
|
|
|
const uint8 Graphics::FONT_SIZES[] = {
|
|
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
|
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
|
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
|
0x06, 0x06, 0x04, 0x03, 0x06, 0x08, 0x07, 0x08, 0x08, 0x04,
|
|
0x05, 0x05, 0x08, 0x07, 0x04, 0x07, 0x03, 0x09, 0x07, 0x05,
|
|
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x04,
|
|
0x06, 0x07, 0x06, 0x07, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07,
|
|
0x07, 0x07, 0x07, 0x05, 0x07, 0x08, 0x07, 0x08, 0x08, 0x07,
|
|
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x07,
|
|
0x07, 0x05, 0x09, 0x05, 0x08, 0x02, 0x04, 0x07, 0x07, 0x07,
|
|
0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x03, 0x08,
|
|
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08,
|
|
0x07, 0x07, 0x07, 0x06, 0x03, 0x06, 0x08, 0x06, 0x08, 0x08,
|
|
0x08, 0x08, 0x02, 0x08, 0x02, 0x08, 0x08, 0x08, 0x08, 0x08,
|
|
0x08, 0x06, 0x02, 0x02, 0x07, 0x02, 0x02, 0x08, 0x08, 0x08,
|
|
0x02, 0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
|
|
0x07, 0x07, 0x07, 0x07, 0x09, 0x09, 0x06, 0x08, 0x08, 0x09,
|
|
0x08, 0x09, 0x08, 0x03, 0x09, 0x07, 0x07, 0x07, 0x06, 0x06,
|
|
0x05, 0x08, 0x08, 0x06, 0x05, 0x04, 0x07, 0x09, 0x09, 0x08,
|
|
0x09, 0x08, 0x08, 0x08, 0x08, 0x09, 0x08, 0x08, 0x09, 0x08,
|
|
0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07, 0x08, 0x09,
|
|
0x08, 0x08, 0x08, 0x09, 0x09, 0x08, 0x09, 0x08, 0x08, 0x08,
|
|
0x08, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x09, 0x08, 0x08,
|
|
0x09, 0x07, 0x08, 0x08, 0x08, 0x08, 0x06, 0x07, 0x08, 0x08,
|
|
0x08, 0x09, 0x08, 0x08, 0x08, 0x09, 0x08, 0x08, 0x08, 0x08,
|
|
0x08, 0x08, 0x08, 0x08, 0x08, 0x08
|
|
};
|
|
|
|
|
|
Graphics::Graphics(Resource *resource)
|
|
: _cameraBob(0), _resource(resource) {
|
|
|
|
memset(_frames, 0, sizeof(_frames));
|
|
memset(_banks, 0, sizeof(_banks));
|
|
memset(_bobs, 0, sizeof(_bobs));
|
|
memset(_sortedBobs, 0, sizeof(_sortedBobs));
|
|
_sortedBobsCount = 0;
|
|
_shrinkBuffer.data = new uint8[ BOB_SHRINK_BUF_SIZE ];
|
|
_backdrop = new uint8[ BACKDROP_W * BACKDROP_H ];
|
|
_panel = new uint8[ PANEL_W * PANEL_H ];
|
|
_screen = new uint8[ SCREEN_W * SCREEN_H ];
|
|
_fullscreen = true;
|
|
_horizontalScroll = 0;
|
|
_paletteRoom = new uint8[ 256 * 3 ];
|
|
_paletteScreen = new uint8[ 256 * 4 ];
|
|
}
|
|
|
|
|
|
Graphics::~Graphics() {
|
|
uint32 i;
|
|
for(i = 0; i < ARRAYSIZE(_banks); ++i) {
|
|
delete _banks[i].data;
|
|
}
|
|
frameEraseAll(true);
|
|
delete[] _shrinkBuffer.data;
|
|
delete[] _backdrop;
|
|
delete[] _panel;
|
|
delete[] _screen;
|
|
delete[] _paletteRoom;
|
|
delete[] _paletteScreen;
|
|
}
|
|
|
|
|
|
void Graphics::bankLoad(const char *bankname, uint32 bankslot) {
|
|
|
|
int16 i;
|
|
|
|
bankErase(bankslot);
|
|
_banks[bankslot].data = _resource->loadFile(bankname);
|
|
if (!_banks[bankslot].data) {
|
|
error("Unable to open bank '%s'", bankname);
|
|
}
|
|
|
|
int16 entries = (int16)READ_LE_UINT16(_banks[bankslot].data);
|
|
if (entries < 0 || entries >= MAX_BANK_SIZE) {
|
|
error("Maximum bank size exceeded or negative bank size : %d", entries);
|
|
}
|
|
|
|
uint32 offset = 2;
|
|
uint8 *p = _banks[bankslot].data;
|
|
for (i = 1; i <= entries; ++i) {
|
|
_banks[bankslot].indexes[i] = offset;
|
|
uint16 w = READ_LE_UINT16(p + offset + 0);
|
|
uint16 h = READ_LE_UINT16(p + offset + 2);
|
|
// jump to next entry, skipping data & header
|
|
offset += w * h + 8;
|
|
}
|
|
|
|
debug(5, "Loaded bank '%s' in slot %d, %d entries", bankname, bankslot, entries);
|
|
}
|
|
|
|
|
|
void Graphics::bankUnpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) {
|
|
|
|
uint8 *p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe];
|
|
|
|
BobFrame *pbf = &_frames[dstframe];
|
|
delete[] pbf->data;
|
|
|
|
pbf->width = READ_LE_UINT16(p + 0);
|
|
pbf->height = READ_LE_UINT16(p + 2);
|
|
pbf->xhotspot = READ_LE_UINT16(p + 4);
|
|
pbf->yhotspot = READ_LE_UINT16(p + 6);
|
|
|
|
uint32 size = pbf->width * pbf->height;
|
|
pbf->data = new uint8[ size ];
|
|
memcpy(pbf->data, p + 8, size);
|
|
|
|
debug(5, "Unpacked frame %d from bank slot %d to frame slot %d", srcframe, bankslot, dstframe);
|
|
}
|
|
|
|
|
|
void Graphics::bankOverpack(uint32 srcframe, uint32 dstframe, uint32 bankslot) {
|
|
|
|
uint8 *p = _banks[bankslot].data + _banks[bankslot].indexes[srcframe];
|
|
uint16 src_w = READ_LE_UINT16(p + 0);
|
|
uint16 src_h = READ_LE_UINT16(p + 2);
|
|
|
|
// unpack if destination frame is smaller than source one
|
|
if (_frames[dstframe].width < src_w || _frames[dstframe].height < src_h) {
|
|
bankUnpack(srcframe, dstframe, bankslot);
|
|
}
|
|
else {
|
|
// copy data 'over' destination frame (without changing frame header)
|
|
memcpy(_frames[dstframe].data, p, src_w * src_h);
|
|
}
|
|
|
|
debug(5, "Overpacked frame %d from bank slot %d to frame slot %d", srcframe, bankslot, dstframe);
|
|
}
|
|
|
|
|
|
void Graphics::bankErase(uint32 bankslot) {
|
|
|
|
delete[] _banks[bankslot].data;
|
|
_banks[bankslot].data = 0;
|
|
|
|
debug(5, "Erased bank in slot %d", bankslot);
|
|
}
|
|
|
|
|
|
void Graphics::bobSetupControl() {
|
|
|
|
bankLoad("control.BBK",17);
|
|
bankUnpack(1, 1, 17); // Mouse pointer
|
|
bankUnpack(3, 3, 17); // Up arrow dialogue
|
|
bankUnpack(4, 4, 17); // Down arrow dialogue
|
|
bankErase(17);
|
|
}
|
|
|
|
|
|
void Graphics::bobAnimString(uint32 bobnum, uint16* animBuf) {
|
|
|
|
BobSlot *pbs = &_bobs[bobnum];
|
|
pbs->active = true;
|
|
pbs->animating = true;
|
|
pbs->anim.string.buffer = animBuf;
|
|
pbs->anim.string.curPos = animBuf;
|
|
pbs->frameNum = animBuf[0];
|
|
pbs->anim.speed = animBuf[1] / 4;
|
|
}
|
|
|
|
|
|
void Graphics::bobAnimNormal(uint32 bobnum, uint16 firstFrame, uint16 lastFrame, uint16 speed, bool rebound, bool xflip) {
|
|
|
|
BobSlot *pbs = &_bobs[bobnum];
|
|
pbs->active = true;
|
|
pbs->animating = true;
|
|
pbs->frameNum = firstFrame;
|
|
pbs->anim.speed = speed;
|
|
pbs->anim.speedBak = speed;
|
|
pbs->anim.string.buffer = NULL;
|
|
pbs->anim.normal.firstFrame = firstFrame;
|
|
pbs->anim.normal.lastFrame = lastFrame;
|
|
pbs->anim.normal.rebound = rebound;
|
|
pbs->frameDir = 1;
|
|
pbs->xflip = xflip;
|
|
}
|
|
|
|
|
|
void Graphics::bobMove(uint32 bobnum, uint16 endx, uint16 endy, int16 speed) {
|
|
|
|
debug(5, "Graphics::bobMove(%d, %d, %d, %d)", bobnum, endx, endy, speed);
|
|
|
|
BobSlot *pbs = &_bobs[bobnum];
|
|
|
|
pbs->active = true;
|
|
pbs->moving = true;
|
|
|
|
pbs->endx = endx;
|
|
pbs->endy = endy;
|
|
|
|
pbs->speed = (speed < 1) ? 1 : speed;
|
|
|
|
int16 dx = endx - pbs->x;
|
|
if (dx < 0) {
|
|
pbs->dx = -dx;
|
|
pbs->xdir = -1;
|
|
}
|
|
else {
|
|
pbs->dx = dx;
|
|
pbs->xdir = 1;
|
|
}
|
|
int16 dy = endy - pbs->y;
|
|
if (dy < 0) {
|
|
pbs->dy = -dy;
|
|
pbs->ydir = -1;
|
|
}
|
|
else {
|
|
pbs->dy = dy;
|
|
pbs->ydir = 1;
|
|
}
|
|
|
|
if (pbs->dx > pbs->dy) {
|
|
pbs->total = pbs->dy / 2;
|
|
pbs->xmajor = true;
|
|
}
|
|
else {
|
|
pbs->total = pbs->dx / 2;
|
|
pbs->xmajor = false;
|
|
}
|
|
|
|
// move one step along line to avoid glitching
|
|
pbs->moveOneStep();
|
|
}
|
|
|
|
|
|
void BobSlot::moveOneStep() {
|
|
|
|
if(xmajor) {
|
|
if(x == endx) {
|
|
y = endy;
|
|
moving = false;
|
|
}
|
|
else {
|
|
x += xdir;
|
|
total += dy;
|
|
if(total > dx) {
|
|
y += ydir;
|
|
total -= dx;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if(y == endy) {
|
|
x = endx;
|
|
moving = false;
|
|
}
|
|
else {
|
|
y += ydir;
|
|
total += dx;
|
|
if(total > dy) {
|
|
x += xdir;
|
|
total -= dy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void BobSlot::animOneStep() {
|
|
|
|
if (anim.string.buffer != NULL) {
|
|
--anim.speed;
|
|
if(anim.speed == 0) {
|
|
anim.string.curPos += 2;
|
|
uint16 nextFrame = anim.string.curPos[0];
|
|
if (nextFrame == 0) {
|
|
anim.string.curPos = anim.string.buffer;
|
|
frameNum = anim.string.curPos[0];
|
|
}
|
|
else {
|
|
frameNum = nextFrame;
|
|
}
|
|
anim.speed = anim.string.curPos[1] / 4;
|
|
|
|
// FIXME: handle that when QueenSound class is ready
|
|
// play memory sfx and move on to next frame
|
|
if(frameNum > 500) {
|
|
frameNum -= 500;
|
|
// _sound->sfxplay(NULLstr);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// normal looping animation
|
|
--anim.speed;
|
|
if(anim.speed == 0) {
|
|
anim.speed = anim.speedBak;
|
|
|
|
uint16 nextFrame = frameNum + frameDir;
|
|
if (nextFrame > anim.normal.lastFrame || nextFrame < anim.normal.firstFrame) {
|
|
if (anim.normal.rebound) {
|
|
frameDir *= -1;
|
|
}
|
|
else {
|
|
frameNum = anim.normal.firstFrame - 1;
|
|
}
|
|
}
|
|
frameNum += frameDir;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::bobDraw(uint32 bobnum, uint16 x, uint16 y, uint16 scale, bool xflip, const Box& box) {
|
|
|
|
uint16 w, h;
|
|
|
|
debug(5, "Preparing to draw frame %d, scale = %d, coords = (%d,%d)", bobnum, scale, x, y);
|
|
|
|
BobFrame *pbf = &_frames[bobnum];
|
|
if (scale < 100) {
|
|
bobShrink(pbf, scale);
|
|
pbf = &_shrinkBuffer;
|
|
}
|
|
w = pbf->width;
|
|
h = pbf->height;
|
|
|
|
if(w != 0 && h != 0 && box.intersects(x, y, w, h)) {
|
|
|
|
uint8 *src = pbf->data;
|
|
uint16 x_skip = 0;
|
|
uint16 y_skip = 0;
|
|
uint16 w_new = w;
|
|
uint16 h_new = h;
|
|
|
|
// compute bounding box intersection with frame
|
|
if (x < box.x1) {
|
|
x_skip = box.x1 - x;
|
|
w_new -= x_skip;
|
|
x = box.x1;
|
|
}
|
|
|
|
if (y < box.y1) {
|
|
y_skip = box.y1 - y;
|
|
h_new -= y_skip;
|
|
y = box.y1;
|
|
}
|
|
|
|
if (x + w_new > box.x2 + 1) {
|
|
w_new = box.x2 - x + 1;
|
|
}
|
|
|
|
if (y + h_new > box.y2 + 1) {
|
|
h_new = box.y2 - y + 1;
|
|
}
|
|
|
|
src += w * y_skip;
|
|
if (!xflip) {
|
|
src += x_skip;
|
|
displayBlit(_screen, x, y, SCREEN_W, src, w_new, h_new, w, xflip, true);
|
|
}
|
|
else {
|
|
src += w - w_new - x_skip;
|
|
x += w_new - 1;
|
|
displayBlit(_screen, x, y, SCREEN_W, src, w_new, h_new, w, xflip, true);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void Graphics::bobDrawInventoryItem(uint32 bobnum, uint16 x, uint16 y) {
|
|
if (bobnum == 0) {
|
|
// clear panel area
|
|
memset(_panel + y * 32 + x, INK_BG_PANEL, 32 * 32);
|
|
}
|
|
else {
|
|
BobFrame *pbf = &_frames[bobnum];
|
|
displayBlit(_panel, x, y, 320, pbf->data, pbf->width, pbf->height, pbf->width, false, false);
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::bobPaste(uint32 bobnum, uint16 x, uint16 y) {
|
|
|
|
BobFrame *pbf = &_frames[bobnum];
|
|
displayBlit(_backdrop, x, y, 640, pbf->data, pbf->width, pbf->height, pbf->width, false, true);
|
|
frameErase(bobnum);
|
|
}
|
|
|
|
|
|
void Graphics::bobShrink(const BobFrame* pbf, uint16 percentage) {
|
|
|
|
// computing new size, rounding to upper value
|
|
uint16 new_w = (pbf->width * percentage + 50) / 100;
|
|
uint16 new_h = (pbf->height * percentage + 50) / 100;
|
|
|
|
debug(5, "Shrinking bob, buffer size = %d", new_w * new_h);
|
|
|
|
if (new_w != 0 && new_h != 0) {
|
|
|
|
_shrinkBuffer.width = new_w;
|
|
_shrinkBuffer.height = new_h;
|
|
|
|
uint32 shrinker = (100 << 0x10) / percentage;
|
|
uint16 x_scale = shrinker >> 0x10;
|
|
uint16 y_scale = x_scale * pbf->width;
|
|
shrinker &= 0xFFFF;
|
|
|
|
uint8* src = pbf->data;
|
|
uint8* dst = _shrinkBuffer.data;
|
|
|
|
uint32 y_count = 0;
|
|
while (new_h--) {
|
|
uint16 i;
|
|
uint32 x_count = 0;
|
|
uint8 *p = src;
|
|
for(i = 0; i < new_w; ++i) {
|
|
*dst++ = *p;
|
|
p += x_scale;
|
|
x_count += shrinker;
|
|
if (x_count > 0xFFFF) {
|
|
++p;
|
|
x_count &= 0xFFFF;
|
|
}
|
|
}
|
|
src += y_scale;
|
|
y_count += shrinker;
|
|
if (y_count > 0xFFFF) {
|
|
src += pbf->width;
|
|
y_count &= 0xFFFF;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::bobClear(uint32 bobnum) {
|
|
|
|
BobSlot *pbs = &_bobs[bobnum];
|
|
|
|
pbs->active = 0;
|
|
pbs->xflip = false;
|
|
pbs->anim.string.buffer = NULL;
|
|
pbs->moving = false;
|
|
pbs->scale = 100;
|
|
pbs->box.x1 = 0;
|
|
pbs->box.y1 = 0;
|
|
pbs->box.x2 = GAME_SCREEN_WIDTH - 1;
|
|
if (_fullscreen || bobnum == 16) { // FIXME: does bob number 16 really used ?
|
|
pbs->box.y2 = GAME_SCREEN_HEIGHT - 1;
|
|
}
|
|
else {
|
|
pbs->box.y2 = ROOM_ZONE_HEIGHT - 1;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::bobSortAll() {
|
|
|
|
_sortedBobsCount = 0;
|
|
|
|
// animate/move the bobs
|
|
for (int32 i = 0; i < ARRAYSIZE(_bobs); ++i) {
|
|
|
|
BobSlot *pbs = &_bobs[i];
|
|
if (pbs->active) {
|
|
_sortedBobs[_sortedBobsCount] = pbs;
|
|
++_sortedBobsCount;
|
|
|
|
if (pbs->animating) {
|
|
pbs->animOneStep();
|
|
}
|
|
if (pbs->moving) {
|
|
for (uint32 j = 0; pbs->moving && j < pbs->speed; ++j) {
|
|
pbs->moveOneStep();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// bubble sort the bobs
|
|
for (int32 index = 0; index < _sortedBobsCount - 1; ++index) {
|
|
int32 smallest = index;
|
|
for (int32 compare = index + 1; compare <= _sortedBobsCount - 1; ++compare) {
|
|
if (_sortedBobs[compare]->y < _sortedBobs[smallest]->y) {
|
|
smallest = compare;
|
|
}
|
|
}
|
|
if (index != smallest) {
|
|
SWAP(_sortedBobs[index], _sortedBobs[smallest]);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void Graphics::bobDrawAll() {
|
|
|
|
int i;
|
|
for (i = 0; i < _sortedBobsCount; ++i) {
|
|
BobSlot *pbs = _sortedBobs[i];
|
|
if (pbs->active) {
|
|
BobFrame *pbf = &_frames[ pbs->frameNum ];
|
|
uint16 xh, yh, x, y;
|
|
|
|
xh = pbf->xhotspot;
|
|
yh = pbf->yhotspot;
|
|
|
|
if (pbs->xflip) {
|
|
xh = pbf->width - xh;
|
|
}
|
|
|
|
// adjusts hot spots when object is scaled
|
|
if (pbs->scale != 100) {
|
|
xh = (xh * pbs->scale) / 100;
|
|
yh = (yh * pbs->scale) / 100;
|
|
}
|
|
|
|
// adjusts position to hot-spot and screen scroll
|
|
x = pbs->x - xh; // - _display->scrollx;
|
|
y = pbs->y - yh;
|
|
|
|
bobDraw(pbs->frameNum, x, y, pbs->scale, pbs->xflip, pbs->box);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::bobClearAll() {
|
|
|
|
for(int32 i = 0; i < ARRAYSIZE(_bobs); ++i) {
|
|
bobClear(i);
|
|
}
|
|
}
|
|
|
|
|
|
BobSlot *Graphics::bob(int index) {
|
|
|
|
if (index < MAX_BOBS_NUMBER)
|
|
return _bobs + index;
|
|
else {
|
|
error("QueenGraphics::bob called with index = %i but MAX_BOBS_NUMBER = %i",
|
|
index, MAX_BOBS_NUMBER);
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::textCurrentColor(uint8 color) {
|
|
_curTextColor = color;
|
|
}
|
|
|
|
|
|
void Graphics::textSet(uint16 x, uint16 y, const char *text, bool outlined) {
|
|
if (y < GAME_SCREEN_HEIGHT) {
|
|
if (x == 0) x = 1;
|
|
if (y == 0) y = 1;
|
|
TextSlot *pts = &_texts[y];
|
|
|
|
pts->x = x;
|
|
pts->color = _curTextColor;
|
|
pts->outlined = outlined;
|
|
pts->text = text;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::textDrawAll() {
|
|
int y;
|
|
for (y = GAME_SCREEN_HEIGHT - 1; y > 0; --y) {
|
|
const TextSlot *pts = &_texts[y];
|
|
if (!pts->text.isEmpty()) {
|
|
displayText(pts, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::textClear(uint16 y1, uint16 y2) {
|
|
|
|
while (y1 <= y2) {
|
|
_texts[y1].text.clear();
|
|
++y1;
|
|
}
|
|
}
|
|
|
|
|
|
uint16 Graphics::textWidth(const char* text) const {
|
|
|
|
uint16 len = 0;
|
|
while (*text) {
|
|
len += FONT_SIZES[ (int)*text ];
|
|
++text;
|
|
}
|
|
return len;
|
|
}
|
|
|
|
|
|
void Graphics::frameErase(uint32 fslot) {
|
|
|
|
BobFrame *pbf = &_frames[fslot];
|
|
pbf->width = 0;
|
|
pbf->height = 0;
|
|
delete[] pbf->data;
|
|
pbf->data = 0;
|
|
}
|
|
|
|
|
|
void Graphics::frameEraseAll(bool joe) {
|
|
|
|
int i = 0;
|
|
if (!joe) {
|
|
i = FRAMES_JOE + FRAMES_JOE_XTRA;
|
|
}
|
|
while (i < 256) {
|
|
frameErase(i);
|
|
++i;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::backdropLoad(const char* name, uint16 room) {
|
|
|
|
// init Dynalum
|
|
char roomPrefix[20];
|
|
strcpy(roomPrefix, name);
|
|
roomPrefix[ strlen(roomPrefix) - 4 ] = '\0';
|
|
dynalumInit(roomPrefix, room);
|
|
|
|
uint8 *pcxbuf = _resource->loadFile(name);
|
|
if (pcxbuf == NULL) {
|
|
error("Unable to load backdrop : '%s'", name);
|
|
}
|
|
|
|
uint32 size = _resource->fileSize(name);
|
|
setRoomPal(pcxbuf + size - 768, 0, (room <= 144) ? 144 : 256);
|
|
|
|
_backdropWidth = READ_LE_UINT16(pcxbuf + 12);
|
|
_backdropHeight = READ_LE_UINT16(pcxbuf + 14);
|
|
|
|
if (room >= 90) {
|
|
_cameraBob = 0;
|
|
}
|
|
|
|
readPCX(pcxbuf + 128, _backdrop, BACKDROP_W, _backdropWidth, _backdropHeight);
|
|
delete[] pcxbuf;
|
|
}
|
|
|
|
|
|
void Graphics::backdropDraw() {
|
|
|
|
int n = 3;
|
|
if (_fullscreen) {
|
|
n = 4;
|
|
}
|
|
uint8 *dst = _screen;
|
|
uint8 *src = _backdrop + _horizontalScroll;
|
|
while (n--) {
|
|
int i;
|
|
for (i = 0; i < 50; ++i) {
|
|
memcpy(dst, src, SCREEN_W);
|
|
dst += SCREEN_W;
|
|
src += BACKDROP_W;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::panelLoad() {
|
|
|
|
uint8 *pcxbuf = _resource->loadFile("panel.pcx");
|
|
if (pcxbuf == NULL) {
|
|
error("Unable to open panel file");
|
|
}
|
|
uint32 size = _resource->fileSize("panel.pcx");
|
|
setRoomPal(pcxbuf + size - 768, 144, 256);
|
|
readPCX(pcxbuf + 128, _panel + PANEL_W * 10, PANEL_W, PANEL_W, PANEL_H - 10);
|
|
delete[] pcxbuf;
|
|
}
|
|
|
|
|
|
void Graphics::panelDraw() {
|
|
memcpy(_screen + SCREEN_W * ROOM_ZONE_HEIGHT, _panel, PANEL_W * PANEL_H);
|
|
}
|
|
|
|
|
|
void Graphics::panelClear() {
|
|
memset(_screen + SCREEN_W * ROOM_ZONE_HEIGHT, 0, PANEL_W * PANEL_H);
|
|
}
|
|
|
|
|
|
void Graphics::readPCX(const uint8 *src, uint8 *dst, uint16 dstPitch, uint16 w, uint16 h) {
|
|
|
|
while (h--) {
|
|
uint8 *p = dst;
|
|
while (p < dst + w ) {
|
|
uint8 col = *src++;
|
|
if ((col & 0xC0) == 0xC0) {
|
|
uint8 len = col & 0x3F;
|
|
memset(p, *src++, len);
|
|
p += len;
|
|
}
|
|
else {
|
|
*p++ = col;
|
|
}
|
|
}
|
|
dst += dstPitch;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::boxDraw(const Box &b, uint8 color) {
|
|
|
|
int x, y;
|
|
|
|
for (y = b.y1; y <= b.y2; ++y) {
|
|
*(_backdrop + y * 640 + b.x1) = color;
|
|
*(_backdrop + y * 640 + b.x2) = color;
|
|
}
|
|
for (x = b.x1; x <= b.x2; ++x) {
|
|
*(_backdrop + b.y1 * 640 + x) = color;
|
|
*(_backdrop + b.y2 * 640 + x) = color;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::useJournal() { // GameSettings* pgs
|
|
|
|
int i;
|
|
|
|
bobClearAll();
|
|
backdropLoad("journal.pcx", 160);
|
|
// _display->fadeout(0,255);
|
|
|
|
// load and unpack journal frames
|
|
frameEraseAll(false);
|
|
bankLoad("journal.BBK", 8);
|
|
for(i = 1; i <= 20; ++i) {
|
|
bankUnpack(i, FRAMES_JOURNAL + i, 8);
|
|
// set hot spots to zero
|
|
_frames[FRAMES_JOURNAL + i].xhotspot = 0;
|
|
_frames[FRAMES_JOURNAL + i].yhotspot = 0;
|
|
}
|
|
// adjust info box hot spot to put it on top always
|
|
_frames[FRAMES_JOURNAL + 20].yhotspot = 200;
|
|
bankErase(8);
|
|
|
|
// TODO: setup zones
|
|
|
|
journalBobPreDraw();
|
|
// _display->fadein(0, 255);
|
|
}
|
|
|
|
|
|
void Graphics::journalBobSetup(uint32 bobnum, uint16 x, uint16 y, uint16 frame) {
|
|
|
|
BobSlot *pbs = &_bobs[bobnum];
|
|
pbs->active = true;
|
|
pbs->x = x;
|
|
pbs->y = y;
|
|
pbs->frameNum = FRAMES_JOURNAL + frame;
|
|
pbs->box.y2 = GAME_SCREEN_HEIGHT - 1;
|
|
}
|
|
|
|
|
|
void Graphics::journalBobPreDraw() { // GameSettings* pgs
|
|
|
|
journalBobSetup(1, 32, 8, 1); // Review entry
|
|
journalBobSetup(2, 32, 56, 2); // Make entry
|
|
journalBobSetup(3, 32, 104, 1); // Close book
|
|
journalBobSetup(4, 32, 152, 3); // Give up
|
|
// journalBobSetup(5, 136 + pgs->talkSpeed * 4 - 4, 164, 18); // Text speed
|
|
journalBobSetup(6, 221, 155, 16); // SFX on/off
|
|
// _bobs[6].active = pgs->sfxToggle;
|
|
// journalBobSetup(7, 136 + (pgs->volume * 130) / 100 - 4, 177, 19); // Music volume
|
|
journalBobSetup(10, 158, 155, 16); // Voice on/off
|
|
// _bobs[10].active = pgs->voiceToggle;
|
|
journalBobSetup(11, 125, 167, 16); // Text on/off
|
|
// _bobs[11].active = pgs->textToggle;
|
|
journalBobSetup(12, 125, 181, 16); // Music on/off
|
|
// _bobs[12].active = pgs->musicToggle;
|
|
}
|
|
|
|
|
|
void Graphics::update() {
|
|
// FIXME: incomplete !
|
|
bobSortAll();
|
|
if (_panelFlag) {
|
|
panelDraw();
|
|
}
|
|
else if (!_fullscreen) {
|
|
panelClear();
|
|
}
|
|
backdropDraw();
|
|
bobDrawAll();
|
|
textDrawAll();
|
|
if (_bobs[0].active) {
|
|
dynalumUpdate(_bobs[0].x, _bobs[0].y);
|
|
}
|
|
displayScreen();
|
|
g_system->delay_msecs(100); // TEMP: move to Logic::update()
|
|
}
|
|
|
|
|
|
void Graphics::displayText(const TextSlot *pts, uint16 y) {
|
|
|
|
uint16 x = pts->x;
|
|
const uint8 *str = (const uint8*)pts->text.c_str();
|
|
while (*str && x < GAME_SCREEN_WIDTH) {
|
|
const uint8 *pchr = FONT + (*str) * 8;
|
|
// if (_resource->_gameVersion->versionString[1] == 'F' && *str == 150) {
|
|
// chr = 251;
|
|
// }
|
|
if (pts->outlined) {
|
|
displayChar(x - 1, y - 1, INK_OUTLINED_TEXT, pchr);
|
|
displayChar(x , y - 1, INK_OUTLINED_TEXT, pchr);
|
|
displayChar(x + 1, y - 1, INK_OUTLINED_TEXT, pchr);
|
|
displayChar(x + 1, y , INK_OUTLINED_TEXT, pchr);
|
|
displayChar(x + 1, y + 1, INK_OUTLINED_TEXT, pchr);
|
|
displayChar(x , y + 1, INK_OUTLINED_TEXT, pchr);
|
|
displayChar(x - 1, y + 1, INK_OUTLINED_TEXT, pchr);
|
|
displayChar(x - 1, y , INK_OUTLINED_TEXT, pchr);
|
|
}
|
|
displayChar(x, y, pts->color, pchr);
|
|
|
|
x += FONT_SIZES[ *str ];
|
|
++str;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::displayChar(uint16 x, uint16 y, uint8 color, const uint8 *chr) {
|
|
|
|
int i, j;
|
|
uint8 *dst = _screen + y * SCREEN_W + x;
|
|
for (j = 0; j < 8; ++j) {
|
|
uint8* p = dst;
|
|
uint8 c = *chr++;
|
|
if (c != 0) {
|
|
for (i = 0; i < 8; ++i) {
|
|
if(c & 0x80) {
|
|
*p = color;
|
|
}
|
|
++p;
|
|
c <<= 1;
|
|
}
|
|
}
|
|
dst += SCREEN_W;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::displayBlit(uint8 *dst_buf, uint16 dst_x, uint16 dst_y, uint16 dst_pitch, const uint8 *src_buf, uint16 src_w, uint16 src_h, uint16 src_pitch, bool xflip, bool masked) {
|
|
|
|
dst_buf += dst_y * dst_pitch + dst_x;
|
|
if (!masked) { // Unmasked always unflipped
|
|
while (src_h--) {
|
|
memcpy(dst_buf, src_buf, src_w);
|
|
src_buf += src_pitch;
|
|
dst_buf += dst_pitch;
|
|
}
|
|
}
|
|
else if (!xflip) { // Masked bitmap unflipped
|
|
while (src_h--) {
|
|
int i;
|
|
for(i = 0; i < src_w; ++i) {
|
|
uint8 b = *(src_buf + i);
|
|
if(b != 0) {
|
|
*(dst_buf + i) = b;
|
|
}
|
|
}
|
|
src_buf += src_pitch;
|
|
dst_buf += dst_pitch;
|
|
}
|
|
}
|
|
else { // Masked bitmap flipped
|
|
while (src_h--) {
|
|
int i;
|
|
for(i = 0; i < src_w; ++i) {
|
|
uint8 b = *(src_buf + i);
|
|
if(b != 0) {
|
|
*(dst_buf - i) = b;
|
|
}
|
|
}
|
|
src_buf += src_pitch;
|
|
dst_buf += dst_pitch;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::displayScreen() {
|
|
// FIXME: temporary code ; cleanup/move to Display class.
|
|
g_system->set_palette(_paletteScreen, 0, 256);
|
|
g_system->copy_rect(_screen, SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
|
|
g_system->update_screen();
|
|
}
|
|
|
|
|
|
void Graphics::setScreenMode(int comPanel, bool inCutaway) {
|
|
if (comPanel == 2 && inCutaway) {
|
|
if (_backdropHeight == GAME_SCREEN_HEIGHT) {
|
|
_fullscreen = true;
|
|
_panelFlag = false;
|
|
}
|
|
else {
|
|
_fullscreen = false;
|
|
_panelFlag = true;
|
|
}
|
|
}
|
|
else {
|
|
_fullscreen = 0;
|
|
_panelFlag = (comPanel == 1);
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::setRoomPal(const uint8 *pal, int start, int end) {
|
|
int i;
|
|
pal += start * 3;
|
|
for (i = start; i < end; ++i, pal += 3) {
|
|
_paletteScreen[i << 2 | 0] = _paletteRoom[i * 3 + 0] = *(pal + 0);
|
|
_paletteScreen[i << 2 | 1] = _paletteRoom[i * 3 + 1] = *(pal + 1);
|
|
_paletteScreen[i << 2 | 2] = _paletteRoom[i * 3 + 2] = *(pal + 2);
|
|
_paletteScreen[i << 2 | 3] = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::dynalumInit(const char* roomPrefix, uint16 room) {
|
|
// io.c l.2063-2089
|
|
memset(_dynalum.msk, 0, sizeof(_dynalum.msk));
|
|
memset(_dynalum.lum, 0, sizeof(_dynalum.lum));
|
|
if (room < 90 || ((room > 94) && (room < 114))) {
|
|
char filename[80];
|
|
sprintf(filename, "%s.msk", roomPrefix);
|
|
_resource->loadFile(filename, 0, (uint8*)_dynalum.msk);
|
|
sprintf(filename, "%s.lum", roomPrefix);
|
|
_resource->loadFile(filename, 0, (uint8*)_dynalum.lum);
|
|
}
|
|
}
|
|
|
|
|
|
void Graphics::dynalumUpdate(uint16 x, uint16 y) {
|
|
|
|
if (x >= _backdropWidth) {
|
|
x = _backdropWidth;
|
|
}
|
|
if (y >= ROOM_ZONE_HEIGHT - 1) {
|
|
y = ROOM_ZONE_HEIGHT - 1;
|
|
}
|
|
uint16 colMask = _dynalum.msk[(y / 4) * 160 + (x / 4)];
|
|
debug(9, "Graphics::dynalumUpdate(%d, %d) - colMask = %d", x, y, colMask);
|
|
if (colMask != _dynalum.oldColMask) {
|
|
uint8 i;
|
|
for (i = 0; i < 16; ++i) {
|
|
uint8 j;
|
|
for (j = 0; j < 3; ++j) {
|
|
int16 c = (int16)(_paletteRoom[(144 + i) * 3 + j] + _dynalum.lum[colMask * 3 + j] * 4);
|
|
if (c < 0) {
|
|
c = 0;
|
|
}
|
|
else if (c > 255) {
|
|
c = 255;
|
|
}
|
|
_paletteScreen[(144 + i) * 4 + j] = (uint8)c;
|
|
}
|
|
}
|
|
_dynalum.oldColMask = colMask;
|
|
// TODO: handle dirty colors (lopal, hipal)
|
|
}
|
|
}
|
|
|
|
|
|
} // End of namespace Queen
|
|
|