Skip to content

Instantly share code, notes, and snippets.

@szapp
Created September 7, 2025 14:38
Show Gist options
  • Select an option

  • Save szapp/b8fb3a0d19b77c7a4240b954eb692d2b to your computer and use it in GitHub Desktop.

Select an option

Save szapp/b8fb3a0d19b77c7a4240b954eb692d2b to your computer and use it in GitHub Desktop.
String formatting with %-expansion in Daedalus.
/*
* String formatting, given %s (string), %i (integer), and %f (float). The variable number of arguments are expected to
* be pushed on the stack. No error handling: If the number or order of arguments does not match, Gothic will crash.
*
* Example usage:
*
* MEM_PushStringParam("Mud");
* MEM_PushIntParam(24);
* castToIntf(1.2);
* out = STR_Format("Hello %s, give me %i ore! That is a %f % percent increase.");
*
*/
func string STR_Format(var string fmt) {
var int skip; skip = 1;
if (CALL_Begin(nextPos)) {
const int zSTRING__SearchRev = 4618320; //0x467850
const int nextPos = 0;
const int pos = 0;
const int percentPtr = 0; percentPtr = _@s("%");
const int formatPtr = 0; formatPtr = _@s(fmt);
CALL_IntParam(_@(skip));
CALL_PtrParam(_@(percentPtr));
CALL_PutRetValTo(_@(pos));
CALL__thiscall(_@(formatPtr), zSTRING__SearchRev);
nextPos = Call_End();
};
if (!replace) {
const int str__replace = 4619456; //0x467CC0
const int replace = 0;
const int neg1 = -1;
const int zero = 0;
const int two = 2;
const int rplCPtr = 0; rplCPtr = _@s(rpl)+4;
const int formatCPtr = 0; formatCPtr = _@s(fmt)+4;
var string rpl;
CALL_Open();
CALL_IntParam(_@(neg1));
CALL_IntParam(_@(zero));
CALL_PtrParam(_@(rplCPtr));
CALL_IntParam(_@(two));
CALL_IntParam(_@(pos));
CALL__thiscall(_@(formatCPtr), str__replace);
replace = CALL_Close();
};
var zString fmtStr; fmtStr = _^(_@s(fmt));
while(pos != -1);
var int type; type = MEM_ReadByte(fmtStr.ptr+pos+1);
if (type == 115) { //s
rpl = MEM_PopStringResult();
} else if (type == 105) { //i
rpl = IntToString(MEM_PopIntResult());
} else if (type == 102) { //f
rpl = toStringf(MEM_PopIntResult());
} else {
skip += 1;
ASM_Run(nextPos);
continue;
};
ASM_Run(replace);
ASM_Run(nextPos);
end;
return fmt;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment