01.10.2013, 10:23
Did it, still crashing. Also wierd thing: when i paste this at the end of gamemode:
The compiler don't crash and the sprintf function is working fine. Also tried to include strlib at the end of gamemode but i didnt worked.
EDIT: redownloaded whole include again, and it's working! Thank you Slice for this include and help
pawn Код:
#if !defined STRLIB_USE_FORMATEX
#if defined __fmt_funcinc
#if !defined FormatSpecifier
#error Please include formatex before strlib.
#endif
#define STRLIB_USE_FORMATEX true
#else
#define STRLIB_USE_FORMATEX false
#endif
#endif
stock sprintf(const fmat[], {Float, _}:...) {
static output[200], frm_header[3], heap;
const output_size = sizeof(output);
if (ispacked(fmat)) {
heap = CopyArgumentToHeap(0);
} else {
heap = 0;
}{}
// Store current frame header
#emit LCTRL 5
#emit CONST.alt frm_header
#emit MOVS 12
// Change the stack pointer to FRM + 12
#emit ADD.C 12 // pri is FRM (see above)
#emit SCTRL 4
// Push sizeof(output)
#emit PUSH.C output_size
// Push output
#emit PUSH.C output
// Push the argument count
#emit LOAD.S.pri 8
#emit ADD.C 8
#emit PUSH.pri
#if !STRLIB_USE_FORMATEX
const formatex = 0; // Dummy used to avoid "unknown symbol" error
goto do_sysreq;
#endif
// Call formatex (unless this was skipped above)
#emit LCTRL 6
#emit ADD.C 36
#emit PUSH.pri
#emit CONST.pri formatex
#emit SCTRL 6
#if !STRLIB_USE_FORMATEX
do_sysreq:
#endif
// Call format (unless formatex was called, in which case this is skipped)
#emit SYSREQ.C format
// Restore the stack pointer to FRM
#emit LCTRL 5
#emit SCTRL 4
// Copy back the frame header
#emit MOVE.alt
#emit CONST.pri frm_header
#emit MOVS 12
// Restore heap if needed
if (heap) {
RestoreHeapToAddress(heap);
}{}
// IMPORTANT: Fix compiler bug (returning strings in variadic functions)
#emit LOAD.S.pri 8
#emit ADD.C 12
#emit MOVE.alt
#emit LCTRL 5
#emit ADD
#emit LOAD.I
#emit STOR.S.pri 20 // 16 + (static_args * 4)
return output;
// It is actually used, just not by its symbol name
#pragma unused fmat
}
static stock CopyArgumentToHeap(arg, bool:pack = false, const argptr[] = "") {
new arg_address, address;
#emit LOAD.S.pri 0
#emit ADD.C 12
#emit LOAD.S.alt arg
#emit SHL.C.alt 2
#emit ADD
#emit LOAD.I
#emit STOR.S.pri arg_address
#emit STOR.S.pri argptr
if (pack) {
new bytes = ((strlen(argptr) + 1 + 3) / 4) * 4;
#emit LCTRL 2
#emit STOR.S.pri address
#emit LOAD.S.alt bytes
#emit ADD
#emit SCTRL 2
//strpack(dest[], const source[], maxlength = sizeof dest)
#emit LOAD.S.pri bytes
#emit SHR.C.pri 2
#emit PUSH.pri
#emit PUSH.S arg_address
#emit PUSH.S address
#emit PUSH.C 12
#emit SYSREQ.C strpack
#emit STACK 16
} else {
new bytes = (strlen(argptr) + 1) * 4;
#emit LCTRL 2
#emit STOR.S.pri address
#emit LOAD.S.alt bytes
#emit ADD
#emit SCTRL 2
//strunpack(dest[], const source[], maxlength = sizeof dest)
#emit LOAD.S.pri bytes
#emit SHR.C.pri 2
#emit PUSH.pri
#emit PUSH.S arg_address
#emit PUSH.S address
#emit PUSH.C 12
#emit SYSREQ.C strunpack
#emit STACK 16
}
#emit LOAD.S.pri 0
#emit ADD.C 12
#emit LOAD.S.alt arg
#emit SHL.C.alt 2
#emit ADD
#emit MOVE.alt
#emit LOAD.S.pri address
#emit STOR.I
return address;
}
static stock RestoreHeapToAddress(address) {
#emit LOAD.S.pri address
#emit SCTRL 2
}
EDIT: redownloaded whole include again, and it's working! Thank you Slice for this include and help