#help_index "TextBase Layer;Char/TextBase Layer" #help_file "::/Doc/TextBase" asm { //************************************ _TEXT_CHAR:: //Bool TextChar(CTask *task,Bool allow_border=FALSE,I64 x,I64 y,I64 d); //Must be called 60fps in Fs->draw_it() callback. PUSH RBP MOV RBP, RSP MOV RCX, U64 SF_ARG1[RBP] MOV RBX, U64 CTask.scroll_x[RCX] SAR RBX, 3 ADD RBX, U64 SF_ARG3[RBP] MOV RAX, U64 CTask.scroll_y[RCX] SAR RAX, 3 ADD RAX, U64 SF_ARG4[RBP] TEST U8 SF_ARG2[RBP], 0xFF JNZ @@10 //Border not allowed TEST RBX, RBX //Check X JS @@05 ADD RBX, U64 CTask.win_left[RCX] CMP RBX, U64 CTask.win_right[RCX] JG @@05 TEST RBX, RBX JS @@05 CMP RBX, TEXT_COLS JGE @@05 TEST RAX, RAX //Check Y JS @@05 ADD RAX, U64 CTask.win_top[RCX] CMP RAX, U64 CTask.win_bottom[RCX] JG @@05 TEST RAX, RAX JS @@05 CMP RAX, TEXT_ROWS JGE @@05 JMP @@15 @@05: XOR RAX, RAX //return FALSE POP RBP RET1 40 //Border allowed @@10: MOV RDX, -1 //Check X CMP RBX, RDX JL @@05 ADD RBX, U64 CTask.win_left[RCX] MOV RDX, U64 CTask.win_right[RCX] INC RDX CMP RBX, RDX JG @@05 TEST RBX, RBX JS @@05 CMP RBX, TEXT_COLS JGE @@05 MOV RDX, -1 //Check Y CMP RAX, RDX JL @@05 ADD RAX, U64 CTask.win_top[RCX] MOV RDX, U64 CTask.win_bottom[RCX] INC RDX CMP RAX, RDX JG @@05 TEST RAX, RAX JS @@05 CMP RAX, TEXT_ROWS JGE @@05 @@15: IMUL2 RAX, TEXT_COLS ADD RBX, RAX SHL RBX, 2 ADD RBX, U64 [&gr.text_base] MOV RAX, U64 SF_ARG5[RBP] MOV U32 [RBX], EAX MOV RAX, TRUE POP RBP RET1 40 //************************************ _TEXT_LEN_STR:: //Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,I64 attr,U8 *s) //Must be called 60fps in Fs->draw_it() callback. PUSH RBP MOV RBP, RSP PUSH RSI PUSH RDI MOV RBX, U64 SF_ARG1[RBP] MOV RSI, U64 SF_ARG6[RBP] MOV RDI, U64 CTask.scroll_x[RBX] SAR RDI, 3 ADD RDI, U64 SF_ARG2[RBP] MOV RCX, U64 SF_ARG4[RBP] TEST RDI, RDI JNS @@05 ADD RCX, RDI SUB RSI, RDI XOR RDI, RDI @@05: ADD RDI, U64 CTask.win_left[RBX] MOV RDX, RCX ADD RDX, RDI DEC RDX CMP RDX, U64 CTask.win_right[RBX] JLE @@10 MOV RAX, RDX SUB RAX, U64 CTask.win_right[RBX] SUB RDX, RAX SUB RCX, RAX @@10: TEST RDI, RDI JNS @@15 ADD RCX, RDI SUB RSI, RDI XOR RDI, RDI @@15: INC RDX SUB RDX, TEXT_COLS JLE @@20 SUB RCX, RDX @@20: CMP RCX, 1 JL @@30 MOV RAX, U64 CTask.scroll_y[RBX] SAR RAX, 3 ADD RAX, U64 SF_ARG3[RBP] TEST RAX, RAX JS @@30 ADD RAX, U64 CTask.win_top[RBX] CMP RAX, U64 CTask.win_bottom[RBX] JG @@30 TEST RAX, RAX JS @@30 CMP RAX, TEXT_ROWS JGE @@30 IMUL2 RAX, TEXT_COLS ADD RDI, RAX SHL RDI, 2 ADD RDI, U64 [&gr.text_base] MOV RAX, U64 SF_ARG5[RBP] @@25: LODSB STOSD DEC RCX JNZ @@25 POP RDI POP RSI MOV RAX, TRUE POP RBP RET1 48 @@30: POP RDI POP RSI XOR RAX, RAX POP RBP RET1 48 //************************************ _TEXT_LEN_ATTR_STR:: //Bool TextLenAttrStr(CTask *task,I64 x,I64 y,I64 len,U32 *_attr) //Must be called 60fps in Fs->draw_it() callback. PUSH RBP MOV RBP, RSP PUSH RSI PUSH RDI MOV RBX, U64 SF_ARG1[RBP] MOV RSI, U64 SF_ARG5[RBP] MOV RDI, U64 CTask.scroll_x[RBX] SAR RDI, 3 ADD RDI, U64 SF_ARG2[RBP] MOV RCX, U64 SF_ARG4[RBP] TEST RDI, RDI JNS @@05 ADD RCX, RDI SHL RDI, 2 SUB RSI, RDI XOR RDI, RDI @@05: ADD RDI, U64 CTask.win_left[RBX] MOV RDX, RCX ADD RDX, RDI DEC RDX CMP RDX, U64 CTask.win_right[RBX] JLE @@10 MOV RAX, RDX SUB RAX, U64 CTask.win_right[RBX] SUB RDX, RAX SUB RCX, RAX @@10: TEST RDI, RDI JNS @@15 ADD RCX, RDI SHL RDI, 2 SUB RSI, RDI XOR RDI, RDI @@15: INC RDX SUB RDX, TEXT_COLS JLE @@20 SUB RCX, RDX @@20: CMP RCX, 1 JL @@30 MOV RAX, U64 CTask.scroll_y[RBX] SAR RAX, 3 ADD RAX, U64 SF_ARG3[RBP] TEST RAX, RAX JS @@30 ADD RAX, U64 CTask.win_top[RBX] CMP RAX, U64 CTask.win_bottom[RBX] JG @@30 TEST RAX, RAX JS @@30 CMP RAX, TEXT_ROWS JGE @@30 IMUL2 RAX, TEXT_COLS ADD RDI, RAX SHL RDI, 2 ADD RDI, U64 [&gr.text_base] @@25: MOVSD DEC RCX JNZ @@25 POP RDI POP RSI MOV RAX, TRUE POP RBP RET1 40 @@30: POP RDI POP RSI XOR RAX, RAX POP RBP RET1 40 //************************************ _TEXT_LEN_ATTR:://Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,I64 attr) //Must be called 60fps in Fs->draw_it() callback. PUSH RBP MOV RBP, RSP PUSH RSI PUSH RDI MOV RBX, U64 SF_ARG1[RBP] MOV RDI, U64 CTask.scroll_x[RBX] SAR RDI, 3 ADD RDI, U64 SF_ARG2[RBP] MOV RCX, U64 SF_ARG4[RBP] TEST RDI, RDI JNS @@05 ADD RCX, RDI XOR RDI, RDI @@05: ADD RDI, U64 CTask.win_left[RBX] MOV RDX, RCX ADD RDX, RDI DEC RDX CMP RDX, U64 CTask.win_right[RBX] JLE @@10 MOV RAX, RDX SUB RAX, U64 CTask.win_right[RBX] SUB RDX, RAX SUB RCX, RAX @@10: TEST RDI, RDI JNS @@15 ADD RCX, RDI XOR RDI, RDI @@15: INC RDX SUB RDX, TEXT_COLS JLE @@20 SUB RCX, RDX @@20: CMP RCX, 1 JL @@35 MOV RAX, U64 CTask.scroll_y[RBX] SAR RAX, 3 ADD RAX, U64 SF_ARG3[RBP] TEST RAX, RAX JS @@35 ADD RAX, U64 CTask.win_top[RBX] CMP RAX, U64 CTask.win_bottom[RBX] JG @@35 TEST RAX, RAX JS @@35 CMP RAX, TEXT_ROWS JGE @@35 IMUL2 RAX, TEXT_COLS ADD RDI, RAX SHL RDI, 2 ADD RDI, U64 [&gr.text_base] MOV RBX, U64 SF_ARG5[RBP] MOV RSI, RDI @@25: LODSD TEST AL, AL JNZ @@30 MOV RAX, RBX STOSD DEC RCX JNZ @@25 @@30: POP RDI POP RSI MOV RAX, TRUE POP RBP RET1 40 @@35: POP RDI POP RSI XOR RAX, RAX POP RBP RET1 40 } public _extern _TEXT_CHAR Bool TextChar(CTask *task, Bool allow_border=FALSE, I64 x, I64 y, I64 d); //Plot char. 60fps in Fs->draw_it() callback. public _extern _TEXT_LEN_STR Bool TextLenStr(CTask *task, I64 x, I64 y, I64 len, I64 attr, U8 *s); //Plot str with len. 60fps in Fs->draw_it() callback. public _extern _TEXT_LEN_ATTR_STR Bool TextLenAttrStr(CTask *task, I64 x, I64 y, I64 len, U32 *_attr); //Plot attr str with len. 60fps in Fs->draw_it() callback. public _extern _TEXT_LEN_ATTR Bool TextLenAttr(CTask *task, I64 x, I64 y, I64 len, I64 attr); //Plot attrs with len. 60fps in Fs->draw_it() callback. public U0 TextPrint(CTask *task, I64 x, I64 y, I64 attr, U8 *format, ...) {//Plot chars. 60fps in Fs->draw_it() callback. //You probably want GrPrint() or just Print(). U8 *buf = StrPrintJoin(NULL, format, argc, argv); TextLenStr(task, x, y, StrLen(buf), attr<<8, buf); Free(buf); } public U0 TextBorder(CTask *task=NULL, I64 l, I64 r, I64 t, I64 b, I64 attr, Bool solid) {//Plot border square. 60fps in Fs->draw_it() callback. //Draws window borders or DolDoc text button borders. //Set task=sys_winmgr_task for no clipping. I64 i; if (!task) task = Fs; attr <<= 8; TextChar(task,, l - 1, t - 1, text.border_chars[6 + solid] + attr); TextChar(task,, r + 1, t - 1, text.border_chars[8 + solid] + attr); TextChar(task,, l - 1, b + 1, text.border_chars[10 + solid] + attr); TextChar(task,, r + 1, b + 1, text.border_chars[12 + solid] + attr); for (i = l; i <= r; i++) { TextChar(task,, i, t - 1, text.border_chars[2 + solid] + attr); TextChar(task,, i, b + 1, text.border_chars[2 + solid] + attr); } for (i = t; i <= b; i++) { TextChar(task,, l - 1, i, text.border_chars[4 + solid] + attr); TextChar(task,, r + 1, i, text.border_chars[4 + solid] + attr); } } public U0 TextRect(I64 l, I64 r, I64 t, I64 b, I64 d) {//Fill text rect. 60fps in Fs->draw_it() callback. I64 y, w; if (l > r || t > b) return; if (t < 0) t = 0; if (b >= TEXT_ROWS) b = TEXT_ROWS - 1; if (l < 0) l = 0; if (r >= TEXT_COLS) r = TEXT_COLS - 1; if (w = r - l + 1) for (y = t; y <= b; y++) MemSetU32(gr.text_base(U8 *) + (y * TEXT_COLS + l) * sizeof(U32), d, w); }