[gamecode] Use fuzzy bsearch to find defs by address

The idea is to find th def that contains the address. Had to write my
own bsearch (well... lifted from wikipedia) because libc's is exact. The
defs are assumed to be sorted (which qfcc now ensures when it writes
progs and sym files).
This commit is contained in:
Bill Currie 2020-03-15 02:48:13 +09:00
parent 968de155a1
commit 3d62a7f253
2 changed files with 26 additions and 18 deletions

View file

@ -321,6 +321,8 @@ void ED_EntityParseFunction (progs_t *pr);
*/
///@{
pr_def_t *PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset)
__attribute__((pure));
pr_def_t *PR_FieldAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure));
pr_def_t *PR_GlobalAtOfs (progs_t *pr, pointer_t ofs) __attribute__((pure));

View file

@ -43,32 +43,38 @@
static const char param_str[] = ".param_0";
pr_def_t *
PR_SearchDefs (pr_def_t *defs, unsigned num_defs, pointer_t offset)
{
// fuzzy bsearh
unsigned left = 0;
unsigned right = num_defs - 1;
unsigned mid;
while (left != right) {
mid = (left + right + 1) / 2;
if (defs[mid].ofs > offset) {
right = mid - 1;
} else {
left = mid;
}
}
if (defs[left].ofs <= offset) {
return defs + left;
}
return 0;
}
pr_def_t *
PR_GlobalAtOfs (progs_t * pr, pointer_t ofs)
{
pr_def_t *def;
pr_uint_t i;
for (i = 0; i < pr->progs->numglobaldefs; i++) {
def = &pr->pr_globaldefs[i];
if (def->ofs == ofs)
return def;
}
return NULL;
return PR_SearchDefs (pr->pr_globaldefs, pr->progs->numglobaldefs, ofs);
}
VISIBLE pr_def_t *
PR_FieldAtOfs (progs_t * pr, pointer_t ofs)
{
pr_def_t *def;
pr_uint_t i;
for (i = 0; i < pr->progs->numfielddefs; i++) {
def = &pr->pr_fielddefs[i];
if (def->ofs == ofs)
return def;
}
return NULL;
return PR_SearchDefs (pr->pr_fielddefs, pr->progs->numfielddefs, ofs);
}
VISIBLE pr_def_t *