It is pretty close. Only the issue with variadic functions has a different reason. Here's our source for wait(), somewhat simplified:

Code:
void CS_Wait(fixed time)
{
	static byte *local_stack,*local_offs;
	_asm
	{
		mov local_offs,ebx
		mov local_stack,ebp		
	}
	time -= 1;

// retrieve function name, stack size, and start address information
	byte *stack = local_stack+3*4; 
	byte *code = (byte*)((DWORD*)local_stack)[1]; // current return address from the stack
	char *name;		// of the function
	void *codestart;	// of the function
	long stacksize;		// local stack size
	long parasize;		// function parameter size
	CS_GetFunctionInfo(code,&name,&stacksize,&parasize,&codestart);
	CS_SchedulerInsert(code,stack,stacksize,code-local_offs,time,codestart,name);

// return to the caller
	_asm
	{
		mov esp,stack
		add esp,stacksize;	// skip local vars
		pop edi			// pop original registers
		pop esi  
		pop ebx  
		pop ebp
		ret			// back to caller
	}
}