mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 03:42:48 +01:00
Add GXT loading support and i18n of prints.
This commit is contained in:
parent
5b9c95d346
commit
688ee493b4
26
rwengine/include/data/GameTexts.hpp
Normal file
26
rwengine/include/data/GameTexts.hpp
Normal 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
|
@ -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
|
||||
|
13
rwengine/include/loaders/LoaderGXT.hpp
Normal file
13
rwengine/include/loaders/LoaderGXT.hpp
Normal 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
|
@ -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());
|
||||
|
48
rwengine/src/loaders/LoaderGXT.cpp
Normal file
48
rwengine/src/loaders/LoaderGXT.cpp
Normal 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);
|
||||
}
|
@ -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;
|
||||
|
@ -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
23
tests/test_text.cpp
Normal 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()
|
Loading…
Reference in New Issue
Block a user