#include "game_types.h"

/* Object_Copy4 @ 0x08017414 (real 164B) -- coroutine copy with resume-PC pools (clone family). Mirrors src/matched/Object_Copy4.c. */
/* Coroutine-style copy: stores the opcode word 0x02000B38 then 0x02000BC8 into
   p[0] across passes, with the resume-PC pool words (self addresses 0x08017454 /
   0x0801748C) doubling as code after the bl returns. Chains GetStackFrame ->
   PopStack -> PushStack. Siblings differ only in pools. Returns p. */
extern int *Mem_GetStackFrame(void);
extern void Mem_PopStack(void);
extern void Mem_PushStack(void);

typedef struct {
    int link;
    int zero;
    int *self;
    int resume;
    int *sp;
} Frame;

int *Object_Copy4(int *p)
{
    int *fr = Mem_GetStackFrame();
    Frame blk;
    p[0] = 0x02000B38;
    /* block 0, resumes at 0x08017454 */
    blk.link = fr[1];
    blk.zero = 0;
    blk.self = (int *)&blk;
    blk.resume = 0x08017454;
    blk.sp = (int *)&blk;
    fr[1] = (int)&blk;
    p[0] = 0x02000BC8;
    fr[1] = *(int *)fr[1];
    /* block 1, resumes at 0x0801748C */
    blk.link = fr[1];
    blk.zero = 0;
    blk.self = (int *)&blk;
    blk.resume = 0x0801748C;
    blk.sp = (int *)&blk;
    fr[1] = (int)&blk + 24;
    p[0] = 0x02000B38;
    fr[1] = *(int *)fr[1];
    Mem_PopStack();
    Mem_PushStack();
    return p;
}
