mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-14 00:40:55 +00:00
More or less fix qfprogs when dumping info from qfo files.
Relocations are still broken, but everything seems to be working and qfprogs now seems to be generally usable.
This commit is contained in:
parent
4f6d18a328
commit
438d14d852
1 changed files with 124 additions and 71 deletions
|
@ -66,6 +66,7 @@ static __attribute__ ((used)) const char rcsid[] =
|
||||||
#include "QF/zone.h"
|
#include "QF/zone.h"
|
||||||
|
|
||||||
#include "obj_file.h"
|
#include "obj_file.h"
|
||||||
|
#include "obj_type.h"
|
||||||
#include "qfprogs.h"
|
#include "qfprogs.h"
|
||||||
#include "reloc.h"
|
#include "reloc.h"
|
||||||
|
|
||||||
|
@ -127,9 +128,9 @@ static int num_edicts;
|
||||||
static int reserved_edicts = 1;
|
static int reserved_edicts = 1;
|
||||||
static progs_t pr;
|
static progs_t pr;
|
||||||
|
|
||||||
//static pr_debug_header_t debug;
|
static pr_debug_header_t debug;
|
||||||
static qfo_t *qfo;
|
static qfo_t *qfo;
|
||||||
//static dprograms_t progs;
|
static dprograms_t progs;
|
||||||
|
|
||||||
static const char *source_path = "";
|
static const char *source_path = "";
|
||||||
|
|
||||||
|
@ -252,54 +253,97 @@ init_qf (void)
|
||||||
func_tab = Hash_NewTable (1021, 0, 0, 0);
|
func_tab = Hash_NewTable (1021, 0, 0, 0);
|
||||||
Hash_SetHashCompare (func_tab, func_hash, func_compare);
|
Hash_SetHashCompare (func_tab, func_hash, func_compare);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
static etype_t
|
static etype_t
|
||||||
get_auxtype (const char *type)
|
get_type (pointer_t type)
|
||||||
{
|
{
|
||||||
if (type[0] != 'F') {
|
qfot_type_t *type_def;
|
||||||
|
if (type < 0 || type >= qfo->spaces[qfo_type_space].data_size)
|
||||||
return ev_void;
|
return ev_void;
|
||||||
} else {
|
type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type);
|
||||||
switch (type[1]) {
|
switch ((ty_type_e)type_def->ty) {
|
||||||
default:
|
case ty_none:
|
||||||
case 'v':
|
// field, pointer and function types store their basic type in
|
||||||
return ev_void;
|
// the same location.
|
||||||
case '*':
|
return type_def->t.type;
|
||||||
return ev_string;
|
case ty_struct:
|
||||||
case 'f':
|
case ty_union:
|
||||||
return ev_float;
|
return ev_invalid;
|
||||||
case 'V':
|
case ty_enum:
|
||||||
return ev_vector;
|
return ev_integer; // FIXME v6 progs should be float
|
||||||
case 'E':
|
case ty_array:
|
||||||
return ev_entity;
|
case ty_class:
|
||||||
case 'F':
|
return ev_invalid;
|
||||||
return ev_field;
|
|
||||||
case '(':
|
|
||||||
return ev_func;
|
|
||||||
case '@': // id
|
|
||||||
case '#': // class
|
|
||||||
case '^':
|
|
||||||
return ev_pointer;
|
|
||||||
case 'Q':
|
|
||||||
return ev_quat;
|
|
||||||
case 'i':
|
|
||||||
return ev_integer;
|
|
||||||
case 's':
|
|
||||||
return ev_short;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return ev_invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static etype_t
|
||||||
|
get_type_size (pointer_t type)
|
||||||
|
{
|
||||||
|
qfot_type_t *type_def;
|
||||||
|
int i, size;
|
||||||
|
if (type < 0 || type >= qfo->spaces[qfo_type_space].data_size)
|
||||||
|
return 1;
|
||||||
|
type_def = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, type);
|
||||||
|
switch ((ty_type_e)type_def->ty) {
|
||||||
|
case ty_none:
|
||||||
|
// field, pointer and function types store their basic type in
|
||||||
|
// the same location.
|
||||||
|
return pr_type_size[type_def->t.type];
|
||||||
|
case ty_struct:
|
||||||
|
for (i = size = 0; i < type_def->t.strct.num_fields; i++)
|
||||||
|
size += get_type_size (type_def->t.strct.fields[i].type);
|
||||||
|
return size;
|
||||||
|
case ty_union:
|
||||||
|
for (i = size = 0; i < type_def->t.strct.num_fields; i++) {
|
||||||
|
int s;
|
||||||
|
s = get_type_size (type_def->t.strct.fields[i].type);
|
||||||
|
if (s > size)
|
||||||
|
size = s;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
case ty_enum:
|
||||||
|
return pr_type_size[ev_integer];
|
||||||
|
case ty_array:
|
||||||
|
return type_def->t.array.size
|
||||||
|
* get_type_size (type_def->t.array.type);
|
||||||
|
case ty_class:
|
||||||
|
return 0; // FIXME
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
function_params (dfunction_t *df, qfo_func_t *func)
|
||||||
|
{
|
||||||
|
qfot_type_t *type;
|
||||||
|
int num_params;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (func->type < 0 || func->type >= qfo->spaces[qfo_type_space].data_size)
|
||||||
|
return;
|
||||||
|
type = QFO_POINTER (qfo, qfo_type_space, qfot_type_t, func->type);
|
||||||
|
if (type->ty != ty_none && type->t.type != ev_func)
|
||||||
|
return;
|
||||||
|
df->numparms = num_params = type->t.func.num_params;
|
||||||
|
if (num_params < 0)
|
||||||
|
num_params = ~num_params;
|
||||||
|
for (i = 0; i < num_params; i++)
|
||||||
|
df->parm_size[i] = get_type_size (type->t.func.param_types[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
convert_def (const qfo_def_t *def, ddef_t *ddef)
|
convert_def (const qfo_def_t *def, ddef_t *ddef)
|
||||||
{
|
{
|
||||||
ddef->type = def->basic_type;
|
ddef->type = get_type (def->type);
|
||||||
ddef->ofs = def->ofs;
|
ddef->ofs = def->offset;
|
||||||
ddef->s_name = def->name;
|
ddef->s_name = def->name;
|
||||||
if (!(def->flags & QFOD_NOSAVE)
|
if (!(def->flags & QFOD_NOSAVE)
|
||||||
&& !(def->flags & QFOD_CONSTANT)
|
&& !(def->flags & QFOD_CONSTANT)
|
||||||
&& (def->flags & QFOD_GLOBAL)
|
&& (def->flags & QFOD_GLOBAL)
|
||||||
&& def->basic_type != ev_func
|
&& ddef->type != ev_func
|
||||||
&& def->basic_type != ev_field)
|
&& ddef->type != ev_field)
|
||||||
ddef->type |= DEF_SAVEGLOBAL;
|
ddef->type |= DEF_SAVEGLOBAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,14 +360,15 @@ convert_qfo (void)
|
||||||
pr.progs = &progs;
|
pr.progs = &progs;
|
||||||
progs.version = PROG_VERSION;
|
progs.version = PROG_VERSION;
|
||||||
|
|
||||||
pr.pr_statements = malloc (qfo->code_size * sizeof (dstatement_t));
|
pr.pr_statements = malloc (qfo->spaces[qfo_code_space].data_size
|
||||||
memcpy (pr.pr_statements, qfo->code,
|
* sizeof (dstatement_t));
|
||||||
qfo->code_size * sizeof (dstatement_t));
|
memcpy (pr.pr_statements, qfo->spaces[qfo_code_space].d.code,
|
||||||
progs.numstatements = qfo->code_size;
|
qfo->spaces[qfo_code_space].data_size * sizeof (dstatement_t));
|
||||||
|
progs.numstatements = qfo->spaces[qfo_code_space].data_size;
|
||||||
|
|
||||||
pr.pr_strings = qfo->strings;
|
pr.pr_strings = qfo->spaces[qfo_strings_space].d.strings;
|
||||||
progs.numstrings = qfo->strings_size;
|
progs.numstrings = qfo->spaces[qfo_strings_space].data_size;
|
||||||
pr.pr_stringsize = qfo->strings_size;
|
pr.pr_stringsize = qfo->spaces[qfo_strings_space].data_size;
|
||||||
|
|
||||||
progs.numfunctions = qfo->num_funcs + 1;
|
progs.numfunctions = qfo->num_funcs + 1;
|
||||||
pr.pr_functions = calloc (progs.numfunctions, sizeof (dfunction_t));
|
pr.pr_functions = calloc (progs.numfunctions, sizeof (dfunction_t));
|
||||||
|
@ -335,14 +380,15 @@ convert_qfo (void)
|
||||||
qfo_func_t *func = qfo->funcs + i;
|
qfo_func_t *func = qfo->funcs + i;
|
||||||
dfunction_t df;
|
dfunction_t df;
|
||||||
|
|
||||||
df.first_statement = func->builtin ? -func->builtin : func->code;
|
memset (&df, 0, sizeof (df));
|
||||||
df.parm_start = qfo->data_size;
|
|
||||||
df.locals = func->locals_size;
|
df.first_statement = func->code;
|
||||||
|
df.parm_start = qfo->spaces[qfo_near_data_space].data_size;
|
||||||
|
df.locals = qfo->spaces[func->locals_space].data_size;
|
||||||
df.profile = 0;
|
df.profile = 0;
|
||||||
df.s_name = func->name;
|
df.s_name = func->name;
|
||||||
df.s_file = func->file;
|
df.s_file = func->file;
|
||||||
df.numparms = func->num_parms;
|
function_params (&df, func);
|
||||||
memcpy (df.parm_size, func->parm_size, sizeof (df.parm_size));
|
|
||||||
|
|
||||||
if (df.locals > num_locals)
|
if (df.locals > num_locals)
|
||||||
num_locals = df.locals;
|
num_locals = df.locals;
|
||||||
|
@ -354,12 +400,13 @@ convert_qfo (void)
|
||||||
pr.auxfunctions[i].source_line = func->line;
|
pr.auxfunctions[i].source_line = func->line;
|
||||||
pr.auxfunctions[i].line_info = func->line_info;
|
pr.auxfunctions[i].line_info = func->line_info;
|
||||||
pr.auxfunctions[i].local_defs = ld - pr.local_defs;
|
pr.auxfunctions[i].local_defs = ld - pr.local_defs;
|
||||||
pr.auxfunctions[i].num_locals = func->num_local_defs;
|
pr.auxfunctions[i].num_locals =
|
||||||
|
qfo->spaces[func->locals_space].num_defs;
|
||||||
|
|
||||||
for (j = 0; j < func->num_local_defs; j++) {
|
for (j = 0; j < qfo->spaces[func->locals_space].num_defs; j++) {
|
||||||
qfo_def_t *d = defs + func->local_defs + j;
|
qfo_def_t *d = qfo->spaces[func->locals_space].defs + j;
|
||||||
convert_def (d, ld++);
|
convert_def (d, ld++);
|
||||||
d->ofs += qfo->data_size;
|
ld->ofs += qfo->spaces[qfo_near_data_space].data_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,30 +421,37 @@ convert_qfo (void)
|
||||||
|
|
||||||
if (!(def->flags & QFOD_LOCAL) && def->name) {
|
if (!(def->flags & QFOD_LOCAL) && def->name) {
|
||||||
if (def->flags & QFOD_EXTERNAL) {
|
if (def->flags & QFOD_EXTERNAL) {
|
||||||
int size = pr_type_size[def->basic_type]; //FIXME struct etc
|
int size = get_type_size (def->type);
|
||||||
if (!size)
|
if (!size)
|
||||||
size = 1;
|
size = 1;
|
||||||
def->ofs += qfo->data_size + num_locals + num_externs;
|
def->offset += qfo->spaces[qfo_near_data_space].data_size
|
||||||
|
+ num_locals + num_externs;
|
||||||
num_externs += size;
|
num_externs += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_def (def, &ddef);
|
convert_def (def, &ddef);
|
||||||
pr.pr_globaldefs[progs.numglobaldefs++] = ddef;
|
pr.pr_globaldefs[progs.numglobaldefs++] = ddef;
|
||||||
if (ddef.type == ev_field) {
|
if (ddef.type == ev_field) {
|
||||||
ddef.type = get_auxtype (qfo->types + def->full_type);
|
ddef.type = get_type (def->type);
|
||||||
progs.entityfields += pr_type_size[ddef.type];
|
progs.entityfields += get_type_size (def->type);
|
||||||
ddef.ofs = qfo->data[ddef.ofs].integer_var;
|
ddef.ofs = QFO_INT (qfo, qfo_near_data_space, ddef.ofs);
|
||||||
pr.pr_fielddefs[progs.numfielddefs++] = ddef;
|
pr.pr_fielddefs[progs.numfielddefs++] = ddef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
progs.numglobals = qfo->data_size;
|
progs.numglobals = qfo->spaces[qfo_near_data_space].data_size;
|
||||||
pr.globals_size = progs.numglobals + num_locals + num_externs;
|
pr.globals_size = progs.numglobals + num_locals + num_externs;
|
||||||
|
pr.globals_size += qfo->spaces[qfo_far_data_space].data_size;
|
||||||
pr.pr_globals = calloc (pr.globals_size, sizeof (pr_type_t));
|
pr.pr_globals = calloc (pr.globals_size, sizeof (pr_type_t));
|
||||||
memcpy (pr.pr_globals, qfo->data, qfo->data_size * sizeof (pr_type_t));
|
memcpy (pr.pr_globals, qfo->spaces[qfo_near_data_space].d.data,
|
||||||
|
qfo->spaces[qfo_near_data_space].data_size * sizeof (pr_type_t));
|
||||||
|
memcpy (pr.pr_globals + progs.numglobals + num_locals + num_externs,
|
||||||
|
qfo->spaces[qfo_far_data_space].d.data,
|
||||||
|
qfo->spaces[qfo_far_data_space].data_size * sizeof (pr_type_t));
|
||||||
|
|
||||||
for (i = 0; i < qfo->num_defs; i++) {
|
for (i = 0; i < qfo->num_defs; i++) {
|
||||||
|
break;
|
||||||
qfo_def_t *def = defs + i;
|
qfo_def_t *def = defs + i;
|
||||||
|
|
||||||
for (j = 0; j < def->num_relocs; j++) {
|
for (j = 0; j < def->num_relocs; j++) {
|
||||||
|
@ -406,28 +460,28 @@ convert_qfo (void)
|
||||||
case rel_none:
|
case rel_none:
|
||||||
break;
|
break;
|
||||||
case rel_op_a_def:
|
case rel_op_a_def:
|
||||||
pr.pr_statements[reloc->ofs].a = def->ofs;
|
pr.pr_statements[reloc->offset].a = def->offset;
|
||||||
break;
|
break;
|
||||||
case rel_op_b_def:
|
case rel_op_b_def:
|
||||||
pr.pr_statements[reloc->ofs].b = def->ofs;
|
pr.pr_statements[reloc->offset].b = def->offset;
|
||||||
break;
|
break;
|
||||||
case rel_op_c_def:
|
case rel_op_c_def:
|
||||||
pr.pr_statements[reloc->ofs].c = def->ofs;
|
pr.pr_statements[reloc->offset].c = def->offset;
|
||||||
break;
|
break;
|
||||||
case rel_op_a_def_ofs:
|
case rel_op_a_def_ofs:
|
||||||
pr.pr_statements[reloc->ofs].a += def->ofs;
|
pr.pr_statements[reloc->offset].a += def->offset;
|
||||||
break;
|
break;
|
||||||
case rel_op_b_def_ofs:
|
case rel_op_b_def_ofs:
|
||||||
pr.pr_statements[reloc->ofs].b += def->ofs;
|
pr.pr_statements[reloc->offset].b += def->offset;
|
||||||
break;
|
break;
|
||||||
case rel_op_c_def_ofs:
|
case rel_op_c_def_ofs:
|
||||||
pr.pr_statements[reloc->ofs].c += def->ofs;
|
pr.pr_statements[reloc->offset].c += def->offset;
|
||||||
break;
|
break;
|
||||||
case rel_def_def:
|
case rel_def_def:
|
||||||
pr.pr_globals[reloc->ofs].integer_var = def->ofs;
|
pr.pr_globals[reloc->offset].integer_var = def->offset;
|
||||||
break;
|
break;
|
||||||
case rel_def_def_ofs:
|
case rel_def_def_ofs:
|
||||||
pr.pr_globals[reloc->ofs].integer_var += def->ofs;
|
pr.pr_globals[reloc->offset].integer_var += def->offset;
|
||||||
break;
|
break;
|
||||||
// these are relative and fixed up before the .qfo is written
|
// these are relative and fixed up before the .qfo is written
|
||||||
case rel_op_a_op:
|
case rel_op_a_op:
|
||||||
|
@ -455,7 +509,7 @@ convert_qfo (void)
|
||||||
pr.debug = &debug;
|
pr.debug = &debug;
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
static int
|
static int
|
||||||
load_progs (const char *name)
|
load_progs (const char *name)
|
||||||
{
|
{
|
||||||
|
@ -480,8 +534,7 @@ load_progs (const char *name)
|
||||||
if (!qfo)
|
if (!qfo)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// convert_qfo ();
|
convert_qfo ();
|
||||||
return 1;
|
|
||||||
} else {
|
} else {
|
||||||
pr.progs_name = name;
|
pr.progs_name = name;
|
||||||
PR_LoadProgsFile (&pr, file, size, 1, 0);
|
PR_LoadProgsFile (&pr, file, size, 1, 0);
|
||||||
|
|
Loading…
Reference in a new issue