Files
scummvm-cursorfix/engines/ultima/nuvie/portraits/portrait_se.cpp
2026-02-02 04:50:13 +01:00

200 lines
5.1 KiB
C++

/* 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/nuvie/core/nuvie_defs.h"
#include "ultima/nuvie/conf/configuration.h"
#include "ultima/nuvie/gui/widgets/console.h"
#include "ultima/nuvie/files/nuvie_io_file.h"
#include "ultima/nuvie/files/u6_shape.h"
#include "ultima/nuvie/core/game.h"
#include "ultima/nuvie/actors/actor_manager.h"
#include "ultima/nuvie/actors/actor.h"
#include "ultima/nuvie/core/game_clock.h"
#include "ultima/nuvie/portraits/portrait_se.h"
#include "ultima/nuvie/misc/u6_misc.h"
namespace Ultima {
namespace Nuvie {
bool PortraitSE::init() {
Common::Path filename;
avatar_portrait_num = 0;
width = 79;
height = 85;
config_get_path(config, "faces.lzc", filename);
if (faces.open(filename, 4) == false) {
ConsoleAddError("Opening " + filename.toString());
return false;
}
return true;
}
bool PortraitSE::load(NuvieIO *objlist) {
// U6 only?
objlist->seek(0x1c72);
avatar_portrait_num = objlist->read1(); //read in the avatar portrait number from objlist.
if (avatar_portrait_num > 0)
avatar_portrait_num--;
return true;
}
uint8 PortraitSE::get_portrait_num(Actor *actor) const {
uint8 num;
if (actor == nullptr)
return NO_PORTRAIT_FOUND;
num = actor->get_actor_num();
return num;
}
U6Shape *PortraitSE::get_background_shape(Actor *actor) {
U6Lib_n file;
U6Shape *bg = new U6Shape();
Common::Path filename;
config_get_path(config, "bkgrnd.lzc", filename);
file.open(filename, 4, NUVIE_GAME_MD);
unsigned char *temp_buf = file.get_item(get_background_shape_num(actor));
bg->load(temp_buf + 8);
free(temp_buf);
return bg;
}
uint8 PortraitSE::get_background_shape_num(Actor *actor) const {
const struct {
uint16 x;
uint16 y;
uint16 x1;
uint16 y1;
uint8 bg_num;
} bg_lookup_tbl[27] = {
{0x1E8, 0x208, 0x287, 0x25F, 0x4},
{0x0E0, 0x260, 0x107, 0x287, 0xC},
{0x140, 0xC0, 0x187, 0xEF, 0xC},
{0x168, 0x218, 0x19F, 0x23F, 0xC},
{0x290, 0x318, 0x2C7, 0x34F, 0xC},
{0x188, 0x108, 0x1B7, 0x13F, 0xC},
{0x3D0, 0x130, 0x3F7, 0x167, 0xC},
{0x220, 0x120, 0x25F, 0x15F, 0xC},
{0x228, 0x60, 0x25F, 0x8F, 0xC},
{0x0F0, 0xA8, 0x307, 0x12F, 0x1},
{0x1F8, 0x40, 0x257, 0x8F, 0x1},
{0x1D8, 0x140, 0x207, 0x167, 0x1},
{0x340, 0xE8, 0x3FF, 0x1DF, 0x1},
{0x130, 0x130, 0x167, 0x1A7, 0x1},
{0x168, 0x1D0, 0x209, 0x227, 0x1},
{0x58, 0x268, 0x90, 0x2A8, 0x1},
{0x118, 0x40, 0x13F, 0x77, 0x1},
{0x280, 0x310, 0x29F, 0x327, 0x1},
{0x160, 0xF8, 0x21F, 0x1A7, 0xB},
{0x230, 0x160, 0x2C7, 0x1E7, 0xB},
{0x100, 0x48, 0x15F, 0xA7, 0xB},
{0x178, 0x100, 0x1C8, 0x12F, 0xB},
{0x120, 0xB0, 0x13F, 0xDF, 0xB},
{0x1A8, 0x78, 0x1EF, 0xB7, 0xB},
{0x0A8, 0x238, 0x100, 0x27F, 0xB},
{0x148, 0x228, 0x1BF, 0x287, 0xB},
{0x0, 0x0, 0x3FF, 0x3FF, 0x2}
};
uint16 x = actor->get_x();
uint16 y = actor->get_y();
uint8 z = actor->get_z();
if (z == 3) {
return 10;
} else if (z != 0) {
return 9;
}
for (int i = 0; i < 27; i++) {
if (x >= bg_lookup_tbl[i].x && y >= bg_lookup_tbl[i].y && x <= bg_lookup_tbl[i].x1 && y <= bg_lookup_tbl[i].y1) {
if (bg_lookup_tbl[i].bg_num < 5) {
GameClock *clock = Game::get_game()->get_clock();
if (clock) {
uint8 hour = clock->get_hour();
if (hour >= 18 || hour < 5) {
return bg_lookup_tbl[i].bg_num + 4;
}
}
}
return bg_lookup_tbl[i].bg_num;
}
}
return 2;
}
unsigned char *PortraitSE::get_portrait_data(Actor *actor) {
uint8 num = get_portrait_num(actor);
if (num == NO_PORTRAIT_FOUND)
return nullptr;
U6Shape *bg_shp = get_background_shape(actor);
unsigned char *temp_buf = faces.get_item(num);
if (!temp_buf)
return nullptr;
U6Shape *p_shp = new U6Shape();
p_shp->load(temp_buf + 8);
free(temp_buf);
//blit the background into the portrait while keeping the 1 pixel border.
uint16 bg_w, bg_h;
bg_shp->get_size(&bg_w, &bg_h);
uint16 p_w, p_h;
p_shp->get_size(&p_w, &p_h);
unsigned char *bg_data = bg_shp->get_data();
unsigned char *p_data = p_shp->get_data();
p_data += p_w;
p_data += 1;
for (int i = 0; i < bg_h; i++) {
for (int j = 0; j < bg_w; j++)
if (p_data[j] == 255) {
p_data[j] = bg_data[j];
}
p_data += p_w;
bg_data += bg_w;
}
bg_data = (unsigned char *)malloc(p_w * p_h);
memcpy(bg_data, p_shp->get_data(), p_w * p_h);
delete bg_shp;
delete p_shp;
return bg_data;
}
} // End of namespace Nuvie
} // End of namespace Ultima