ULTIMA1: Added extraction of Origin logo from game executable

This commit is contained in:
Paul Gilbert 2020-01-19 10:11:11 -08:00 committed by Paul Gilbert
parent 642e8b376b
commit 8f3d6a537f
6 changed files with 147 additions and 1 deletions

View File

@ -34,6 +34,7 @@
#include <string.h>
#include "archive.h"
#include "ultima1_map.h"
#include "ultima1_resources.h"
#define VERSION_NUMBER 1
@ -48,6 +49,7 @@ int main(int argc, char *argv[]) {
error("Could not open output file");
}
writeUltima1Resources(archive);
writeUltima1EnhancedMap(archive);
archive.close();

View File

@ -4,6 +4,7 @@ MODULE_OBJS := \
create_ultima.o \
archive.o \
ultima1_map.o \
ultima1_resources.o \
hashmap.o \
memorypool.o \
str.o

View File

@ -0,0 +1,96 @@
/* 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
// HACK to allow building with the SDL backend on MinGW
// see bug #1800764 "TOOLS: MinGW tools building broken"
#ifdef main
#undef main
#endif // main
#include "ultima1_resources.h"
#include "file.h"
#define FILE_BUFFER_SIZE 1024
#define MD5_COMPUTE_SIZE 1024
uint32 computeMD5(Common::File &f) {
uint32 total = 0;
f.seek(0);
for (int idx = 0; idx < MD5_COMPUTE_SIZE; ++idx)
total += f.readByte();
f.seek(0);
return total;
}
#define DATA_SEGMENT_OFFSET 0x40D0
#define LOGO_HEIGHT 64
#define LOGO_WIDTH1 199
#define LOGO_WIDTH2 76
#define LOGO_TABLE1 0x3262
#define LOGO_TABLE2 0x4320
void createLogo(Common::File &in, Common::MemFile &out) {
int offsets[LOGO_HEIGHT][2];
char buffer[LOGO_WIDTH1 + LOGO_WIDTH2 + 1];
// Load in the tables
in.seek(DATA_SEGMENT_OFFSET + LOGO_TABLE1);
for (int y = 0; y < LOGO_HEIGHT; ++y)
offsets[y][0] = in.readWord();
in.seek(DATA_SEGMENT_OFFSET + LOGO_TABLE2);
for (int y = 0; y < LOGO_HEIGHT; ++y)
offsets[y][1] = in.readWord();
// Convert the lines
for (int y = 0; y < LOGO_HEIGHT; ++y) {
in.seek(DATA_SEGMENT_OFFSET + offsets[y][0]);
in.read(buffer, LOGO_WIDTH1 + 1);
assert(buffer[LOGO_WIDTH1] == '\0');
in.seek(DATA_SEGMENT_OFFSET + offsets[y][1]);
in.read(buffer + LOGO_WIDTH1, LOGO_WIDTH2 + 1);
assert(buffer[LOGO_WIDTH1 + LOGO_WIDTH2] == '\0');
for (int x = 0; x < (LOGO_WIDTH1 + LOGO_WIDTH2); ++x)
out.writeByte(buffer[x] == '*' ? 1 : 0);
}
}
void writeUltima1Resources(Archive &a) {
// Open up ultima1.exe for logo
Common::File u1;
if (!u1.open("Ultima 1/ultima.exe"))
error("Could not find ultima.exe");
if (computeMD5(u1) != 64620)
error("Unknown version of Ultima 1 ultima.exe");
// Add the Origin logo
Common::MemFile logo;
createLogo(u1, logo);
a.add("ULTIMA1/LOGO", logo);
u1.close();
}

View File

@ -0,0 +1,30 @@
/* 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef ULTIMA1_RESOURCES_H
#define ULTIMA1_RESOURCES_H
#include "archive.h"
extern void writeUltima1Resources(Archive &a);
#endif

View File

@ -24,7 +24,9 @@
#include "ultima/ultima1/u1gfx/drawing_support.h"
#include "ultima/ultima1/core/resources.h"
#include "ultima/ultima1/game.h"
#include "ultima/shared/core/file.h"
#include "ultima/shared/engine/messages.h"
#include "image/bmp.h"
namespace Ultima {
namespace Ultima1 {
@ -34,7 +36,16 @@ BEGIN_MESSAGE_MAP(ViewTitle, Shared::Gfx::VisualContainer)
ON_MESSAGE(KeypressMsg)
END_MESSAGE_MAP()
ViewTitle::ViewTitle(Shared::TreeItem *parent) : Shared::Gfx::VisualContainer("Title", Rect(0, 0, 320, 200), parent) {
ViewTitle::ViewTitle(TreeItem *parent) : Shared::Gfx::VisualContainer("Title", Rect(0, 0, 320, 200), parent) {
// Load the Origin logo
Shared::File f("data/logo.bmp");
Image::BitmapDecoder bmp;
if (!bmp.loadStream(f))
error("Couldn't load logo");
const Graphics::Surface *src = bmp.getSurface();
_logo.create(src->w, src->h);
_logo.blitFrom(*src);
}
ViewTitle::~ViewTitle() {
@ -54,6 +65,9 @@ void ViewTitle::draw() {
s.writeString(game->_res->TITLE_MESSAGES[0], TextPoint(16, 8), game->_whiteColor);
s.writeString(game->_res->TITLE_MESSAGES[1], TextPoint(8, 11), game->_whiteColor);
s.writeString(game->_res->TITLE_MESSAGES[2], TextPoint(0, 21), game->_whiteColor);
//****DEBUG*****
s.blitFrom(_logo);
}
bool ViewTitle::KeypressMsg(CKeypressMsg &msg) {

View File

@ -25,6 +25,7 @@
#include "ultima/shared/gfx/visual_container.h"
#include "ultima/shared/gfx/bitmap.h"
#include "graphics/managed_surface.h"
namespace Ultima {
@ -50,6 +51,8 @@ using Shared::CKeypressMsg;
class ViewTitle : public Shared::Gfx::VisualContainer {
DECLARE_MESSAGE_MAP;
bool KeypressMsg(CKeypressMsg &msg);
private:
Graphics::ManagedSurface _logo;
public:
CLASSDEF;
ViewTitle(Shared::TreeItem *parent = nullptr);