1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-19 20:23:54 +00:00

Finished all basic parsers. Added --quiet option to esmtool.

This commit is contained in:
Nicolay Korslund 2010-02-28 09:18:48 +01:00
parent 2302e1f712
commit db56985828
12 changed files with 194 additions and 105 deletions

View file

@ -6,7 +6,7 @@
namespace ESM { namespace ESM {
/* /*
* Books * Books, magic scrolls, notes and so on
*/ */
struct Book struct Book

View file

@ -57,12 +57,11 @@ struct Cell
if(esm.isNextSub("DELE")) esm.skipHSub(); if(esm.isNextSub("DELE")) esm.skipHSub();
esm.getHNT(data, "DATA", 12); esm.getHNT(data, "DATA", 12);
region = esm.getHNOString("RGNN");
// Save position and move on // Save position and move on
context = esm.getContext(); context = esm.getContext();
esm.skipRecord(); esm.skipRecord();
region = esm.getHNOString("RGNN");
} }
}; };
} }

View file

@ -22,9 +22,9 @@ struct InventoryList
void load(ESMReader &esm) void load(ESMReader &esm)
{ {
ContItem ci; ContItem ci;
while(esm.hasMoreSubs()) while(esm.isNextSub("NPCO"))
{ {
esm.getHNT(ci, "NPCO", 36); esm.getHT(ci, 36);
list.push_back(ci); list.push_back(ci);
} }
} }

View file

@ -72,6 +72,7 @@ struct Creature
esm.getHNT(data, "NPDT", 96); esm.getHNT(data, "NPDT", 96);
esm.getHNT(flags, "FLAG"); esm.getHNT(flags, "FLAG");
scale = 1.0;
esm.getHNOT(scale, "XSCL"); esm.getHNOT(scale, "XSCL");
inventory.load(esm); inventory.load(esm);

46
esm/loaddial.hpp Normal file
View file

@ -0,0 +1,46 @@
#ifndef _ESM_DIAL_H
#define _ESM_DIAL_H
#include "esm_reader.hpp"
namespace ESM {
/*
* Dialogue topic and journal entries. The actual data is contained in
* the INFO records following the DIAL.
*/
struct Dialogue
{
enum Type
{
Topic = 0,
Voice = 1,
Greeting = 2,
Persuasion = 3,
Journal = 4,
Deleted = -1
};
char type;
void load(ESMReader &esm)
{
esm.getSubNameIs("DATA");
esm.getSubHeader();
int si = esm.getSubSize();
if(si == 1)
esm.getT(type);
else if(si == 4)
{
// These are just markers, their values are not used.
int i;
esm.getT(i);
esm.getHNT(i,"DELE");
type = Deleted;
}
else esm.fail("Unknown sub record size");
}
};
}
#endif

View file

@ -203,6 +203,8 @@ struct GameSetting
void load(ESMReader &esm) void load(ESMReader &esm)
{ {
assert(id != "");
dirty = false; dirty = false;
// We are apparently allowed to be empty // We are apparently allowed to be empty

View file

@ -14,6 +14,7 @@
#include "loadcont.hpp" #include "loadcont.hpp"
#include "loadcrea.hpp" #include "loadcrea.hpp"
#include "loadcrec.hpp" #include "loadcrec.hpp"
#include "loaddial.hpp"
#include "loaddoor.hpp" #include "loaddoor.hpp"
#include "loadench.hpp" #include "loadench.hpp"
#include "loadfact.hpp" #include "loadfact.hpp"

View file

@ -42,6 +42,8 @@ int main(int argc, char**argv)
return 0; return 0;
} }
bool quiet = info.quiet_given;
esm.open(filename); esm.open(filename);
cout << "Author: " << esm.getAuthor() << endl; cout << "Author: " << esm.getAuthor() << endl;
@ -57,10 +59,11 @@ int main(int argc, char**argv)
while(esm.hasMoreRecs()) while(esm.hasMoreRecs())
{ {
NAME n = esm.getRecName(); NAME n = esm.getRecName();
cout << "\nRecord: " << n.toString();
esm.getRecHeader(); esm.getRecHeader();
string id = esm.getHNOString("NAME"); string id = esm.getHNOString("NAME");
cout << " '" << id << "'\n"; if(!quiet)
cout << "\nRecord: " << n.toString()
<< " '" << id << "'\n";
switch(n.val) switch(n.val)
{ {
@ -68,15 +71,33 @@ int main(int argc, char**argv)
{ {
Activator ac; Activator ac;
ac.load(esm); ac.load(esm);
if(quiet) break;
cout << " Name: " << ac.name << endl; cout << " Name: " << ac.name << endl;
cout << " Mesh: " << ac.model << endl; cout << " Mesh: " << ac.model << endl;
cout << " Script: " << ac.script << endl; cout << " Script: " << ac.script << endl;
break; break;
} }
case REC_ALCH:
{
Potion p;
p.load(esm);
if(quiet) break;
cout << " Name: " << p.name << endl;
break;
}
case REC_APPA:
{
Apparatus p;
p.load(esm);
if(quiet) break;
cout << " Name: " << p.name << endl;
break;
}
case REC_ARMO: case REC_ARMO:
{ {
Armor am; Armor am;
am.load(esm); am.load(esm);
if(quiet) break;
cout << " Name: " << am.name << endl; cout << " Name: " << am.name << endl;
cout << " Mesh: " << am.model << endl; cout << " Mesh: " << am.model << endl;
cout << " Icon: " << am.icon << endl; cout << " Icon: " << am.icon << endl;
@ -90,23 +111,83 @@ int main(int argc, char**argv)
{ {
BodyPart bp; BodyPart bp;
bp.load(esm); bp.load(esm);
if(quiet) break;
cout << " Name: " << bp.name << endl; cout << " Name: " << bp.name << endl;
cout << " Mesh: " << bp.model << endl; cout << " Mesh: " << bp.model << endl;
break; break;
} }
case REC_BOOK:
{
Book b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Mesh: " << b.model << endl;
break;
}
case REC_BSGN: case REC_BSGN:
{ {
BirthSign bs; BirthSign bs;
bs.load(esm); bs.load(esm);
if(quiet) break;
cout << " Name: " << bs.name << endl; cout << " Name: " << bs.name << endl;
cout << " Texture: " << bs.texture << endl; cout << " Texture: " << bs.texture << endl;
cout << " Description: " << bs.description << endl; cout << " Description: " << bs.description << endl;
break; break;
} }
case REC_CELL:
{
Cell b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Region: " << b.region << endl;
break;
}
case REC_CLAS:
{
Class b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
cout << " Description: " << b.description << endl;
break;
}
case REC_CLOT:
{
Clothing b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_CONT:
{
Container b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_CREA:
{
Creature b;
b.load(esm);
if(quiet) break;
cout << " Name: " << b.name << endl;
break;
}
case REC_DIAL:
{
Dialogue b;
b.load(esm);
break;
}
case REC_DOOR: case REC_DOOR:
{ {
Door d; Door d;
d.load(esm); d.load(esm);
if(quiet) break;
cout << " Name: " << d.name << endl; cout << " Name: " << d.name << endl;
cout << " Mesh: " << d.model << endl; cout << " Mesh: " << d.model << endl;
cout << " Script: " << d.script << endl; cout << " Script: " << d.script << endl;
@ -114,10 +195,42 @@ int main(int argc, char**argv)
cout << " CloseSound: " << d.closeSound << endl; cout << " CloseSound: " << d.closeSound << endl;
break; break;
} }
case REC_ENCH:
{
Enchantment b;
b.load(esm);
break;
}
case REC_GMST:
{
GameSetting b;
b.id = id;
b.load(esm);
if(quiet) break;
cout << " Value: ";
if(b.type == VT_String)
cout << "'" << b.str << "' (string)";
else if(b.type == VT_Float)
cout << b.f << " (float)";
else if(b.type == VT_Int)
cout << b.i << " (int)";
cout << "\n Dirty: " << b.dirty << endl;
break;
}
case REC_INFO:
{
DialInfo p;
p.load(esm);
if(quiet) break;
cout << " Id: " << p.id << endl;
cout << " Text: " << p.response << endl;
break;
}
case REC_SOUN: case REC_SOUN:
{ {
Sound d; Sound d;
d.load(esm); d.load(esm);
if(quiet) break;
cout << " Sound: " << d.sound << endl; cout << " Sound: " << d.sound << endl;
cout << " Volume: " << (int)d.data.volume << endl; cout << " Volume: " << (int)d.data.volume << endl;
break; break;
@ -126,12 +239,14 @@ int main(int argc, char**argv)
{ {
Spell s; Spell s;
s.load(esm); s.load(esm);
if(quiet) break;
cout << " Name: " << s.name << endl; cout << " Name: " << s.name << endl;
break; break;
} }
default: default:
cout << " Skipping\n";
esm.skipRecord(); esm.skipRecord();
if(quiet) break;
cout << " Skipping\n";
} }
} }

View file

@ -4,5 +4,6 @@ purpose "Inspect and extract from Morrowind ES files (ESM, ESP, ESS)"
args "--unamed-opts=ES-FILE -F esmtool_cmd -G" args "--unamed-opts=ES-FILE -F esmtool_cmd -G"
option "raw" r "Show an unformattet list of all records and subrecords" optional option "raw" r "Show an unformattet list of all records and subrecords" optional
option "quiet" q "Supress all record information. Useful for speed tests." optional
text "\nIf no option is given, the default action is to parse the entire archive and diplay diagnostic information." text "\nIf no option is given, the default action is to parse the entire archive and diplay diagnostic information."

View file

@ -34,6 +34,7 @@ const char *gengetopt_args_info_help[] = {
" -h, --help Print help and exit", " -h, --help Print help and exit",
" -V, --version Print version and exit", " -V, --version Print version and exit",
" -r, --raw Show an unformattet list of all records and subrecords", " -r, --raw Show an unformattet list of all records and subrecords",
" -q, --quiet Supress all record information. Useful for speed tests.",
"\nIf no option is given, the default action is to parse the entire archive and \ndiplay diagnostic information.", "\nIf no option is given, the default action is to parse the entire archive and \ndiplay diagnostic information.",
0 0
}; };
@ -60,6 +61,7 @@ void clear_given (struct gengetopt_args_info *args_info)
args_info->help_given = 0 ; args_info->help_given = 0 ;
args_info->version_given = 0 ; args_info->version_given = 0 ;
args_info->raw_given = 0 ; args_info->raw_given = 0 ;
args_info->quiet_given = 0 ;
} }
static static
@ -77,6 +79,7 @@ void init_args_info(struct gengetopt_args_info *args_info)
args_info->help_help = gengetopt_args_info_help[0] ; args_info->help_help = gengetopt_args_info_help[0] ;
args_info->version_help = gengetopt_args_info_help[1] ; args_info->version_help = gengetopt_args_info_help[1] ;
args_info->raw_help = gengetopt_args_info_help[2] ; args_info->raw_help = gengetopt_args_info_help[2] ;
args_info->quiet_help = gengetopt_args_info_help[3] ;
} }
@ -192,6 +195,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
write_into_file(outfile, "version", 0, 0 ); write_into_file(outfile, "version", 0, 0 );
if (args_info->raw_given) if (args_info->raw_given)
write_into_file(outfile, "raw", 0, 0 ); write_into_file(outfile, "raw", 0, 0 );
if (args_info->quiet_given)
write_into_file(outfile, "quiet", 0, 0 );
i = EXIT_SUCCESS; i = EXIT_SUCCESS;
@ -1019,6 +1024,7 @@ cmdline_parser_internal (
{ "help", 0, NULL, 'h' }, { "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' }, { "version", 0, NULL, 'V' },
{ "raw", 0, NULL, 'r' }, { "raw", 0, NULL, 'r' },
{ "quiet", 0, NULL, 'q' },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
@ -1027,7 +1033,7 @@ cmdline_parser_internal (
custom_opterr = opterr; custom_opterr = opterr;
custom_optopt = optopt; custom_optopt = optopt;
c = custom_getopt_long (argc, argv, "hVr", long_options, &option_index); c = custom_getopt_long (argc, argv, "hVrq", long_options, &option_index);
optarg = custom_optarg; optarg = custom_optarg;
optind = custom_optind; optind = custom_optind;
@ -1060,6 +1066,18 @@ cmdline_parser_internal (
goto failure; goto failure;
break; break;
case 'q': /* Supress all record information. Useful for speed tests.. */
if (update_arg( 0 ,
0 , &(args_info->quiet_given),
&(local_args_info.quiet_given), optarg, 0, 0, ARG_NO,
check_ambiguity, override, 0, 0,
"quiet", 'q',
additional_error))
goto failure;
break;
case 0: /* Long option with no short option */ case 0: /* Long option with no short option */
case '?': /* Invalid option. */ case '?': /* Invalid option. */

View file

@ -40,10 +40,12 @@ struct gengetopt_args_info
const char *help_help; /**< @brief Print help and exit help description. */ const char *help_help; /**< @brief Print help and exit help description. */
const char *version_help; /**< @brief Print version and exit help description. */ const char *version_help; /**< @brief Print version and exit help description. */
const char *raw_help; /**< @brief Show an unformattet list of all records and subrecords help description. */ const char *raw_help; /**< @brief Show an unformattet list of all records and subrecords help description. */
const char *quiet_help; /**< @brief Supress all record information. Useful for speed tests. help description. */
unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int help_given ; /**< @brief Whether help was given. */
unsigned int version_given ; /**< @brief Whether version was given. */ unsigned int version_given ; /**< @brief Whether version was given. */
unsigned int raw_given ; /**< @brief Whether raw was given. */ unsigned int raw_given ; /**< @brief Whether raw was given. */
unsigned int quiet_given ; /**< @brief Whether quiet was given. */
char **inputs ; /**< @brief unamed options (options without names) */ char **inputs ; /**< @brief unamed options (options without names) */
unsigned inputs_num ; /**< @brief unamed options number */ unsigned inputs_num ; /**< @brief unamed options number */

View file

@ -1,96 +0,0 @@
/*
OpenMW - The completely unofficial reimplementation of Morrowind
Copyright (C) 2008 Nicolay Korslund
Email: < korslund@gmail.com >
WWW: http://openmw.snaptoad.com/
This file (loadspel.d) is part of the OpenMW package.
OpenMW is distributed as free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License
version 3, as published by the Free Software Foundation.
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
version 3 along with this program. If not, see
http://www.gnu.org/licenses/ .
*/
module esm.loadspel;
import esm.imports;
/*
* Spell
*/
struct SpellList
{
RegionBuffer!(Spell*) list;
void load()
{
list = esFile.getRegion().getBuffer!(Spell*)(0,1);
while(esFile.isNextSub("NPCS"))
list ~= esFile.getHPtr!(Spell)(spells);
}
}
struct Spell
{
char[] id;
LoadState state;
enum SpellType
{
Spell = 0, // Normal spell, must be cast and costs mana
Ability = 1, // Inert ability, always in effect
Blight = 2, // Blight disease
Disease = 3, // Common disease
Curse = 4, // Curse (?)
Power = 5 // Power, can use once a day
}
enum Flags
{
Autocalc = 1,
PCStart = 2,
Always = 4 // Casting always succeeds
}
align(1) struct SPDTstruct
{
SpellType type;
int cost;
Flags flags;
static assert(SPDTstruct.sizeof==12);
}
SPDTstruct data;
char[] name;
EffectList effects;
void load()
{with(esFile){
name = getHNOString("FNAM");
readHNExact(&data, data.sizeof, "SPDT");
effects = getRegion().getBuffer!(ENAMstruct)(0,1);
while(isNextSub("ENAM"))
{
effects.length = effects.length + 1;
readHExact(&effects.array[$-1], effects.array[$-1].sizeof);
}
}}
}
ListID!(Spell) spells;