From f865612c19d55a62d8b787a3728ff05020016041 Mon Sep 17 00:00:00 2001 From: OmniBlade Date: Thu, 31 Oct 2019 13:06:50 +0000 Subject: [PATCH] Implements functioins from brqsort.c. --- src/BRSRC13/CORE/FW/brqsort.c | 144 ++++++++++++++++++++++++++++++---- src/BRSRC13/CORE/FW/brqsort.h | 2 +- 2 files changed, 128 insertions(+), 18 deletions(-) diff --git a/src/BRSRC13/CORE/FW/brqsort.c b/src/BRSRC13/CORE/FW/brqsort.c index d1d0f9bf..37db395f 100644 --- a/src/BRSRC13/CORE/FW/brqsort.c +++ b/src/BRSRC13/CORE/FW/brqsort.c @@ -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; } diff --git a/src/BRSRC13/CORE/FW/brqsort.h b/src/BRSRC13/CORE/FW/brqsort.h index 69ae5aa2..b41ef3c0 100644 --- a/src/BRSRC13/CORE/FW/brqsort.h +++ b/src/BRSRC13/CORE/FW/brqsort.h @@ -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