1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-07 03:12:36 +01:00

Add GXT loading support and i18n of prints.

This commit is contained in:
Daniel Evans 2014-07-28 06:20:39 +01:00
parent 5b9c95d346
commit 688ee493b4
8 changed files with 134 additions and 2 deletions

View File

@ -0,0 +1,26 @@
#pragma once
#ifndef _GAMETEXTS_HPP_
#define _GAMETEXTS_HPP_
#include <string>
#include <unordered_map>
class GameTexts
{
std::unordered_map<std::string, std::string> _textDB;
public:
void addText(const std::string& id, const std::string& text) {
_textDB.insert({ id, text });
}
std::string text(const std::string& id) {
auto a = _textDB.find(id);
if( a != _textDB.end() ) {
return a->second;
}
return id;
}
};
#endif

View File

@ -11,6 +11,7 @@
#include <loaders/WeatherLoader.hpp>
#include <objects/VehicleInfo.hpp>
#include <data/CollisionModel.hpp>
#include <data/GameTexts.hpp>
#include <memory>
@ -106,6 +107,8 @@ public:
void loadHandling(const std::string& path);
SCMFile* loadSCM(const std::string& path);
void loadGXT(const std::string& name);
/**
* Loads water level data
@ -280,6 +283,8 @@ public:
int getWaterIndexAt(const glm::vec3& ws) const;
float getWaveHeightAt(const glm::vec3& ws) const;
GameTexts texts;
};
#endif

View File

@ -0,0 +1,13 @@
#pragma once
#ifndef _LOADERGXT_HPP_
#define _LOADERGXT_HPP_
#include <engine/RWTypes.hpp>
#include <data/GameTexts.hpp>
class LoaderGXT
{
public:
void load( GameTexts& texts, FileHandle& file );
};
#endif

View File

@ -9,6 +9,8 @@
#include <data/WeaponData.hpp>
#include <script/SCMFile.hpp>
#include <loaders/LoaderGXT.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
@ -88,6 +90,7 @@ void GameData::load()
_knownFiles.insert({"loplyguy.dff", {false, datpath+"/models/Generic/loplyguy.dff"}});
_knownFiles.insert({"weapons.dff", {false, datpath+"/models/Generic/weapons.dff"}});
_knownFiles.insert({"particle.txd", {false, datpath+"/models/particle.txd"}});
_knownFiles.insert({"english.gxt", {false, datpath+"/TEXT/english.gxt"}});
loadDFF("wheels.DFF");
loadDFF("weapons.dff");
@ -368,6 +371,15 @@ SCMFile *GameData::loadSCM(const std::string &path)
return scm;
}
void GameData::loadGXT(const std::string &name)
{
auto d = openFile2(name);
LoaderGXT loader;
loader.load( texts, d );
}
void GameData::loadWaterpro(const std::string& path)
{
std::ifstream ifstr(path.c_str());

View File

@ -0,0 +1,48 @@
#include <loaders/LoaderGXT.hpp>
#include <iconv.h>
void LoaderGXT::load(GameTexts &texts, FileHandle &file)
{
auto data = file->data;
data += 4; // TKEY
std::uint32_t blocksize = *(std::uint32_t*)data;
data += 4;
auto tdata = data+blocksize+8;
// This is not supported in GCC 4.8.1
//std::wstring_convert<std::codecvt<char16_t,char,std::mbstate_t>,char16_t> convert;
auto icv = iconv_open("UTF-8", "UTF-16");
for( size_t t = 0; t < blocksize/12; ++t ) {
size_t offset = *(std::uint32_t*)(data+(t * 12 + 0));
std::string id(data+(t * 12 + 4));
// Find the terminating bytes
size_t bytes = 0;
for(;; bytes++ ) {
if(tdata[offset+bytes-1] == 0 && tdata[offset+bytes] == 0) break;
}
size_t len = bytes/2;
size_t outSize = 1024;
char u8buff[1024];
char *uwot = u8buff;
char* strbase = tdata+offset;
iconv(icv, &strbase, &bytes, &uwot, &outSize);
u8buff[len] = '\0';
std::string message(u8buff);
texts.addText(id, message);
}
iconv_close(icv);
}

View File

@ -230,7 +230,9 @@ SCMMicrocodeTable ops_game = {
})
OPC( 0x00BC, "Print Message Now", 3, {
m->getWorld()->state.osTextString = p->at(0).string;
std::string str(p->at(0).string);
str = m->getWorld()->gameData.texts.text(str);
m->getWorld()->state.osTextString = str;
m->getWorld()->state.osTextTime = p->at(1).integer / 1000.f;
m->getWorld()->state.osTextStart= m->getWorld()->gameTime;
m->getWorld()->state.osTextStyle = p->at(2).integer;

View File

@ -212,6 +212,8 @@ void init(std::string gtapath, bool loadWorld)
// Load dynamic object data
gta->gameData.loadDynamicObjects(gtapath + "/data/object.dat");
gta->gameData.loadGXT("english.gxt");
gta->gameTime = 0.f;
debugDrawer = new DebugDraw;
@ -404,7 +406,8 @@ void render(float alpha)
auto sz = window.getSize();
auto b = messageText.getLocalBounds();
messageText.setPosition(sz.x / 2.f - std::round(b.width / 2.f), sz.y / 2.f - std::round(b.height / 2.f));
float lowerBar = sz.y - sz.y * 0.1f;
messageText.setPosition(sz.x / 2.f - std::round(b.width / 2.f), lowerBar - std::round(b.height / 2.f));
window.draw(messageText);
}
}

23
tests/test_text.cpp Normal file
View File

@ -0,0 +1,23 @@
#include <boost/test/unit_test.hpp>
#include "test_globals.hpp"
#include <data/GameTexts.hpp>
#include <loaders/LoaderGXT.hpp>
BOOST_AUTO_TEST_SUITE(TextTests)
BOOST_AUTO_TEST_CASE(load_test)
{
{
auto d = Global::get().e->gameData.openFile2("english.gxt");
GameTexts texts;
LoaderGXT loader;
loader.load( texts, d );
BOOST_CHECK_EQUAL( texts.text("1008"), "BUSTED" );
}
}
BOOST_AUTO_TEST_SUITE_END()