Implements functioins from brqsort.c.

This commit is contained in:
OmniBlade 2019-10-31 13:06:50 +00:00
parent 8c0a8f4934
commit f865612c19
2 changed files with 128 additions and 18 deletions

View File

@ -5,16 +5,110 @@ char rscid[49];
// Offset: 8
// Size: 560
void BrQsort(void *basep, unsigned int nelems, unsigned int size, br_qsort_cbfn *comp) {
char *stack[40];
char **sp;
char *i;
char *j;
char *limit;
unsigned int thresh;
char *base;
unsigned int width;
void (*swap_func)(char*, char*, unsigned int);
void BrQsort(void *basep, unsigned int nelems, unsigned int size, br_qsort_cbfn comp) {
char *stack[40];
char **sp;
char *i;
char *j;
char *limit;
unsigned int thresh;
char *base;
unsigned int width;
void (*swap_func)(char*, char*, unsigned int);
width = size;
swap_func = swap_chars;
if (size == 4) { // Do we have exactly 1 32bit in worth of data at a time?
swap_func = swap_int_1;
} else if (!(size & 3)) { // Is our data divisible by 4 so can be swapped 32bit at a time?
width >>= 2;
swap_func = swap_ints;
}
base = (char *)basep;
thresh = 7 * size;
sp = stack;
for (limit = (char *)basep + size * nelems; ; limit = sp[1]) {
while (limit - base > thresh) {
swap_func(
&base[size * ((limit - base) / size >> 1)],
base,
width);
i = &base[size];
j = &limit[-size];
if (comp(&base[size], &limit[-size]) > 0) {
swap_func(i, j, width);
}
if (comp(base, j) > 0) {
swap_func(base, j, width);
}
if (comp(i, base) > 0) {
swap_func(i, base, width);
}
while (1) {
do
{
i += size;
} while (comp(i, base) < 0);
do
{
j -= size;
} while (comp(j, base) > 0);
if (i > j)
{
break;
}
swap_func(i, j, width);
}
swap_func(base, j, width);
if (j - base <= limit - i) {
*sp = i;
sp[1] = limit;
limit = j;
} else {
*sp = base;
sp[1] = j;
base = i;
}
sp += 2;
}
j = base;
for (i = &base[size]; i < limit; i += size)
{
while (comp(j, &j[size]) > 0) {
swap_func(j, &j[size], width);
if (j == base) {
break;
}
j -= size;
}
j = i;
}
if (stack == sp) {
break;
}
sp -= 2;
base = *sp;
}
}
// Offset: 579
@ -23,7 +117,13 @@ void BrQsort(void *basep, unsigned int nelems, unsigned int size, br_qsort_cbfn
// EDX: b
// EBX: nbytes
void swap_chars(char *a, char *b, unsigned int nbytes) {
char tmp;
char tmp;
do {
tmp = *a;
*a++ = *b;
*b++ = tmp;
} while(--nbytes);
}
// Offset: 670
@ -32,9 +132,15 @@ void swap_chars(char *a, char *b, unsigned int nbytes) {
// EDX: bp
// EBX: nints
void swap_ints(char *ap, char *bp, unsigned int nints) {
int *a;
int *b;
int tmp;
int *a = (int *)ap;
int *b = (int *)bp;
int tmp;
do {
tmp = *a;
*a++ = *b;
*b++ = tmp;
} while(--nints);
}
// Offset: 776
@ -43,8 +149,12 @@ void swap_ints(char *ap, char *bp, unsigned int nints) {
// EDX: bp
// EBX: nints
void swap_int_1(char *ap, char *bp, unsigned int nints) {
int *a;
int *b;
int tmp;
int *a = (int *)ap;
int *b = (int *)bp;
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}

View File

@ -2,7 +2,7 @@
#include "br_types.h"
// Offset: 8
// Size: 560
void BrQsort(void *basep, unsigned int nelems, unsigned int size, br_qsort_cbfn *comp);
void BrQsort(void *basep, unsigned int nelems, unsigned int size, br_qsort_cbfn comp);
// Offset: 579
// Size: 81