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,272 @@
/* 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/ultima0/gfx/dungeon.h"
#include "ultima/ultima0/gfx/monster.h"
#include "ultima/ultima0/ultima0.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
int Dungeon::_xLeft;
int Dungeon::_xRight;
int Dungeon::_yBottom;
int Dungeon::_yDiffLeft;
int Dungeon::_yDiffRight;
#define HWColour(IDX) color = IDX
#define X(n) (x1 + w * (n)/10)
#define Y(n) (y1 + h * (n)/10)
#define HWLine(X1, Y1, X2, Y2) s->drawLine(X1, Y1, X2, Y2, color)
#define BOX(x1,y1,x2,y2) { HWLine(X(x1),Y(y1),X(x2),Y(y1));HWLine(X(x1),Y(y1),X(x1),Y(y2));HWLine(X(x2),Y(y2),X(x2),Y(y1));HWLine(X(x2),Y(y2),X(x1),Y(y2)); }
void Dungeon::draw(Graphics::ManagedSurface *s) {
const auto &player = g_engine->_player;
const auto &dungeon = g_engine->_dungeon;
s->clear();
double level = 0;
Common::Rect rIn, rOut;
Common::Point dir, pos, next;
int monster, front, left, right;
calcRect(s, &rOut, 0);
pos = player._dungeonPos; // Get position
// Iterate through drawing successively distinct tiles in the facing direction
do {
level++; // Next level
calcRect(s, &rIn, level);
next.x = pos.x + player._dungeonDir.x; // Next position
next.y = pos.y + player._dungeonDir.y;
dir = player._dungeonDir; rotateLeft(&dir); // To the left
left = dungeon._map[pos.x + dir.x][pos.y + dir.y];
rotateLeft(&dir); rotateLeft(&dir); // To the right
right = dungeon._map[pos.x + dir.x][pos.y + dir.y];
front = dungeon._map[next.x][next.y]; // What's in front ?
// Check for monster present
monster = dungeon.findMonster(pos);
if (monster >= 0)
monster = dungeon._monsters[monster]._type;
// Draw the dungeon
drawDungeon(s, &rOut, &rIn, left, front, right,
dungeon._map[pos.x][pos.y], monster);
pos = next; // Next position down
rOut = rIn; // Last in is new out
} while (level < MAX_VIEW_DEPTH && ISDRAWOPEN(front));
}
void Dungeon::calcRect(Graphics::ManagedSurface *s, Common::Rect *r, double level) {
const int centerX = s->w / 2, centerY = s->h / 2;
int xWidth = s->w / (level + 1);
int yWidth = s->h / (level + 1);
// Set bounding box
r->left = centerX - xWidth / 2;
r->right = centerX + xWidth / 2;
r->top = centerY - yWidth / 2;
r->bottom = centerY + yWidth / 2;
}
void Dungeon::rotateLeft(Common::Point *dir) {
int t;
if (dir->y == 0) dir->x = -dir->x;
t = dir->x;
dir->x = dir->y;
dir->y = t;
}
void Dungeon::drawDungeon(Graphics::ManagedSurface *s, Common::Rect *rOut,
Common::Rect *rIn, int left, int centre, int right, int room, int monster) {
int x1, y1, x, y, y2;
Common::Rect r;
double Scale;
int color;
HWColour(COL_WALL); // Start on the walls
// Do we draw the left edge
if (ISDRAWOPEN(left)) {
HWLine(rOut->left, rIn->top, rIn->left, rIn->top);
HWLine(rOut->left, rIn->bottom, rIn->left, rIn->bottom);
HWLine(rOut->left, rOut->top, rOut->left, rOut->bottom);
} else {
// If closed, draw left diags
HWLine(rOut->left, rOut->top, rIn->left, rIn->top);
HWLine(rOut->left, rOut->bottom, rIn->left, rIn->bottom);
}
// Do we draw the right edge
if (ISDRAWOPEN(right)) {
HWLine(rOut->right, rIn->top, rIn->right, rIn->top);
HWLine(rOut->right, rIn->bottom, rIn->right, rIn->bottom);
HWLine(rOut->right, rOut->top, rOut->right, rOut->bottom);
} else {
// If closed draw right diags
HWLine(rOut->right, rOut->top, rIn->right, rIn->top);
HWLine(rOut->right, rOut->bottom, rIn->right, rIn->bottom);
}
// Back wall ?
if (!ISDRAWOPEN(centre)) {
HWLine(rIn->left, rIn->top, rIn->right, rIn->top);
HWLine(rIn->left, rIn->bottom, rIn->right, rIn->bottom);
if (!ISDRAWOPEN(left)) // Corner if left,right closed
HWLine(rIn->left, rIn->top, rIn->left, rIn->bottom);
if (!ISDRAWOPEN(right))
HWLine(rIn->right, rIn->top, rIn->right, rIn->bottom);
}
// Set up for left side
setRange(rOut->left, rIn->left,
rOut->bottom,
rOut->bottom - rOut->top,
rIn->bottom - rIn->top);
drawWall(s, left);
// Set up for right side
setRange(rIn->right, rOut->right,
rIn->bottom,
rIn->bottom - rIn->top,
rOut->bottom - rOut->top);
drawWall(s, right);
// Set up for centre
setRange(rIn->left, rIn->right,
rIn->bottom,
rIn->bottom - rIn->top,
rIn->bottom - rIn->top);
drawWall(s, centre);
if (room == DT_LADDERUP) {
r = Common::Rect(rOut->left, rOut->top, rOut->right, rIn->top);
_DRAWPit(s, &r, 1);
}
if (room == DT_LADDERDN || room == DT_PIT) {
r = Common::Rect(rOut->left, rIn->bottom, rOut->right, rOut->bottom);
_DRAWPit(s, &r, -1);
}
// Get the object area
r = Common::Rect(
(rIn->left + rOut->left) / 2,
(rIn->top + rOut->top) / 2,
(rIn->right + rOut->right) / 2,
(rIn->bottom + rOut->bottom) / 2);
// Ladder here ?
if (room == DT_LADDERUP || room == DT_LADDERDN) {
HWColour(COL_LADDER);
y1 = r.top; y2 = r.bottom;
x = (r.right - r.left) * 3 / 10;
// Vertical lines
HWLine(r.left + x, y1, r.left + x, y2);
HWLine(r.right - x, y1, r.right - x, y2);
x1 = (y2 - y1) / 5;
// Horizontal ladder rungs
for (y = y1 + x1 / 2; y < y2; y += x1)
HWLine(r.left + x, y, r.right - x, y);
}
// Scale for monsters/gold. Scale factor has been empirically chosen
Scale = 0.35 / (r.right - r.left) * s->w;
// Monster here ?
if (monster > 0) {
HWColour(COL_MONSTER);
Monster::draw(s, (r.left + r.right) / 2, r.bottom, monster, Scale);
}
// Draw the gold (as a mimic)
if (room == DT_GOLD) {
HWColour(COL_MONSTER);
Monster::draw(s, (r.left + r.right) / 2, r.bottom, MN_MIMIC, Scale);
}
}
void Dungeon::setRange(int x1, int x2, int y, int yd1, int yd2) {
_xLeft = x1; _xRight = x2; // Set x ranges
_yBottom = y; // Set lower left y value
_yDiffLeft = yd1; _yDiffRight = yd2; // Set difference for either end
}
void Dungeon::drawWall(Graphics::ManagedSurface *s, int n) {
int x1, y1, x2, y2;
int color = 0;
if (n == DT_DOOR) {
HWColour(COL_DOOR);
x1 = 35; y1 = 0; x2 = 35; y2 = 60;
drawConvert(&x1, &y1);
drawConvert(&x2, &y2);
HWLine(x1, y1, x2, y2);
x1 = 65; y1 = 60; drawConvert(&x1, &y1);
HWLine(x1, y1, x2, y2);
x2 = 65; y2 = 0; drawConvert(&x2, &y2);
HWLine(x1, y1, x2, y2);
}
}
void Dungeon::drawConvert(int *px, int *py) {
long x, y, yd; // Longs for overflow in 16 bit
x = (_xRight - _xLeft); // Calculate width
x = x * (*px) / 100 + _xLeft; // Work out horiz value
yd = (_yDiffRight - _yDiffLeft); // Work out height of vert for x
yd = yd * (*px) / 100;
y = _yBottom + // Half of the distance
yd / 2 - // + Scaled total size
(yd + _yDiffLeft) * (*py) / 100;
*px = (int)x; // Write back, casting to int
*py = (int)y;
}
void Dungeon::_DRAWPit(Graphics::ManagedSurface *s, Common::Rect *r, int Dir) {
int x1, x2, y1;
int color;
HWColour(COL_HOLE);
y1 = (r->top - r->bottom) / 5;
r->bottom += y1; r->top -= y1;
x1 = (r->right - r->left) / 5;
r->left += x1; r->right -= x1;
x2 = 0; x1 = x1 / 2;
if (Dir > 0)
{
y1 = x1; x1 = x2; x2 = y1;
}
HWLine(r->left + x1, r->top, r->right - x1, r->top);
HWLine(r->left + x1, r->top, r->left + x2, r->bottom);
HWLine(r->left + x2, r->bottom, r->right - x2, r->bottom);
HWLine(r->right - x1, r->top, r->right - x2, r->bottom);
}
} // namespace Views
} // namespace Ultima0
} // namespace Ultima

View File

@@ -0,0 +1,81 @@
/* 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 ULTIMA0_GFX_MAP_H
#define ULTIMA0_GFX_MAP_H
#include "graphics/managed_surface.h"
#include "ultima/ultima0/data/data.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
class Dungeon {
private:
// Slanted drawing constants
static int _xLeft, _xRight, _yBottom, _yDiffLeft, _yDiffRight;
/**
* Calculate display rectangle
*/
static void calcRect(Graphics::ManagedSurface *s, Common::Rect *r, double _level);
/**
* Rotate a direction left
*/
static void rotateLeft(Common::Point *Dir);
/**
* Draw part of dungeon
*/
static void drawDungeon(Graphics::ManagedSurface *s, Common::Rect *rOut,
Common::Rect *rIn, int Left, int Centre, int Right, int Room, int Monster);
/**
* Set the oblique drawing routine
*/
static void setRange(int x1, int x2, int y, int yd1, int yd2);
/**
* Draw wall object using current setting
*/
static void drawWall(Graphics::ManagedSurface *s, int n);
/**
* Convert coordinates from oblique to logical
*/
static void drawConvert(int *px, int *py);
/**
* Draw the pits/ladder hole
*/
static void _DRAWPit(Graphics::ManagedSurface *s, Common::Rect *r, int Dir);
public:
static void draw(Graphics::ManagedSurface *s);
};
} // namespace Gfx
} // namespace Ultima0
} // namespace Ultima
#endif

View File

@@ -0,0 +1,224 @@
/* 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/ultima0/gfx/font.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
static const byte FONT1[2048] = {
124,130,186,162,186,130,124,0,126,129,165,129,165,153,129,126,
126,129,165,129,153,165,129,126,108,246,246,254,124,56,16,0,
16,56,124,254,124,56,16,0,16,56,84,254,84,16,56,0,
56,124,254,254,108,16,56,0,16,24,20,20,48,112,96,0,
254,254,254,238,254,254,254,0,236,138,138,170,170,170,236,0,
142,136,136,140,136,136,232,0,174,170,170,234,170,170,174,0,
238,136,136,204,136,136,136,0,238,138,138,142,140,138,234,0,
62,34,62,34,102,238,204,0,16,84,40,198,40,84,16,0,
240,248,252,254,252,248,240,0,30,62,126,254,126,62,30,0,
16,56,124,16,124,56,16,0,238,238,238,238,238,0,238,0,
254,68,68,68,68,68,68,0,126,128,188,198,122,2,252,0,
0,0,0,0,255,255,0,0,16,56,124,16,124,56,16,254,
16,56,124,254,56,56,56,0,56,56,56,254,124,56,16,0,
16,24,252,254,252,24,16,0,16,48,126,254,126,48,16,0,
144,72,36,18,36,72,144,0,18,36,72,144,72,36,18,0,
16,40,68,146,40,68,130,0,130,68,40,146,68,40,16,0,
0,0,0,0,0,0,0,0,16,16,16,16,16,0,16,0,
40,40,40,0,0,0,0,0,68,254,68,68,68,254,68,0,
16,126,144,124,18,252,16,0,66,164,72,16,36,74,132,0,
56,68,56,112,138,132,122,0,16,16,32,0,0,0,0,0,
8,16,16,16,16,16,8,0,32,16,16,16,16,16,32,0,
16,84,56,254,56,84,16,0,16,16,16,254,16,16,16,0,
0,0,0,0,0,16,16,32,0,0,0,254,0,0,0,0,
0,0,0,0,0,0,16,0,2,4,8,16,32,64,128,0,
124,130,130,130,130,130,124,0,240,16,16,16,16,16,254,0,
252,2,2,124,128,128,254,0,252,2,2,28,2,2,252,0,
130,130,130,126,2,2,2,0,254,128,252,2,2,2,252,0,
126,128,252,130,130,130,124,0,252,2,2,2,2,2,2,0,
124,130,130,124,130,130,124,0,126,130,130,126,2,2,252,0,
0,0,0,16,0,0,16,0,0,0,0,16,0,0,16,32,
8,16,32,64,32,16,8,0,0,0,0,254,0,254,0,0,
64,32,16,8,16,32,64,0,56,68,4,8,16,0,16,0,
60,66,154,170,156,64,62,0,124,130,130,254,130,130,130,0,
252,130,130,252,130,130,252,0,124,130,128,128,128,130,124,0,
252,130,130,130,130,130,252,0,254,128,128,240,128,128,254,0,
254,128,128,240,128,128,128,0,124,130,128,142,130,130,124,0,
130,130,130,254,130,130,130,0,254,16,16,16,16,16,254,0,
62,2,2,2,130,130,124,0,130,132,136,240,136,132,130,0,
128,128,128,128,128,128,254,0,252,146,146,146,146,146,146,0,
130,194,162,146,138,134,130,0,124,130,130,130,130,130,124,0,
252,130,130,252,128,128,128,0,124,130,130,130,138,134,126,0,
252,130,130,252,130,130,130,0,126,128,128,124,2,2,252,0,
254,16,16,16,16,16,16,0,130,130,130,130,130,130,124,0,
130,130,68,68,40,40,16,0,130,130,130,146,146,146,108,0,
130,68,40,16,40,68,130,0,130,130,130,126,2,2,252,0,
254,4,8,16,32,64,254,0,56,32,32,32,32,32,56,0,
128,64,32,16,8,4,2,0,56,8,8,8,8,8,56,0,
16,40,68,130,0,0,0,0,0,0,0,0,0,0,0,255,
32,32,16,0,0,0,0,0,0,0,56,68,124,68,68,0,
0,0,120,68,120,68,120,0,0,0,60,64,64,64,60,0,
0,0,120,68,68,68,120,0,0,0,124,64,112,64,124,0,
0,0,124,64,112,64,64,0,0,0,60,64,76,68,60,0,
0,0,68,68,124,68,68,0,0,0,124,16,16,16,124,0,
0,0,28,4,4,68,56,0,0,0,68,72,112,72,68,0,
0,0,64,64,64,64,124,0,0,0,120,84,84,84,84,0,
0,0,120,68,68,68,68,0,0,0,56,68,68,68,56,0,
0,0,120,68,120,64,64,0,0,0,56,68,68,76,54,0,
0,0,120,68,120,68,68,0,0,0,60,64,56,4,120,0,
0,0,124,16,16,16,16,0,0,0,68,68,68,68,56,0,
0,0,68,68,40,40,16,0,0,0,68,68,84,108,68,0,
0,0,68,40,16,40,68,0,0,0,68,68,60,4,120,0,
0,0,124,8,16,32,124,0,8,16,16,32,16,16,8,0,
16,16,16,0,16,16,16,0,32,16,16,8,16,16,32,0,
80,40,0,0,0,0,0,0,0,16,40,68,130,130,254,0,
254,254,254,254,254,254,254,0,0,0,0,0,0,254,254,0,
0,0,124,124,124,124,124,0,0,0,0,0,0,0,124,0,
128,128,128,128,128,128,128,0,0,64,64,64,64,64,64,0,
16,24,28,30,28,24,16,0,16,48,112,240,112,48,16,0,
62,30,30,62,114,224,64,0,4,14,156,248,240,240,248,0,
64,224,114,62,30,30,62,0,248,240,240,248,156,14,4,0,
56,68,130,130,130,68,56,0,56,124,254,254,254,124,56,0,
0,124,68,68,68,124,0,0,0,124,124,124,124,124,0,0,
0,60,110,126,112,126,60,0,0,60,118,126,14,126,60,0,
0,60,126,106,126,126,106,0,0,60,126,86,126,126,86,0,
0,0,0,24,24,0,0,0,0,0,24,60,60,24,0,0,
0,12,52,36,36,108,72,0,0,0,0,0,0,0,0,0,
60,126,198,231,255,224,126,60,60,126,227,231,255,7,126,60,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,52,118,118,94,126,60,0,0,60,110,126,112,126,60,0,
0,60,126,122,110,110,44,0,0,60,126,14,126,118,60,0,
0,0,0,0,0,0,0,0,126,126,126,126,60,0,0,0,
0,15,31,31,31,31,15,0,126,127,127,127,127,127,63,0,
0,0,0,60,126,126,126,126,126,126,126,126,126,126,126,126,
0,63,127,127,127,127,127,126,126,127,127,127,127,127,127,126,
0,240,248,248,248,248,240,0,126,254,254,254,254,254,252,0,
0,255,255,255,255,255,255,0,126,255,255,255,255,255,255,0,
0,252,254,254,254,254,254,126,126,254,254,254,254,254,254,126,
0,255,255,255,255,255,255,126,126,255,255,255,255,255,255,126,
0,0,63,63,48,55,52,52,0,0,255,255,0,255,0,0,
0,0,248,248,24,216,88,88,88,88,88,88,88,88,88,88,
88,216,24,248,248,0,0,0,0,255,0,255,255,0,0,0,
52,55,48,63,63,0,0,0,52,52,52,52,52,52,52,52,
0,0,0,31,24,24,24,24,0,0,0,255,0,0,0,0,
0,0,0,240,48,48,48,48,48,48,48,48,48,48,48,48,
48,48,48,240,0,0,0,0,0,0,0,255,0,0,0,0,
24,24,24,31,0,0,0,0,24,24,24,24,24,24,24,24,
136,34,136,34,136,34,136,34,85,170,85,170,85,170,85,170,
68,170,68,170,68,170,68,170,51,102,204,153,51,102,204,153,
204,102,51,153,204,102,51,153,199,143,31,62,124,248,241,227,
227,241,248,124,62,31,143,199,174,128,186,2,234,8,171,32,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
void Font::writeChar(Graphics::ManagedSurface *dst, uint32 chr,
const Common::Point &textPos, byte textColor) {
if (chr == ' ')
return; // Don't do anything for spaces
const byte *GfxData = FONT1 + chr * 8;
Graphics::Surface charArea = dst->getSubArea(Common::Rect(textPos.x, textPos.y,
textPos.x + GLYPH_WIDTH, textPos.y + GLYPH_HEIGHT));
const int w = 1;
const int h = 1;
// Work through the 64 pixel array
for (int x = 0; x < 8; ++x) {
for (int y = 0; y < 8; ++y) {
// Check for whether character has pixel in this position
if (_FONTPixelSet(GfxData, x, y)) {
Common::Rect rc2(x * 2, y * 2, x * 2 + 2, y * 2 + 2);
charArea.fillRect(rc2, textColor);
// Neaten the diagonals
if (_FONTPixelSet(GfxData, x, y + 1) == 0 &&
_FONTPixelSet(GfxData, x - 1, y) == 0 &&
_FONTPixelSet(GfxData, x - 1, y + 1) != 0)
_FONTAngleDraw(&charArea, &rc2, -w, h, textColor);
if (_FONTPixelSet(GfxData, x, y + 1) == 0 &&
_FONTPixelSet(GfxData, x + 1, y) == 0 &&
_FONTPixelSet(GfxData, x + 1, y + 1) != 0)
_FONTAngleDraw(&charArea, &rc2, w, h, textColor);
}
}
}
}
bool Font::_FONTPixelSet(const byte * Data, int x, int y) {
if (x < 0 || y < 0 || x > 7 || y > 7)
return false;
return (Data[y] & (0x80 >> x)) ? 1 : 0;
}
void Font::_FONTAngleDraw(Graphics::Surface *s, Common::Rect *rc, int w, int h, byte colour) {
int i, m;
Common::Rect rc3;
m = ABS(w);
if (ABS(h) > m)
m = ABS(h);
for (i = 0; i < m; i++) {
rc3.left = rc->left + w * i / m;
rc3.top = rc->top + h * i / m;
rc3.setWidth(rc->width());
rc3.setHeight(rc->height());
s->fillRect(rc3, colour);
}
}
} // namespace Gfx
} // namespace Ultima0
} // namespace Ultima

View File

@@ -0,0 +1,71 @@
/* 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 ULTIMA0_GFX_FONT_H
#define ULTIMA0_GFX_FONT_H
#include "common/rect.h"
#include "graphics/managed_surface.h"
#include "ultima/ultima0/data/defines.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
constexpr int GLYPH_HEIGHT = 16;
constexpr int GLYPH_WIDTH = 16;
constexpr int TEXT_WIDTH = DEFAULT_SCX / GLYPH_WIDTH;
constexpr int TEXT_HEIGHT = DEFAULT_SCY / GLYPH_HEIGHT;
class TextRect : public ::Common::Rect {
public:
TextRect() : ::Common::Rect() {}
TextRect(int left_, int top_, int right_, int bottom_) :
::Common::Rect(left_ * GLYPH_WIDTH, top_ * GLYPH_HEIGHT,
(right_ + 1) * GLYPH_WIDTH, (bottom_ + 1) * GLYPH_HEIGHT) {}
};
class Font {
private:
/**
* Returns true if a pixel is set in the source font data
*/
static bool _FONTPixelSet(const byte *Data, int x, int y);
/**
* Draw an angled line - this stops the squared corners on diagonals showing
*/
static void _FONTAngleDraw(Graphics::Surface *s, Common::Rect *rc,
int w, int h, byte colour);
public:
/**
* Draws a character onto the passed surface
*/
static void writeChar(Graphics::ManagedSurface *dst, uint32 chr,
const Common::Point &textPos, byte textColor);
};
} // namespace Gfx
} // namespace Ultima0
} // namespace Ultima
#endif

View File

@@ -0,0 +1,109 @@
/* 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/ultima0/gfx/gfx_surface.h"
#include "ultima/ultima0/gfx/font.h"
#include "ultima/ultima0/ultima0.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
void GfxSurface::writeString(const Common::Point &pt, const Common::String &str,
Graphics::TextAlign align) {
_textPos = pt;
writeString(str, align);
}
void GfxSurface::writeString(const Common::String &str, Graphics::TextAlign align) {
size_t strSize = 0;
for (const char *p = str.c_str(); *p; ++p)
strSize += Common::isPrint(*p) ? 1 : 0;
switch (align) {
case Graphics::kTextAlignCenter:
_textPos.x -= strSize / 2;
break;
case Graphics::kTextAlignRight:
_textPos.x -= strSize;
break;
case Graphics::kTextAlignLeft:
default:
break;
}
for (const char *p = str.c_str(); *p; ++p) {
if (*p == '\n') {
assert(align == Graphics::kTextAlignLeft);
newLine();
} else if (*p < 32) {
setColor((byte)*p);
} else {
writeChar(*p);
}
}
}
void GfxSurface::writeChar(uint32 chr) {
if (chr >= ' ') {
Font::writeChar(this, chr, Common::Point(_textPos.x * GLYPH_WIDTH,
_textPos.y * GLYPH_HEIGHT), _textColor);
++_textPos.x;
}
if (_textPos.x >= TEXT_WIDTH || chr == '\n') {
newLine();
}
}
void GfxSurface::newLine() {
_textPos.x = 0;
_textPos.y++;
if (_textPos.y >= TEXT_HEIGHT) {
_textPos.y = TEXT_HEIGHT - 1;
// Scroll the screen contents up
blitFrom(*this, Common::Rect(0, GLYPH_HEIGHT, DEFAULT_SCX, DEFAULT_SCY),
Common::Point(0, 0));
fillRect(Common::Rect(0, DEFAULT_SCX - GLYPH_HEIGHT, DEFAULT_SCX, DEFAULT_SCY), 0);
}
}
void GfxSurface::setTextPos(const Common::Point &pt) {
_textPos = pt;
}
byte GfxSurface::setColor(byte color) {
byte oldColor = _textColor;
_textColor = color;
return oldColor;
}
byte GfxSurface::setColor(byte r, byte g, byte b) {
byte oldColor = _textColor;
_textColor = g_engine->_palette.findBestColor(r, g, b);
return oldColor;
}
} // namespace Gfx
} // namespace Ultima0
} // namespace Ultima

View File

@@ -0,0 +1,61 @@
/* 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 ULTIMA0_GFX_SURFACE_H
#define ULTIMA0_GFX_SURFACE_H
#include "graphics/font.h"
#include "graphics/managed_surface.h"
#include "ultima/ultima0/gfx/font.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
class GfxSurface : public Graphics::ManagedSurface {
private:
Common::Point _textPos;
byte _textColor = C_TEXT_DEFAULT;
void newLine();
public:
GfxSurface() : Graphics::ManagedSurface() {}
GfxSurface(Graphics::ManagedSurface &surf, const Common::Rect &bounds) : Graphics::ManagedSurface(surf, bounds) {}
/**
* Write some text to the surface
*/
void writeString(const Common::Point &pt, const Common::String &str,
Graphics::TextAlign align = Graphics::kTextAlignLeft);
void writeString(const Common::String &str, Graphics::TextAlign align = Graphics::kTextAlignLeft);
void writeChar(uint32 chr);
void setTextPos(const Common::Point &pt);
byte setColor(byte color);
byte setColor(byte r, byte g, byte b);
};
} // namespace Gfx
} // namespace Ultima0
} // namespace Ultima
#endif

View File

@@ -0,0 +1,142 @@
/* 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/ultima0/gfx/map.h"
#include "ultima/ultima0/ultima0.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
void Map::draw(Graphics::ManagedSurface *s, bool showAsMap) {
const auto &player = g_engine->_player;
const auto &map = g_engine->_worldMap;
s->clear();
int x, y, x1, y1, w, h, grid;
Common::Rect r;
grid = showAsMap ? WORLD_MAP_SIZE : (g_engine->isEnhanced() ? 7 : 3);
w = s->w / grid; h = s->h / grid; // Get grid sizes
for (x = 0; x < grid; x++) {
for (y = 0; y < grid; y++) {
r = Common::Rect(x * w, y * h, x * w + w - 1, y * h + h - 1);
if (showAsMap) {
// If map, not centered around us
x1 = x, y1 = y;
} else {
// Which cell?
x1 = player._worldPos.x - grid / 2 + x;
y1 = player._worldPos.y - grid / 2 + y;
}
drawTile(s, r, map.read(x1, y1));
// Draw us if we're there
if (x1 == player._worldPos.x && y1 == player._worldPos.y)
drawTile(s, r, WT_PLAYER);
}
}
}
#define HWColour(IDX) color = IDX
#define X(n) (x1 + w * (n)/10)
#define Y(n) (y1 + h * (n)/10)
#define HWLine(X1, Y1, X2, Y2) s->drawLine(X1, Y1, X2, Y2, color)
#define BOX(x1,y1,x2,y2) { HWLine(X(x1),Y(y1),X(x2),Y(y1));HWLine(X(x1),Y(y1),X(x1),Y(y2));HWLine(X(x2),Y(y2),X(x2),Y(y1));HWLine(X(x2),Y(y2),X(x1),Y(y2)); }
void Map::drawTile(Graphics::ManagedSurface *s, const Common::Rect &r, int obj) {
int x1 = r.left;
int y1 = r.top;
int w = r.width();
int h = r.height();
byte color = 0;
// Decide on the object
switch (obj) {
case WT_SPACE:
// Space does nothing at all
break;
case WT_MOUNTAIN:
// Mountain the cracked effect
HWColour(COL_MOUNTAIN);
HWLine(X(2), Y(6), X(2), Y(10));
HWLine(X(0), Y(8), X(2), Y(8));
HWLine(X(2), Y(6), X(4), Y(6));
HWLine(X(4), Y(6), X(4), Y(4));
HWLine(X(2), Y(2), X(4), Y(4));
HWLine(X(2), Y(2), X(2), Y(0));
HWLine(X(2), Y(2), X(0), Y(2));
HWLine(X(8), Y(4), X(4), Y(4));
HWLine(X(8), Y(4), X(8), Y(0));
HWLine(X(8), Y(2), X(10), Y(2));
HWLine(X(6), Y(4), X(6), Y(8));
HWLine(X(10), Y(8), X(6), Y(8));
HWLine(X(8), Y(8), X(8), Y(10));
break;
case WT_TREE:
// Tree is just a box
HWColour(COL_TREE);
BOX(3, 3, 7, 7);
break;
case WT_TOWN:
// Town is 5 boxes
HWColour(COL_TOWN);
BOX(2, 2, 4, 4); BOX(4, 4, 6, 6); BOX(6, 6, 8, 8);
BOX(6, 2, 8, 4); BOX(2, 6, 4, 8);
break;
case WT_DUNGEON:
// Dungeon is a cross
HWColour(COL_DUNGEON);
HWLine(X(3), Y(3), X(7), Y(7));
HWLine(X(7), Y(3), X(3), Y(7));
break;
case WT_BRITISH:
// British castle
HWColour(COL_BRITISH);
HWLine(X(2), Y(2), X(8), Y(8));
HWLine(X(8), Y(2), X(2), Y(8));
BOX(0, 0, 10, 10);
BOX(2, 2, 8, 8);
break;
case WT_PLAYER:
// Player
HWColour(COL_PLAYER);
HWLine(X(4), Y(5), X(6), Y(5));
HWLine(X(5), Y(4), X(5), Y(6));
break;
default:
break;
}
}
} // namespace Views
} // namespace Ultima0
} // namespace Ultima

View File

@@ -0,0 +1,43 @@
/* 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 ULTIMA0_GFX_MAP_H
#define ULTIMA0_GFX_MAP_H
#include "graphics/managed_surface.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
class Map {
private:
static void drawTile(Graphics::ManagedSurface *s, const Common::Rect &r, int obj);
public:
static void draw(Graphics::ManagedSurface *s, bool showAsMap = false);
};
} // namespace Gfx
} // namespace Ultima0
} // namespace Ultima
#endif

View File

@@ -0,0 +1,205 @@
/* 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/ultima0/gfx/monster.h"
#include "ultima/ultima0/ultima0.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
Monster::DrawFn Monster::DRAW_FUNCTIONS[] = {
nullptr, drawSkeleton, drawThief, drawRat, drawOrc, drawViper,
drawCarrion, drawGremlin, drawMimic, drawDaemon, drawBalrog
};
int Monster::_xPos = 640;
int Monster::_yPos = 512;
constexpr int color = COL_MONSTER;
// End marker
#define END (-9999.99)
#define X(n) (x1 + w * (n)/10)
#define Y(n) (y1 + h * (n)/10)
#define HWLine(X1, Y1, X2, Y2) s->drawLine(X1, Y1, X2, Y2, color)
#define BOX(x1,y1,x2,y2) { HWLine(X(x1),Y(y1),X(x2),Y(y1));HWLine(X(x1),Y(y1),X(x1),Y(y2));HWLine(X(x2),Y(y2),X(x2),Y(y1));HWLine(X(x2),Y(y2),X(x1),Y(y2)); }
void Monster::draw(Graphics::ManagedSurface *s, int x, int y, int monster, double scale) {
// Save drawing pos
_xPos = x; _yPos = y;
if (monster == MN_MIMIC)
// Fix for Mimic/Chest
_xPos -= 90;
// Call appropriate function
assert(monster > 0 && monster <= MN_BALROG);
(*DRAW_FUNCTIONS[monster])(s, 0, 0, scale);
}
void Monster::hPlot(Graphics::ManagedSurface *s, double x, double y, ...) {
va_list alist;
double y1, x1;
// Start reading values
va_start(alist, y);
bool isPixel = true;
do {
x1 = va_arg(alist, double); // Get the next two
y1 = va_arg(alist, double);
if (x1 != END && y1 != END) {
// If legit, draw the line
HWLine(_xPos + x, _yPos + y, _xPos + x1, _yPos + y1);
isPixel = false;
} else if (isPixel)
// Single pixel only
HWLine(_xPos + x, _yPos + y, _xPos + x, _yPos + y);
x = x1; y = y1;
} while (x1 != END && y1 != END);
va_end(alist);
}
void Monster::drawSkeleton(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x - 23 / d, y, x - 15 / d, y, x - 15 / d, y - 15 / d, x - 8 / d, y - 30 / d, x + 8 / d, y - 30 / d, x + 15 / d, y - 15 / d, x + 15 / d, y, x + 23 / d, y, END, END);
hPlot(s, x, y - 26 / d, x, y - 65 / d, END, END);
hPlot(s, x - 2 / d + .5, y - 38 / d, x + 2 / d + .5, y - 38 / d, END, END);
hPlot(s, x - 3 / d + .5, y - 45 / d, x + 3 / d + .5, y - 45 / d, END, END);
hPlot(s, x - 5 / d + .5, y - 53 / d, x + 5 / d + .5, y - 53 / d, END, END);
hPlot(s, x - 23 / d, y - 56 / d, x - 30 / d, y - 53 / d, x - 23 / d, y - 45 / d, x - 23 / d, y - 53 / d, x - 8 / d, y - 38 / d, END, END);
hPlot(s, x - 15 / d, y - 45 / d, x - 8 / d, y - 60 / d, x + 8 / d, y - 60 / d, x + 15 / d, y - 45 / d, END, END);
hPlot(s, x + 15 / d, y - 42 / d, x + 15 / d, y - 57 / d, END, END);
hPlot(s, x + 12 / d, y - 45 / d, x + 20 / d, y - 45 / d, END, END);
hPlot(s, x, y - 75 / d, x - 5 / d + .5, y - 80 / d, x - 8 / d, y - 75 / d, x - 5 / d + .5, y - 65 / d, x + 5 / d + .5, y - 65 / d, x + 5 / d + .5, y - 68 / d, x - 5 / d + .5, y - 68 / d, x - 5 / d + .5, y - 65 / d, END, END);
hPlot(s, x + 5 / d + .5, y - 65 / d, x + 8 / d, y - 75 / d, x + 5 / d + .5, y - 80 / d, x - 5 / d + .5, y - 80 / d, END, END);
hPlot(s, x - 5 / d + .5, y - 72 / d, END, END);
hPlot(s, x + 5 / d + .5, y - 72 / d, END, END);
}
void Monster::drawThief(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x, y - 56 / d, x, y - 8 / d, x + 10 / d, y, x + 30 / d, y, x + 30 / d, y - 45 / d, x + 10 / d, y - 64 / d, x, y - 56 / d, END, END);
hPlot(s, x - 10 / d, y - 64 / d, x - 30 / d, y - 45 / d, x - 30 / d, y, x - 10 / d, y, x, y - 8 / d, END, END);
hPlot(s, x - 10 / d, y - 64 / d, x - 10 / d, y - 75 / d, x, y - 83 / d, x + 10 / d, y - 75 / d, x, y - 79 / d, x - 10 / d, y - 75 / d, x, y - 60 / d, x + 10 / d, y - 75 / d, x + 10 / d, y - 64 / d, END, END);
}
void Monster::drawRat(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x + 5 / d, y - 30 / d, x, y - 25 / d, x - 5 / d, y - 30 / d, x - 15 / d, y - 5 / d, x - 10 / d, y, x + 10 / d, y, x + 15 / d, y - 5 / d, END, END);
hPlot(s, x + 20 / d, y - 5 / d, x + 10 / d, y, x + 15 / d, y - 5 / d, x + 5 / d, y - 30 / d, x + 10 / d, y - 40 / d, x + 3 / d + .5, y - 35 / d, x - 3 / d + .5, y - 35 / d, x - 10 / d, y - 40 / d, x - 5 / d, y - 30 / d, END, END);
hPlot(s, x - 5 / d, y - 33 / d, x - 3 / d + .5, y - 30 / d, END, END);
hPlot(s, x + 5 / d, y - 33 / d, x + 3 / d + .5, y - 30 / d, END, END);
hPlot(s, x - 5 / d, y - 20 / d, x - 5 / d, y - 15 / d, END, END);
hPlot(s, x + 5 / d, y - 20 / d, x + 5 / d, y - 15 / d, END, END);
hPlot(s, x - 7 / d, y - 20 / d, x - 7 / d, y - 15 / d, END, END);
hPlot(s, x + 7 / d, y - 20 / d, x + 7 / d, y - 15 / d, END, END);
}
void Monster::drawOrc(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x, y, x - 15 / d, y, x - 8 / d, y - 8 / d, x - 8 / d, y - 15 / d, x - 15 / d, y - 23 / d, x - 15 / d, y - 15 / d, x - 23 / d, y - 23 / d, END, END);
hPlot(s, x - 23 / d, y - 23 / d, x - 15 / d, y - 53 / d, x - 8 / d, y - 53 / d, x - 15 / d, y - 68 / d, x - 8 / d, y - 75 / d, x, y - 75 / d, END, END);
hPlot(s, x, y, x + 15 / d, y, x + 8 / d, y - 8 / d, x + 8 / d, y - 15 / d, x + 15 / d, y - 23 / d, x + 15 / d, y - 15 / d, x + 23 / d, y - 23 / d, END, END);
hPlot(s, x + 23 / d, y - 23 / d, x + 15 / d, y - 53 / d, x + 8 / d, y - 53 / d, x + 15 / d, y - 68 / d, x + 8 / d, y - 75 / d, x, y - 75 / d, END, END);
hPlot(s, x - 15 / d, y - 68 / d, x + 15 / d, y - 68 / d, END, END);
hPlot(s, x - 8 / d, y - 53 / d, x + 8 / d, y - 53 / d, END, END);
hPlot(s, x - 23 / d, y - 15 / d, x + 8 / d, y - 45 / d, END, END);
hPlot(s, x - 8 / d, y - 68 / d, x, y - 60 / d, x + 8 / d, y - 68 / d, x + 8 / d, y - 60 / d, x - 8 / d, y - 60 / d, x - 8 / d, y - 68 / d, END, END);
hPlot(s, x, y - 38 / d, x - 8 / d, y - 38 / d, x + 8 / d, y - 53 / d, x + 8 / d, y - 45 / d, x + 15 / d, y - 45 / d, x, y - 30 / d, x, y - 38 / d, END, END);
}
void Monster::drawViper(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x - 10 / d, y - 15 / d, x - 10 / d, y - 30 / d, x - 15 / d, y - 20 / d, x - 15 / d, y - 15 / d, x - 15 / d, y, x + 15 / d, y, x + 15 / d, y - 15 / d, x - 15 / d, y - 15 / d, END, END);
hPlot(s, x - 15 / d, y - 10 / d, x + 15 / d, y - 10 / d, END, END);
hPlot(s, x - 15 / d, y - 5 / d, x + 15 / d, y - 5 / d, END, END);
hPlot(s, x, y - 15 / d, x - 5 / d, y - 20 / d, x - 5 / d, y - 35 / d, x + 5 / d, y - 35 / d, x + 5 / d, y - 20 / d, x + 10 / d, y - 15 / d, END, END);
hPlot(s, x - 5 / d, y - 20 / d, x + 5 / d, y - 20 / d, END, END);
hPlot(s, x - 5 / d, y - 25 / d, x + 5 / d, y - 25 / d, END, END);
hPlot(s, x - 5 / d, y - 30 / d, x + 5 / d, y - 30 / d, END, END);
hPlot(s, x - 10 / d, y - 35 / d, x - 10 / d, y - 40 / d, x - 5 / d, y - 45 / d, x + 5 / d, y - 45 / d, x + 10 / d, y - 40 / d, x + 10 / d, y - 35 / d, END, END);
hPlot(s, x - 10 / d, y - 40 / d, x, y - 45 / d, x + 10 / d, y - 40 / d, END, END);
hPlot(s, x - 5 / d, y - 40 / d, x + 5 / d, y - 40 / d, x + 15 / d, y - 30 / d, x, y - 40 / d, x - 15 / d, y - 30 / d, x - 5 / d + .5, y - 40 / d, END, END);
}
void Monster::drawCarrion(Graphics::ManagedSurface *s, double x, double y, double d) {
// 79-dst.recty(d) line here
hPlot(s, x - 20 / d, y - 79 / d, x - 20 / d, y - 88 / d, x - 10 / d, y - 83 / d, x + 10 / d, y - 83 / d, x + 20 / d, y - 88 / d, x + 20 / d, y - 79 / d, x - 20 / d, y - 79 / d, END, END);
hPlot(s, x - 20 / d, y - 88 / d, x - 30 / d, y - 83 / d, x - 30 / d, y - 78 / d, END, END);
hPlot(s, x + 20 / d, y - 88 / d, x + 30 / d, y - 83 / d, x + 40 / d, y - 83 / d, END, END);
hPlot(s, x - 15 / d, y - 86 / d, x - 20 / d, y - 83 / d, x - 20 / d, y - 78 / d, x - 30 / d, y - 73 / d, x - 30 / d, y - 68 / d, x - 20 / d, y - 63 / d, END, END);
hPlot(s, x - 10 / d, y - 83 / d, x - 10 / d, y - 58 / d, x, y - 50 / d, END, END);
hPlot(s, x + 10 / d, y - 83 / d, x + 10 / d, y - 78 / d, x + 20 / d, y - 73 / d, x + 20 / d, y - 40 / d, END, END);
hPlot(s, x + 15 / d, y - 85 / d, x + 20 / d, y - 78 / d, x + 30 / d, y - 76 / d, x + 30 / d, y - 60 / d, END, END);
hPlot(s, x, y - 83 / d, x, y - 73 / d, x + 10 / d, y - 68 / d, x + 10 / d, y - 63 / d, x, y - 58 / d, END, END);
}
void Monster::drawGremlin(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x + 5 / d + 1, y - 10 / d, x - 5 / d + 1, y - 10 / d, x, y - 15 / d, x + 10 / d, y - 20 / d, x + 5 / d + 1, y - 15 / d, x + 5 / d + 1, y - 10 / d, END, END);
hPlot(s, x + 5 / d + 1, y - 10 / d, x + 7 / d + 1, y - 6 / d, x + 5 / d + 1, y - 3 / d, x - 5 / d + 1, y - 3 / d, x - 7 / d + 1, y - 6 / d, x - 5 / d + 1, y - 10 / d, END, END);
hPlot(s, x + 2 / d + 1, y - 3 / d, x + 5 / d + 1, y, x + 8 / d, y, END, END);
hPlot(s, x - 2 / d + 1, y - 3 / d, x - 5 / d + 1, y, x - 8 / d, y, END, END);
hPlot(s, x + 3 / d + 1, y - 8 / d, END, END);
hPlot(s, x - 3 / d + 1, y - 8 / d, END, END);
hPlot(s, x + 3 / d + 1, y - 5 / d, x - 3 / d + 1, y - 5 / d, END, END);
}
void Monster::drawMimic(Graphics::ManagedSurface *s, double x, double y, double d) {
double xx = x;
hPlot(s, 139 - 10 / d, xx, 139 - 10 / d, xx - 10 / d, 139 + 10 / d, xx - 10 / d, 139 + 10 / d, xx, 139 - 10 / d, xx, END, END);
hPlot(s, 139 - 10 / d, xx - 10 / d, 139 - 5 / d, xx - 15 / d, 139 + 15 / d, xx - 15 / d, 139 + 15 / d, xx - 5 / d, 139 + 10 / d, xx, END, END);
hPlot(s, 139 + 10 / d, xx - 10 / d, 139 + 15 / d, xx - 15 / d, END, END);
}
void Monster::drawDaemon(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x - 14 / d, y - 46 / d, x - 12 / d, y - 37 / d, x - 20 / d, y - 32 / d, x - 30 / d, y - 32 / d, x - 22 / d, y - 24 / d, x - 40 / d, y - 17 / d, x - 40 / d, y - 7 / d, x - 38 / d, y - 5 / d, x - 40 / d, y - 3 / d, x - 40 / d, y, END, END);
hPlot(s, x - 40 / d, y, x - 36 / d, y, x - 34 / d, y - 2 / d, x - 32 / d, y, x - 28 / d, y, x - 28 / d, y - 3 / d, x - 30 / d, y - 5 / d, x - 28 / d, y - 7 / d, x - 28 / d, y - 15 / d, x, y - 27 / d, END, END);
hPlot(s, x + 14 / d, y - 46 / d, x + 12 / d, y - 37 / d, x + 20 / d, y - 32 / d, x + 30 / d, y - 32 / d, x + 22 / d, y - 24 / d, x + 40 / d, y - 17 / d, x + 40 / d, y - 7 / d, x + 38 / d, y - 5 / d, x + 40 / d, y - 3 / d, x + 40 / d, y, END, END);
hPlot(s, x + 40 / d, y, x + 36 / d, y, x + 34 / d, y - 2 / d, x + 32 / d, y, x + 28 / d, y, x + 28 / d, y - 3 / d, x + 30 / d, y - 5 / d, x + 28 / d, y - 7 / d, x + 28 / d, y - 15 / d, x, y - 27 / d, END, END);
hPlot(s, x + 6 / d, y - 48 / d, x + 38 / d, y - 41 / d, x + 40 / d, y - 42 / d, x + 18 / d, y - 56 / d, x + 12 / d, y - 56 / d, x + 10 / d, y - 57 / d, x + 8 / d, y - 56 / d, x - 8 / d, y - 56 / d, x - 10 / d, y - 58 / d, x + 14 / d, y - 58 / d, x + 16 / d, y - 59 / d, END, END);
hPlot(s, x + 16 / d, y - 59 / d, x + 8 / d, y - 63 / d, x + 6 / d, y - 63 / d, x + 2 / d + .5, y - 70 / d, x + 2 / d + .5, y - 63 / d, x - 2 / d + .5, y - 63 / d, x - 2 / d + .5, y - 70 / d, x - 6 / d, y - 63 / d, x - 8 / d, y - 63 / d, x - 16 / d, y - 59 / d, x - 14 / d, y - 58 / d, x - 10 / d, y - 58 / d, END, END);
hPlot(s, x - 10 / d, y - 57 / d, x - 12 / d, y - 56 / d, x - 18 / d, y - 56 / d, x - 36 / d, y - 47 / d, x - 36 / d, y - 39 / d, x - 28 / d, y - 41 / d, x - 28 / d, y - 46 / d, x - 20 / d, y - 50 / d, x - 18 / d, y - 50 / d, x - 14 / d, y - 46 / d, END, END);
hPlot(s, x - 28 / d, y - 41 / d, x + 30 / d, y - 55 / d, END, END);
hPlot(s, x + 28 / d, y - 58 / d, x + 22 / d, y - 56 / d, x + 22 / d, y - 53 / d, x + 28 / d, y - 52 / d, x + 34 / d, y - 54 / d, END, END);
hPlot(s, x + 20 / d, y - 50 / d, x + 26 / d, y - 47 / d, END, END);
hPlot(s, x + 10 / d, y - 58 / d, x + 10 / d, y - 61 / d, x + 4 / d, y - 58 / d, END, END);
hPlot(s, x - 10 / d, y - 58 / d, x - 10 / d, y - 61 / d, x - 4 / d, y - 58 / d, END, END);
hPlot(s, x + 40 / d, y - 9 / d, x + 50 / d, y - 12 / d, x + 40 / d, y - 7 / d, END, END);
hPlot(s, x - 8 / d, y - 25 / d, x + 6 / d, y - 7 / d, x + 28 / d, y - 7 / d, x + 28 / d, y - 9 / d, x + 20 / d, y - 9 / d, x + 6 / d, y - 25 / d, END, END);
}
void Monster::drawBalrog(Graphics::ManagedSurface *s, double x, double y, double d) {
hPlot(s, x + 6 / d, y - 60 / d, x + 30 / d, y - 90 / d, x + 60 / d, y - 30 / d, x + 60 / d, y - 10 / d, x + 30 / d, y - 40 / d, x + 15 / d, y - 40 / d, END, END);
hPlot(s, x - 6 / d, y - 60 / d, x - 30 / d, y - 90 / d, x - 60 / d, y - 30 / d, x - 60 / d, y - 10 / d, x - 30 / d, y - 40 / d, x - 15 / d, y - 40 / d, END, END);
hPlot(s, x, y - 25 / d, x + 6 / d, y - 25 / d, x + 10 / d, y - 20 / d, x + 12 / d, y - 10 / d, x + 10 / d, y - 6 / d, x + 10 / d, y, x + 14 / d, y, x + 15 / d, y - 5 / d, x + 16 / d, y, x + 20 / d, y, END, END);
hPlot(s, x + 20 / d, y, x + 20 / d, y - 6 / d, x + 18 / d, y - 10 / d, x + 18 / d, y - 20 / d, x + 15 / d, y - 30 / d, x + 15 / d, y - 45 / d, x + 40 / d, y - 60 / d, x + 40 / d, y - 70 / d, END, END);
hPlot(s, x + 40 / d, y - 70 / d, x + 10 / d, y - 55 / d, x + 6 / d, y - 60 / d, x + 10 / d, y - 74 / d, x + 6 / d, y - 80 / d, x + 4 / d + .5, y - 80 / d, x + 3 / d + .5, y - 82 / d, x + 2 / d + .5, y - 80 / d, x, y - 80 / d, END, END);
hPlot(s, x, y - 25 / d, x - 6 / d, y - 25 / d, x - 10 / d, y - 20 / d, x - 12 / d, y - 10 / d, x - 10 / d, y - 6 / d, x - 10 / d, y, x - 14 / d, y, x - 15 / d, y - 5 / d, x - 16 / d, y, x - 20 / d, y, END, END);
hPlot(s, x - 20 / d, y, x - 20 / d, y - 6 / d, x - 18 / d, y - 10 / d, x - 18 / d, y - 20 / d, x - 15 / d, y - 30 / d, x - 15 / d, y - 45 / d, x - 40 / d, y - 60 / d, x - 40 / d, y - 70 / d, END, END); // left wing
hPlot(s, x - 40 / d, y - 70 / d, x - 10 / d, y - 55 / d, x - 6 / d, y - 60 / d, x - 10 / d, y - 74 / d, x - 6 / d, y - 80 / d, x - 4 / d + .5, y - 80 / d, x - 3 / d + .5, y - 82 / d, x - 2 / d + .5, y - 80 / d, x, y - 80 / d, END, END);
hPlot(s, x - 6 / d, y - 25 / d, x, y - 6 / d, x + 10 / d, y, x + 4 / d + .5, y - 8 / d, x + 6 / d, y - 25 / d, END, END);
hPlot(s, x - 40 / d, y - 64 / d, x - 40 / d, y - 90 / d, x - 52 / d, y - 80 / d, x - 52 / d, y - 40 / d, END, END);
hPlot(s, x + 40 / d, y - 86 / d, x + 38 / d, y - 92 / d, x + 42 / d, y - 92 / d, x + 40 / d, y - 86 / d, x + 40 / d, y - 50 / d, END, END);
hPlot(s, x + 4 / d + .5, y - 70 / d, x + 6 / d, y - 74 / d, END, END);
hPlot(s, x - 4 / d + .5, y - 70 / d, x - 6 / d, y - 74 / d, END, END);
hPlot(s, x, y - 64 / d, x, y - 60 / d, END, END);
}
} // namespace Views
} // namespace Ultima0
} // namespace Ultima

View File

@@ -0,0 +1,67 @@
/* 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 ULTIMA0_GFX_MONSTER_H
#define ULTIMA0_GFX_MONSTER_H
#include "graphics/managed_surface.h"
#include "ultima/ultima0/data/data.h"
namespace Ultima {
namespace Ultima0 {
namespace Gfx {
class Monster {
private:
// Drawing position
static int _xPos, _yPos;
/**
* Emulate the Apple ][ HPLOT function
*/
static void hPlot(Graphics::ManagedSurface *s, double x, double y, ...);
/**
* Monster drawing functions
*/
typedef void(*DrawFn)(Graphics::ManagedSurface *s, double x, double y, double d);
static void drawSkeleton(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawThief(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawRat(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawOrc(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawViper(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawCarrion(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawGremlin(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawMimic(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawDaemon(Graphics::ManagedSurface *s, double x,double y,double d);
static void drawBalrog(Graphics::ManagedSurface *s, double x,double y,double d);
static DrawFn DRAW_FUNCTIONS[];
public:
static void draw(Graphics::ManagedSurface *s, int x, int y,
int monster, double scale);
};
} // namespace Gfx
} // namespace Ultima0
} // namespace Ultima
#endif