Merge branch 'master' of https://github.com/zinnschlag/openmw into graphics

This commit is contained in:
scrawl 2013-02-27 09:25:44 +01:00
commit 369f881170
27 changed files with 203 additions and 73 deletions

View file

@ -43,7 +43,7 @@ namespace MWBase
virtual void remove (const MWWorld::Ptr& ptr) = 0;
///< Deregister an object for management
virtual void updateCell(const MWWorld::Ptr &ptr) = 0;
virtual void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) = 0;
///< Moves an object to a new cell
virtual void drop (const MWWorld::CellStore *cellStore) = 0;

View file

@ -382,7 +382,7 @@ namespace MWClass
const MWMechanics::MagicEffects &mageffects = npcdata->mCreatureStats.getMagicEffects();
const float encumbranceTerm = fJumpEncumbranceBase->getFloat() +
fJumpEncumbranceMultiplier->getFloat() *
(Npc::getEncumbrance(ptr)/Npc::getCapacity(ptr));
(1.0f - Npc::getEncumbrance(ptr)/Npc::getCapacity(ptr));
float a = npcdata->mNpcStats.getSkill(ESM::Skill::Acrobatics).getModified();
float b = 0.0f;

View file

@ -1,6 +1,8 @@
#include <components/misc/stringops.hpp>
#include "messagebox.hpp"
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
using namespace MWGui;
@ -375,6 +377,7 @@ void InteractiveMessageBox::enterPressed()
if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok)
{
buttonActivated(*button);
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
break;
}
}

View file

@ -61,7 +61,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager)
prevButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectPreviousHair);
nextButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onSelectNextHair);
setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu4", "Race"));
setText("RaceT", mWindowManager.getGameSettingString("sRaceMenu5", "Race"));
getWidget(mRaceList, "RaceList");
mRaceList->setScrollVisible(true);
mRaceList->eventListSelectAccept += MyGUI::newDelegate(this, &RaceDialog::onSelectRace);

View file

@ -181,6 +181,11 @@ namespace MWInput
case A_Activate:
resetIdleTime();
activate();
if( MWBase::Environment::get().getWindowManager()->isGuiMode()
&& MWBase::Environment::get().getWindowManager()->getMode() == MWGui::GM_InterMessageBox ) {
// Pressing the activation key when a messagebox is prompting for "ok" will activate the ok button
MWBase::Environment::get().getWindowManager()->enterPressed();
}
break;
case A_Journal:
toggleJournal ();

View file

@ -26,13 +26,15 @@ void Activators::removeActivator (const MWWorld::Ptr& ptr)
mActivators.erase(iter);
}
void Activators::updateActivatorCell(const MWWorld::Ptr &ptr)
void Activators::updateActivator(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
{
PtrControllerMap::iterator iter = mActivators.find(ptr);
PtrControllerMap::iterator iter = mActivators.find(old);
if(iter != mActivators.end())
{
CharacterController ctrl = iter->second;
mActivators.erase(iter);
ctrl.updatePtr(ptr);
mActivators.insert(std::make_pair(ptr, ctrl));
}
}

View file

@ -28,8 +28,8 @@ namespace MWMechanics
void removeActivator (const MWWorld::Ptr& ptr);
///< Deregister an activator
void updateActivatorCell(const MWWorld::Ptr& ptr);
///< Updates an activator with a new cell store
void updateActivator(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr);
///< Updates an activator with a new Ptr
void dropActivators (const MWWorld::CellStore *cellStore);
///< Deregister all activators in the given cell.

View file

@ -179,13 +179,15 @@ namespace MWMechanics
mActors.erase(iter);
}
void Actors::updateActorCell(const MWWorld::Ptr &ptr)
void Actors::updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
{
PtrControllerMap::iterator iter = mActors.find(ptr);
PtrControllerMap::iterator iter = mActors.find(old);
if(iter != mActors.end())
{
CharacterController ctrl = iter->second;
mActors.erase(iter);
ctrl.updatePtr(ptr);
mActors.insert(std::make_pair(ptr, ctrl));
}
}

View file

@ -58,8 +58,8 @@ namespace MWMechanics
///
/// \note Ignored, if \a ptr is not a registered actor.
void updateActorCell(const MWWorld::Ptr& ptr);
///< Updates an actor with a new cell store
void updateActor(const MWWorld::Ptr &old, const MWWorld::Ptr& ptr);
///< Updates an actor with a new Ptr
void dropActors (const MWWorld::CellStore *cellStore);
///< Deregister all actors in the given cell.

View file

@ -131,6 +131,12 @@ CharacterController::~CharacterController()
}
void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
{
mPtr = ptr;
}
void CharacterController::markerEvent(float time, const std::string &evt)
{
if(evt == "stop")

View file

@ -79,6 +79,8 @@ public:
CharacterController(const CharacterController &rhs);
virtual ~CharacterController();
void updatePtr(const MWWorld::Ptr &ptr);
Ogre::Vector3 update(float duration);
void playGroup(const std::string &groupname, int mode, int count);

View file

@ -191,12 +191,12 @@ namespace MWMechanics
mActivators.removeActivator(ptr);
}
void MechanicsManager::updateCell(const MWWorld::Ptr &ptr)
void MechanicsManager::updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
{
if(ptr.getTypeName() == typeid(ESM::Activator).name())
mActivators.updateActivatorCell(ptr);
mActivators.updateActivator(old, ptr);
else
mActors.updateActorCell(ptr);
mActors.updateActor(old, ptr);
}
@ -557,7 +557,8 @@ namespace MWMechanics
float fPerDieRollMult = gmst.find("fPerDieRollMult")->getFloat();
float fPerTempMult = gmst.find("fPerTempMult")->getFloat();
float x,y = 0;
float x = 0;
float y = 0;
float roll = static_cast<float> (std::rand()) / RAND_MAX * 100;

View file

@ -48,7 +48,7 @@ namespace MWMechanics
virtual void remove (const MWWorld::Ptr& ptr);
///< Deregister an object for management
virtual void updateCell(const MWWorld::Ptr &ptr);
virtual void updateCell(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr);
///< Moves an object to a new cell
virtual void drop(const MWWorld::CellStore *cellStore);

View file

@ -170,6 +170,7 @@ namespace MWRender
void RaceSelectionPreview::update(float angle)
{
mAnimation->runAnimation(0.0f);
mNode->roll(Ogre::Radian(angle), Ogre::SceneNode::TS_LOCAL);
mNode->setVisible (true);
@ -184,4 +185,9 @@ namespace MWRender
rebuild();
update(0);
}
void RaceSelectionPreview::onSetup ()
{
mAnimation->play("idle", "start", "stop", false);
}
}

View file

@ -85,6 +85,8 @@ namespace MWRender
public:
RaceSelectionPreview();
virtual void onSetup();
void update(float angle);
const ESM::NPC &getPrototype() const {

View file

@ -404,6 +404,8 @@ public:
*type = MWSound::SampleType_UInt8;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_S16)
*type = MWSound::SampleType_Int16;
else if(mAVStream->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
*type = MWSound::SampleType_Float32;
else
fail(std::string("Unsupported sample format: ")+
av_get_sample_fmt_name(mAVStream->codec->sample_fmt));

View file

@ -134,6 +134,18 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
return dec;
}
static AVSampleFormat ffmpegNonPlanarSampleFormat (AVSampleFormat format)
{
switch (format)
{
case AV_SAMPLE_FMT_U8P: return AV_SAMPLE_FMT_U8;
case AV_SAMPLE_FMT_S16P: return AV_SAMPLE_FMT_S16;
case AV_SAMPLE_FMT_S32P: return AV_SAMPLE_FMT_S32;
case AV_SAMPLE_FMT_FLTP: return AV_SAMPLE_FMT_FLT;
case AV_SAMPLE_FMT_DBLP: return AV_SAMPLE_FMT_DBL;
default:return format;
}
}
void FFmpeg_Decoder::open(const std::string &fname)
{
@ -153,10 +165,6 @@ void FFmpeg_Decoder::open(const std::string &fname)
try
{
for(size_t j = 0;j < mFormatCtx->nb_streams;j++)
if(mFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
mFormatCtx->streams[j]->codec->request_sample_fmt = AV_SAMPLE_FMT_S16;
if(avformat_find_stream_info(mFormatCtx, NULL) < 0)
fail("Failed to find stream info in "+fname);
@ -164,7 +172,6 @@ void FFmpeg_Decoder::open(const std::string &fname)
{
if(mFormatCtx->streams[j]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
mFormatCtx->streams[j]->codec->request_sample_fmt = AV_SAMPLE_FMT_S16;
mStream = &mFormatCtx->streams[j];
break;
}
@ -172,6 +179,8 @@ void FFmpeg_Decoder::open(const std::string &fname)
if(!mStream)
fail("No audio streams in "+fname);
(*mStream)->codec->request_sample_fmt = ffmpegNonPlanarSampleFormat ((*mStream)->codec->sample_fmt);
AVCodec *codec = avcodec_find_decoder((*mStream)->codec->codec_id);
if(!codec)
{
@ -224,6 +233,8 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
*type = SampleType_UInt8;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16)
*type = SampleType_Int16;
else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLT)
*type = SampleType_Float32;
else
fail(std::string("Unsupported sample format: ")+
av_get_sample_fmt_name((*mStream)->codec->sample_fmt));

View file

@ -88,6 +88,51 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
}
}
}
if(alIsExtensionPresent("AL_EXT_FLOAT32"))
{
static const struct {
char name[32];
ChannelConfig chans;
SampleType type;
} fltfmtlist[] = {
{ "AL_FORMAT_MONO_FLOAT32", ChannelConfig_Mono, SampleType_Float32 },
{ "AL_FORMAT_STEREO_FLOAT32", ChannelConfig_Stereo, SampleType_Float32 },
};
static const size_t fltfmtlistsize = sizeof(fltfmtlist)/sizeof(fltfmtlist[0]);
for(size_t i = 0;i < fltfmtlistsize;i++)
{
if(fltfmtlist[i].chans == chans && fltfmtlist[i].type == type)
{
ALenum format = alGetEnumValue(fltfmtlist[i].name);
if(format != 0 && format != -1)
return format;
}
}
if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
{
static const struct {
char name[32];
ChannelConfig chans;
SampleType type;
} fltmcfmtlist[] = {
{ "AL_FORMAT_QUAD32", ChannelConfig_Quad, SampleType_Float32 },
{ "AL_FORMAT_51CHN32", ChannelConfig_5point1, SampleType_Float32 },
{ "AL_FORMAT_71CHN32", ChannelConfig_7point1, SampleType_Float32 },
};
static const size_t fltmcfmtlistsize = sizeof(fltmcfmtlist)/sizeof(fltmcfmtlist[0]);
for(size_t i = 0;i < fltmcfmtlistsize;i++)
{
if(fltmcfmtlist[i].chans == chans && fltmcfmtlist[i].type == type)
{
ALenum format = alGetEnumValue(fltmcfmtlist[i].name);
if(format != 0 && format != -1)
return format;
}
}
}
}
fail(std::string("Unsupported sound format (")+getChannelConfigName(chans)+", "+getSampleTypeName(type)+")");
return AL_NONE;

View file

@ -9,7 +9,8 @@ namespace MWSound
{
enum SampleType {
SampleType_UInt8,
SampleType_Int16
SampleType_Int16,
SampleType_Float32
};
const char *getSampleTypeName(SampleType type);

View file

@ -607,6 +607,7 @@ namespace MWSound
{
case SampleType_UInt8: return "U8";
case SampleType_Int16: return "S16";
case SampleType_Float32: return "Float32";
}
return "(unknown sample type)";
}
@ -638,6 +639,7 @@ namespace MWSound
{
case SampleType_UInt8: frames *= 1; break;
case SampleType_Int16: frames *= 2; break;
case SampleType_Float32: frames *= 4; break;
}
return frames;
}

View file

@ -86,7 +86,7 @@ MWWorld::Ptr MWWorld::Cells::getPtrAndCache (const std::string& name, Ptr::CellS
MWWorld::Cells::Cells (const MWWorld::ESMStore& store, std::vector<ESM::ESMReader>& reader)
: mStore (store), mReader (reader),
mIdCache (20, std::pair<std::string, Ptr::CellStore *> ("", (Ptr::CellStore*)0)), /// \todo make cache size configurable
mIdCache (40, std::pair<std::string, Ptr::CellStore *> ("", (Ptr::CellStore*)0)), /// \todo make cache size configurable
mIdCacheIndex (0)
{}

View file

@ -773,7 +773,7 @@ namespace MWWorld
mRendering->updateObjectCell(ptr, copy);
MWBase::MechanicsManager *mechMgr = MWBase::Environment::get().getMechanicsManager();
mechMgr->updateCell(copy);
mechMgr->updateCell(ptr, copy);
std::string script =
MWWorld::Class::get(ptr).getScript(ptr);
@ -832,16 +832,16 @@ namespace MWWorld
rot.y = Ogre::Degree(y).valueRadians();
rot.z = Ogre::Degree(z).valueRadians();
float *objRot = ptr.getRefData().getPosition().rot;
if(ptr.getRefData().getBaseNode() == 0 || !mRendering->rotateObject(ptr, rot, adjust))
if (mRendering->rotateObject(ptr, rot, adjust))
{
objRot[0] = (adjust ? objRot[0] + rot.x : rot.x), objRot[1] = (adjust ? objRot[1] + rot.y : rot.y), objRot[2] = (adjust ? objRot[2] + rot.z : rot.z);
return;
}
// rotate physically iff renderer confirm so
float *objRot = ptr.getRefData().getPosition().rot;
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
// do this after rendering rotated the object so it gets changed by Class->adjustRotation
objRot[0] = rot.x, objRot[1] = rot.y, objRot[2] = rot.z;
mPhysics->rotateObject(ptr);
if (ptr.getRefData().getBaseNode() != 0) {
mPhysics->rotateObject(ptr);
}
}
}
void World::safePlaceObject(const MWWorld::Ptr& ptr,MWWorld::CellStore &Cell,ESM::Position pos)

View file

@ -45,7 +45,10 @@ namespace Compiler
reportWarning ("Names for script " + mName + " do not match", loc);
mState = EndCompleteState;
return true;
return false; // we are stopping here, because there might be more garbage on the end line,
// that we must ignore.
//
/// \todo allow this workaround to be disabled for newer scripts
}
return Parser::parseName (name, loc, scanner);

View file

@ -155,6 +155,8 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
// the flags we currently use, at least.
flags |= node->flags;
isCollisionNode = isCollisionNode || (node->recType == Nif::RC_RootCollisionNode);
// Marker objects: no collision
/// \todo don't do this in the editor
if (node->name.find("marker") != std::string::npos)
@ -191,25 +193,26 @@ void ManualBulletShapeLoader::handleNode(const Nif::Node *node, int flags,
}
}
if(node->hasBounds)
if(!hasCollisionNode || isCollisionNode)
{
cShape->boxTranslation = node->boundPos;
cShape->boxRotation = node->boundRot;
mBoundingBox = new btBoxShape(getbtVector(node->boundXYZ));
}
if(node->hasBounds)
{
cShape->boxTranslation = node->boundPos;
cShape->boxRotation = node->boundRot;
mBoundingBox = new btBoxShape(getbtVector(node->boundXYZ));
}
if(node->recType == Nif::RC_NiTriShape && (isCollisionNode || !hasCollisionNode))
{
cShape->mCollide = !(flags&0x800);
handleNiTriShape(static_cast<const Nif::NiTriShape*>(node), flags, node->getWorldTransform(), raycastingOnly);
if(node->recType == Nif::RC_NiTriShape)
{
cShape->mCollide = !(flags&0x800);
handleNiTriShape(static_cast<const Nif::NiTriShape*>(node), flags, node->getWorldTransform(), raycastingOnly);
}
}
// For NiNodes, loop through children
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node);
if(ninode)
{
isCollisionNode = isCollisionNode || (node->recType == Nif::RC_RootCollisionNode);
const Nif::NodeList &list = ninode->children;
for(size_t i = 0;i < list.length();i++)
{

View file

@ -602,7 +602,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
Nif::NiSourceTexture *st = t->textures[0].texture.getPtr();
if (st->external)
{
/* Bethesda at some at some point converted all their BSA
/* Bethesda at some point converted all their BSA
* textures from tga to dds for increased load speed, but all
* texture file name references were kept as .tga.
*/
@ -621,6 +621,17 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
if(!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
texName = path + st->filename;
}
else if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
{
// workaround for Better Heads addon
size_t lastSlash = st->filename.rfind('\\');
if (lastSlash != std::string::npos && lastSlash + 1 != st->filename.size()) {
texName = path + st->filename.substr(lastSlash + 1);
// workaround for Better Bodies addon
if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(texName))
texName = st->filename;
}
}
}
else warn("Found internal texture, ignoring.");
}
@ -691,7 +702,7 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String
new sh::Vector4(diffuse.x, diffuse.y, diffuse.z, alpha)));
instance->setProperty ("specular", sh::makeProperty<sh::Vector4> (
new sh::Vector4(specular.x, specular.y, specular.z, glossiness)));
new sh::Vector4(specular.x, specular.y, specular.z, glossiness*255.0f)));
instance->setProperty ("emissive", sh::makeProperty<sh::Vector3> (
new sh::Vector3(emissive.x, emissive.y, emissive.z)));
@ -773,7 +784,6 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
std::string mGroup;
size_t mShapeIndex;
std::string mMaterialName;
std::string mShapeName;
void warn(const std::string &msg)
{
@ -882,8 +892,7 @@ class NIFMeshLoader : Ogre::ManualResourceLoader
Ogre::VertexDeclaration *decl;
int nextBuf = 0;
Ogre::SubMesh *sub = ((mShapeName.length() > 0) ? mesh->createSubMesh(mShapeName) :
mesh->createSubMesh());
Ogre::SubMesh *sub = mesh->createSubMesh();
// Add vertices
sub->useSharedVertices = false;
@ -1043,6 +1052,10 @@ public:
void createMeshes(const Nif::Node *node, MeshInfoList &meshes, int flags=0)
{
// Do not create meshes for the collision shape (includes all children)
if(node->recType == Nif::RC_RootCollisionNode)
return;
flags |= node->flags;
// Marker objects: just skip the entire node
@ -1071,12 +1084,11 @@ public:
if(node->recType == Nif::RC_NiTriShape && !(flags&0x01)) // Not hidden
{
const Nif::NiTriShape *shape = dynamic_cast<const Nif::NiTriShape*>(node);
mShapeName = shape->name;
Ogre::MeshManager &meshMgr = Ogre::MeshManager::getSingleton();
std::string fullname = mName+"@index="+Ogre::StringConverter::toString(shape->recIndex);
if(mShapeName.length() > 0)
fullname += "@shape="+mShapeName;
if(shape->name.length() > 0)
fullname += "@shape="+shape->name;
Misc::StringUtils::toLower(fullname);
Ogre::MeshPtr mesh = meshMgr.getByName(fullname);

View file

@ -12,65 +12,75 @@ Marc Zinnschlag (Zini) - Lead Programmer/Project Manager
Adam Hogan (aurix)
Aleksandar Jovanov
Alexander Nadeau (wareya)
Alexander Olofsson (Ace)
Artem Kotsynyak (greye)
athile
BrotherBrick
Chris Robinson
Chris Robinson (KittyCat)
Cory F. Cohen (cfcohen)
Cris Mihalache (Mirceam)
Douglas Diniz (Dgdiniz)
Douglas Mencken (dougmencken)
Edmondo Tommasina (edmondo)
Eduard Cot (trombonecot)
Eli2
Emanuel "potatoesmaster" Guével
gugus / gus
Emanuel Guével (potatoesmaster)
gugus/gus
Jacob Essex (Yacoby)
Jannik Heller (scrawl)
Jason Hooks (jhooks)
Joel Graff (graffy)
Jordan Milne
Julien Voisin (jvoisin/ap0)
Karl-Felix Glatzer (k1ll)
Lars Söderberg (Lazaroth)
lazydev
Leon Saunders (emoose)
Lukasz Gromanowski (lgro)
Marcin Hulist (Gohan)
Mark Siewert (mark76)
Manuel Edelmann (vorenon)
Michael Mc Donnell
Michael Papageorgiou (werdanith)
Nathan Jeffords (blunted2night)
Nikolay Kasyanov (corristo)
Nolan Poe (nopoe)
Paul McElroy (Greendogo)
Pieter van der Kloet (pvdk)
Radu-Marius Popovici (rpopovici)
Roman Melnik (Kromgart)
Sandy Carter (bwrsandman)
Sebastian Wick (swick)
Sergey Shambir
Sylvain T. (Garvek)
Sylvain Thesnieres (Garvek)
Tom Mason (wheybags)
Packagers:
Alexander Olofsson (Ace) - Windows
BrotherBrick - Ubuntu Linux
Edmondo Tommasina - Gentoo Linux
Edmondo Tommasina (edmondo) - Gentoo Linux
Julian Ospald (hasufell) - Gentoo Linux
Karl-Felix Glatzer (k1ll) - Linux Binaries
Kenny Armstrong (artorius) - Fedora Linux
Nikolay Kasyanov (corristo) - Mac OS X
Sandy Carter (bwrsandman) - Arch Linux
Public Relations:
ElderTroll - Release Manager
sir_herrbatka - News Writer
Public Relations and Translations:
Artem Kotsynyak (greye) - Russian News Writer
Julien Voisin (jvoisin/ap0) - French News Writer
Mickey Lyle (raevol) - Release Manager
Pithorn - Chinese News Writer
sir_herrbatka - English/Polish News Writer
WeirdSexy - Podcaster
Website:
juanmnzsk8 - Spanish News Writer
Julien Voisin (jvoisin/ap0) - French News Writer
Kingpix - Italian News Writer
Lukasz Gromanowski (lgro) - Website Administrator
Nikolay Kasyanov (corristo) - Russian News Writer
Okulo - Dutch News Writer
penguinroad - Indonesian News Writer
Ryan Sardonic (Wry) - Wiki Editor
sir_herrbatka - Forum Admin/Polish News Writer
spyboot - German News Writer
sir_herrbatka - Forum Administrator
Formula Research:
@ -86,20 +96,32 @@ Sadler
Artwork:
Necrod - OpenMW Logo
raevol - Wordpress Theme
Mickey Lyle (raevol) - Wordpress Theme
Okulo - OpenMW Editor Icons
Inactive Contributors:
Ardekantur
Armin Preiml
Carl Maxwell
Diggory Hardy
Jan Borsodi
Dmitry Marakasov (AMDmi3)
ElderTroll
guidoj
Jan-Peter Nilsson (peppe)
Jan Borsodi
Josua Grawitter
juanmnzsk8
Kingpix
Lordrea
Michal Sciubidlo
Nicolay Korslund
pchan3
penguinroad
psi29a
sergoz
spyboot
Star-Demon
Thoronador
Yuri Krupenin
@ -117,7 +139,7 @@ Thanks to Kevin Ryan,
for creating the icon used for the Data Files tab of the OpenMW Launcher.
Thanks to Georg Duffner,
for the open-source EB Garamond fontface.
for his EB Garamond fontface, see OFL.txt for his license terms.
Thanks to Dongle,
for his Daedric fontface, see Daedric Font License.txt for his license terms.

View file

@ -9,7 +9,7 @@ Website: http://www.openmw.org
Font Licenses:
EBGaramond-Regular.ttf: OFL (see OFL.txt for more information)
VeraMono.ttf: custom (see Bitstream Vera License.txt for more information)
DejaVuLGCSansMono.ttf: custom (see DejaVu Font License.txt for more information)