#include "game_types.h"

/* Object_Copy @ 0x0801666C (real 164B) -- coroutine copy with resume-PC pools (clone family). Mirrors src/matched/Object_Copy.c. */
/* Coroutine-style copy: stores the opcode word 0x02000B38 then 0x02000B20 into
   p[0] across passes, with the resume-PC pool words (self addresses 0x080166AC /
   0x080166E4) 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_Copy(int *p)
{
    int *fr = Mem_GetStackFrame();
    Frame blk;
    p[0] = 0x02000B38;
    /* block 0, resumes at 0x080166AC */
    blk.link = fr[1];
    blk.zero = 0;
    blk.self = (int *)&blk;
    blk.resume = 0x080166AC;
    blk.sp = (int *)&blk;
    fr[1] = (int)&blk;
    p[0] = 0x02000B20;
    fr[1] = *(int *)fr[1];
    /* block 1, resumes at 0x080166E4 */
    blk.link = fr[1];
    blk.zero = 0;
    blk.self = (int *)&blk;
    blk.resume = 0x080166E4;
    blk.sp = (int *)&blk;
    fr[1] = (int)&blk + 24;
    p[0] = 0x02000B38;
    fr[1] = *(int *)fr[1];
    Mem_PopStack();
    Mem_PushStack();
    return p;
}
