WIP: apps/ircc: fix text formatting issues (#376) #392
No files matched your search
@@ -158,12 +158,8 @@ skip_parameter:
|
||||
cmp al, ':'
|
||||
jne .part1
|
||||
|
||||
; Skip all trailing spaces
|
||||
; esi already points to first char after ':', preserve leading spaces
|
||||
.part3:
|
||||
lodsb
|
||||
cmp al, ' '
|
||||
je .part3
|
||||
dec esi
|
||||
ret
|
||||
|
||||
; Now, skip all trailing spaces and first semicolon
|
||||
|
||||
@@ -33,10 +33,17 @@ text_insert_newlines: ; esi = ASCIIZ string
|
||||
je .soft_nl
|
||||
cmp al, 10 ; it's a newline, continue onto the next line
|
||||
je .newline
|
||||
cmp al, 3 ; mIRC color escape - skip args without counting width
|
||||
je .skip_color
|
||||
cmp al, 0x20 ; other control char (bold, italic, reset, etc.) - skip without counting
|
||||
jb .next_byte
|
||||
and al, 0xc0 ; Is it a multi byte UTF8 char?
|
||||
cmp al, 0x80
|
||||
je .next_byte
|
||||
jmp .more
|
||||
.skip_color:
|
||||
call skip_mirc_color_args ; consume the same byte span as renderer's dec_to_esi
|
||||
jmp .next_byte
|
||||
.newline:
|
||||
inc edx
|
||||
jmp .next_line
|
||||
@@ -279,11 +286,19 @@ draw_channel_text:
|
||||
je @f
|
||||
cmp al, 10 ; hard newline
|
||||
je @f
|
||||
cmp al, 15 ; 0x0F reset char: default color applies from here forward
|
||||
je @f
|
||||
cmp al, 3 ; mIRC escape code
|
||||
jne @b
|
||||
|
||||
cld
|
||||
lea edx, [esi+2]
|
||||
; bare \x03 (no digit) = color reset, use default
|
||||
movzx eax, byte[edx]
|
||||
sub al, '0'
|
||||
cmp al, 9
|
||||
ja @f ; ecx already holds default here (set above),
|
||||
; no explicit reset needed in this branch
|
||||
call dec_to_esi
|
||||
jz @f
|
||||
mov ecx, [irc_colors + 4*esi]
|
||||
@@ -328,9 +343,21 @@ draw_channel_text:
|
||||
cmp byte[edx], 10
|
||||
je .newline_hard
|
||||
|
||||
cmp byte[edx], 15 ; 0x0F: reset all formatting to default
|
||||
jne .check_colors
|
||||
inc edx
|
||||
mov ecx, [colors.work_text]
|
||||
or ecx, 0x30000000
|
||||
jmp .line
|
||||
.check_colors:
|
||||
cmp byte[edx], 3 ; escape code for mIRC colors
|
||||
jne .no_colors
|
||||
inc edx
|
||||
; bare \x03 with no digit = reset color to default
|
||||
movzx eax, byte[edx]
|
||||
sub al, '0'
|
||||
cmp al, 9
|
||||
ja .color_reset
|
||||
call dec_to_esi
|
||||
jz .line
|
||||
mov ecx, [irc_colors + 4*esi]
|
||||
@@ -343,6 +370,13 @@ draw_channel_text:
|
||||
jz .line
|
||||
mov edi, [irc_colors + 4*esi]
|
||||
or ecx, 0x40000000
|
||||
jmp .line ; skip .no_colors fallthrough; pre-PR fell
|
||||
; through and inc'd edx, eating first char
|
||||
; of the message after \x03N,N
|
||||
.color_reset:
|
||||
mov ecx, [colors.work_text]
|
||||
or ecx, 0x30000000
|
||||
jmp .line
|
||||
.no_colors:
|
||||
|
||||
; Some non-printable, just skip it
|
||||
@@ -434,6 +468,68 @@ dec_to_esi:
|
||||
|
||||
|
||||
|
||||
;----------------------------------
|
||||
; Skip mIRC color args after \x03 (forward direction only).
|
||||
;
|
||||
; Consumes the exact same byte span as the dec_to_esi-based parsing used by
|
||||
; draw_channel_text, so width calculation in text_insert_newlines/text_nextline
|
||||
; stays in sync with what the renderer actually draws:
|
||||
;
|
||||
; no digit after \x03 : consume 0 bytes (renderer takes .color_reset)
|
||||
; N fg digits, value 0..15 : consume N, then optionally +1+M for ',bg'
|
||||
; (fg=0 is mIRC color 0 = white, fully valid)
|
||||
; N fg digits, value >= 16 : consume N (renderer's .fail path resets esi
|
||||
; to 0 and trips jz; ',bg' left untouched)
|
||||
;
|
||||
; "No digits" is distinguished from "value 0" by remembering the entry esi on
|
||||
; the stack and comparing after the fg loop. This is what dec_to_esi cannot do
|
||||
; (it reuses esi=0 for both fail and value-0), but the renderer side gets away
|
||||
; with it because the recent pre-check ('cmp al, 9; ja .color_reset') already
|
||||
; filtered out the no-digit case before the call.
|
||||
;
|
||||
; IN: esi = ptr to first byte after \x03
|
||||
; OUT: esi = ptr to first byte past the consumed color args
|
||||
; ebx preserved (callers track state in it); eax clobbered (matches
|
||||
; dec_to_esi convention; callers reload AL via lodsb on return)
|
||||
;----------------------------------
|
||||
skip_mirc_color_args:
|
||||
|
||||
push ebx
|
||||
push esi ; remember entry esi to detect "no digits"
|
||||
xor ebx, ebx ; fg value accumulator (mirrors dec_to_esi's esi)
|
||||
.fg_loop:
|
||||
movzx eax, byte[esi]
|
||||
sub al, '0'
|
||||
jb .fg_done
|
||||
cmp al, 9
|
||||
ja .fg_done
|
||||
inc esi
|
||||
lea ebx, [ebx*4 + ebx] ; ebx * 5
|
||||
lea ebx, [ebx*2 + eax] ; ebx * 10 + eax
|
||||
jmp .fg_loop
|
||||
.fg_done:
|
||||
cmp [esp], esi ; esi unchanged? → no fg digits, bare \x03
|
||||
je .done ; (renderer took .color_reset, no ',bg')
|
||||
cmp ebx, 16 ; fg out of range → renderer's .fail path,
|
||||
jae .done ; ',bg' also left unconsumed
|
||||
cmp byte[esi], ','
|
||||
jne .done
|
||||
inc esi ; consume ','
|
||||
.bg_loop:
|
||||
movzx eax, byte[esi]
|
||||
sub al, '0'
|
||||
jb .done
|
||||
cmp al, 9
|
||||
ja .done
|
||||
inc esi ; bg digits always consumed regardless of value
|
||||
jmp .bg_loop
|
||||
.done:
|
||||
pop eax ; discard the saved entry esi
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
|
||||
|
||||
if TIMESTAMP
|
||||
print_timestamp:
|
||||
|
||||
|
||||
@@ -226,11 +226,11 @@ window_open:
|
||||
.got_it:
|
||||
lodsb
|
||||
cmp al, ' '
|
||||
je .got_it
|
||||
je .got_it ; skip spaces before the colon
|
||||
cmp al, ':'
|
||||
je .got_it
|
||||
dec esi
|
||||
|
||||
je .set_window ; found colon, stop here - preserve leading spaces of message
|
||||
dec esi ; not space or colon, put it back
|
||||
.set_window:
|
||||
mov [window_print], ebx
|
||||
ret
|
||||
|
||||
|
||||
Reference in new issue
Block a user