forked from KolibriOS/kolibrios
apps/ircc: refactor color-arg skipping, fix width/render desync
- Factor duplicated .skip_color from text_insert_newlines and text_nextline into a shared skip_mirc_color_args matching the renderer's dec_to_esi byte span. - Guard text_nextline backward scans (DF check) so forward-parsing \x03 args doesn't corrupt esi during scroll-up. - Document the silent jmp .line that stops .no_colors from eating the byte after \x03N,N. - Document the .color_reset branch for bare \x03.
This commit is contained in:
@@ -42,33 +42,7 @@ text_insert_newlines: ; esi = ASCIIZ string
|
||||
je .next_byte
|
||||
jmp .more
|
||||
.skip_color:
|
||||
lodsb ; optional fg color digit(s)
|
||||
cmp al, '0'
|
||||
jb .skip_color_done
|
||||
cmp al, '9'
|
||||
ja .skip_color_done
|
||||
lodsb ; optional 2nd fg digit
|
||||
cmp al, '0'
|
||||
jb .skip_color_comma
|
||||
cmp al, '9'
|
||||
ja .skip_color_comma
|
||||
lodsb ; char after 2 fg digits
|
||||
.skip_color_comma:
|
||||
cmp al, ',' ; optional background color?
|
||||
jne .skip_color_done
|
||||
lodsb ; optional bg color digit(s)
|
||||
cmp al, '0'
|
||||
jb .skip_color_done
|
||||
cmp al, '9'
|
||||
ja .skip_color_done
|
||||
lodsb ; optional 2nd bg digit
|
||||
cmp al, '0'
|
||||
jb .skip_color_done
|
||||
cmp al, '9'
|
||||
ja .skip_color_done
|
||||
jmp .next_byte
|
||||
.skip_color_done:
|
||||
dec esi
|
||||
call skip_mirc_color_args ; consume the same byte span as renderer's dec_to_esi
|
||||
jmp .next_byte
|
||||
.newline:
|
||||
inc edx
|
||||
@@ -122,34 +96,20 @@ text_nextline:
|
||||
.done:
|
||||
ret
|
||||
.skip_color:
|
||||
lodsb
|
||||
cmp al, '0'
|
||||
jb .skip_color_done
|
||||
cmp al, '9'
|
||||
ja .skip_color_done
|
||||
lodsb
|
||||
cmp al, '0'
|
||||
jb .skip_color_comma
|
||||
cmp al, '9'
|
||||
ja .skip_color_comma
|
||||
lodsb
|
||||
.skip_color_comma:
|
||||
cmp al, ','
|
||||
jne .skip_color_done
|
||||
lodsb
|
||||
cmp al, '0'
|
||||
jb .skip_color_done
|
||||
cmp al, '9'
|
||||
ja .skip_color_done
|
||||
lodsb
|
||||
cmp al, '0'
|
||||
jb .skip_color_done
|
||||
cmp al, '9'
|
||||
ja .skip_color_done
|
||||
jmp .loop
|
||||
.skip_color_done:
|
||||
dec esi
|
||||
; In backward scans (called with DF set from draw_channel_text scroll loop),
|
||||
; color args precede \x03 in buffer and have already been counted as plain
|
||||
; chars. Forward-parsing them here would corrupt esi, so fall back to the
|
||||
; pre-PR behavior of treating \x03 as a regular 1-width character.
|
||||
pushfd
|
||||
pop eax ; AL is reloaded by lodsb on .loop re-entry
|
||||
test eax, 1 shl 10 ; DF set = backward direction
|
||||
jnz .skip_color_backward
|
||||
call skip_mirc_color_args
|
||||
jmp .loop
|
||||
.skip_color_backward:
|
||||
dec ecx
|
||||
jnz .loop
|
||||
ret ; ecx hit 0: same as .done fallthrough
|
||||
|
||||
;----------------------------------
|
||||
; print string
|
||||
@@ -356,7 +316,8 @@ draw_channel_text:
|
||||
movzx eax, byte[edx]
|
||||
sub al, '0'
|
||||
cmp al, 9
|
||||
ja @f
|
||||
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]
|
||||
@@ -428,7 +389,9 @@ draw_channel_text:
|
||||
jz .line
|
||||
mov edi, [irc_colors + 4*esi]
|
||||
or ecx, 0x40000000
|
||||
jmp .line
|
||||
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
|
||||
@@ -524,6 +487,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:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user