#include "game_types.h"

/* GameState_Setup @ 0x08007290 (real 146B) -- teardown/reap chain with sqrt walk. Mirrors src/matched/GameState_Setup.c. */
/* Animates/frees the head blocks, walks the 0x2284 chain down by 4 calling
   Math_Sqrt per entry until s+516, clears the object array, runs an empty
   countdown, probes IsInf, and frees children when flag bit 0 is set. */
extern void Collectible_Animate(int *p, int mode);
extern void Render_DrawSpriteAt(int *p, int mode);
extern void Player_FreeState(int *p, int mode);
extern int Math_Sqrt(int a, int b);
extern void ObjectArray_ClearWithFree(int *p, int mode);
extern int Float_IsInf(int a, int b);
extern void Mem_FreeAndChildren(int *p);

int GameState_Setup(int *s, int f)
{
    int *r4 = (int *)((char *)s + 0x2284);
    int *end = (int *)((char *)s + 516);
    int r;
    Collectible_Animate((int *)((char *)s + 9344), 2);
    Render_DrawSpriteAt((int *)((char *)s + 0x22F4), 2);
    Player_FreeState(r4, 2);
    if (end != 0 && end != r4) {
        for (;;) {
            int *e;
            int v;
            r4 = (int *)((char *)r4 - 4);
            e = (int *)r4[14];
            v = *(short *)((char *)e + 8) + (int)r4;
            Math_Sqrt(v, (int)e[3]);
            if (r4 == end)
                break;
        }
    }
    ObjectArray_ClearWithFree((int *)((char *)s + 416), 2);
    {
        int *dst = (int *)((char *)s + 140);
        int *k = (int *)((char *)s + 396);
        if (dst != 0 && dst != k) {
            do {
                k = (int *)((char *)k - 16);
            } while (k != dst);
        }
    }
    r = Float_IsInf((int)((char *)s + 88), 2);
    if ((f & 1) != 0)
        Mem_FreeAndChildren(s);
    return r;
}
