271 lines
7.2 KiB
PHP
271 lines
7.2 KiB
PHP
BUF_SIZE = 4096
|
|
FRM_WIDTH = 1
|
|
MARGIN = 1
|
|
|
|
struct TEXT_VIEW
|
|
left dd ?
|
|
top dd ?
|
|
width dd ?
|
|
height dd ?
|
|
|
|
bg_color dd ?
|
|
fg_color dd ?
|
|
|
|
buf_data dd ?
|
|
buf_size dd ?
|
|
data_size dd ?
|
|
|
|
total_lines dd ?
|
|
curr_line dd ?
|
|
max_length dd ? ; length of the longest string
|
|
|
|
rows dd ?
|
|
cols dd ?
|
|
ends
|
|
|
|
proc text_view_init stdcall, text_view:dword
|
|
mov ecx, [text_view]
|
|
xor eax, eax
|
|
mov [ecx + TEXT_VIEW.buf_data], eax
|
|
mov [ecx + TEXT_VIEW.buf_size], eax
|
|
mov [ecx + TEXT_VIEW.data_size], eax
|
|
mov [ecx + TEXT_VIEW.total_lines], eax
|
|
mov [ecx + TEXT_VIEW.curr_line], eax
|
|
mov [ecx + TEXT_VIEW.max_length], eax
|
|
ret
|
|
endp
|
|
|
|
proc text_view_deinit stdcall uses ebx, text_view:dword
|
|
mov ebx, [text_view]
|
|
mov ecx, [ebx + TEXT_VIEW.buf_data]
|
|
test ecx, ecx
|
|
jz .exit
|
|
mcall SF_SYS_MISC, SSF_MEM_FREE
|
|
.exit
|
|
ret
|
|
endp
|
|
|
|
proc text_view_draw stdcall uses ebx esi edi, text_view:dword
|
|
mov esi, [text_view]
|
|
call tv.draw_frame_and_bg
|
|
call tv.calc_rows_and_cols
|
|
DEBUGF 0, "text_view rows=%d cols=%d\n", [esi + TEXT_VIEW.rows], [esi + TEXT_VIEW.cols]
|
|
|
|
mov eax, [esi + TEXT_VIEW.curr_line]
|
|
mov ebx, [esi + TEXT_VIEW.total_lines]
|
|
DEBUGF 0, "text_view curr_line=%d total_lines=%d\n", eax, ebx
|
|
sub ebx, eax
|
|
cmp ebx, [esi + TEXT_VIEW.rows]
|
|
jbe @f
|
|
mov ebx, [esi + TEXT_VIEW.rows]
|
|
@@:
|
|
mov edi, [esi + TEXT_VIEW.buf_data]
|
|
call goto_curr_line
|
|
mov ecx, ebx ; ecx = count lines
|
|
xor eax, eax ; eax = index from 0
|
|
|
|
mov ebx, [esi + TEXT_VIEW.left]
|
|
add ebx, MARGIN + FRM_WIDTH
|
|
shl ebx, 16
|
|
add ebx, [esi + TEXT_VIEW.top]
|
|
add ebx, MARGIN + FRM_WIDTH
|
|
|
|
.draw_lines:
|
|
cmp eax, ecx
|
|
jae .draw_lines_end
|
|
push eax ecx
|
|
call tv.draw_single_line
|
|
; move edi pointer to the next string
|
|
add edi, eax
|
|
inc edi
|
|
pop ecx eax
|
|
inc eax ; next line num
|
|
add ebx, FONT_HEIGHT + MARGIN
|
|
jmp .draw_lines
|
|
.draw_lines_end:
|
|
ret
|
|
endp
|
|
|
|
proc text_view_append_line stdcall uses ebx esi edi, text_view:dword, string:dword
|
|
mov esi, [string]
|
|
call strlen
|
|
inc eax ; include \0
|
|
mov esi, [text_view]
|
|
mov edi, eax
|
|
add eax, [esi + TEXT_VIEW.data_size]
|
|
cmp eax, [esi + TEXT_VIEW.buf_size]
|
|
jbe .noalloc
|
|
|
|
and eax, not (BUF_SIZE - 1)
|
|
add eax, BUF_SIZE
|
|
mov ecx, eax
|
|
mov edx, [esi + TEXT_VIEW.buf_data]
|
|
mcall SF_SYS_MISC, SSF_MEM_REALLOC
|
|
test eax, eax
|
|
jz .exit
|
|
|
|
mov [esi + TEXT_VIEW.buf_data], eax
|
|
mov [esi + TEXT_VIEW.buf_size], ecx
|
|
.noalloc:
|
|
inc [esi + TEXT_VIEW.total_lines]
|
|
mov eax, edi
|
|
cmp eax, [esi + TEXT_VIEW.max_length]
|
|
jbe .short
|
|
|
|
mov [esi + TEXT_VIEW.max_length], eax
|
|
.short:
|
|
mov ecx, edi
|
|
mov edi, [esi + TEXT_VIEW.buf_data]
|
|
add edi, [esi + TEXT_VIEW.data_size]
|
|
add [esi + TEXT_VIEW.data_size], ecx
|
|
mov esi, [string]
|
|
cld
|
|
rep movsb
|
|
.exit:
|
|
ret
|
|
endp
|
|
|
|
proc text_view_clear stdcall uses ebx, text_view:dword
|
|
mov edx, [text_view]
|
|
mov ecx, [edx + TEXT_VIEW.buf_data]
|
|
test ecx, ecx
|
|
jz @f
|
|
mcall SF_SYS_MISC, SSF_MEM_FREE
|
|
@@:
|
|
xor eax, eax
|
|
mov [edx + TEXT_VIEW.buf_data], eax
|
|
mov [edx + TEXT_VIEW.buf_size], eax
|
|
mov [edx + TEXT_VIEW.data_size], eax
|
|
mov [edx + TEXT_VIEW.total_lines], eax
|
|
mov [edx + TEXT_VIEW.curr_line], eax
|
|
mov [edx + TEXT_VIEW.max_length], eax
|
|
ret
|
|
endp
|
|
|
|
proc text_view_deinit stdcall uses ebx, text_view:dword
|
|
mov edx, [text_view]
|
|
mov ecx, [edx + TEXT_VIEW.buf_data]
|
|
test ecx, ecx
|
|
jz @f
|
|
mcall SF_SYS_MISC, SSF_MEM_FREE
|
|
@@:
|
|
ret
|
|
endp
|
|
|
|
proc tv.draw_frame_and_bg
|
|
; esi = text_view
|
|
mov ebx, [esi + TEXT_VIEW.left]
|
|
shl ebx, 16
|
|
add ebx, [esi + TEXT_VIEW.width]
|
|
mov ecx, [esi + TEXT_VIEW.top]
|
|
shl ecx, 16
|
|
add ecx, [esi + TEXT_VIEW.height]
|
|
mov edx, [esi + TEXT_VIEW.fg_color]
|
|
call draw_frame
|
|
add ebx, 1 shl 16
|
|
sub ebx, 2
|
|
add ecx, 1 shl 16
|
|
sub ecx, 2
|
|
mov edx, [esi + TEXT_VIEW.bg_color]
|
|
mcall SF_DRAW_RECT
|
|
ret
|
|
endp
|
|
|
|
proc tv.calc_rows_and_cols
|
|
; esi = text_view
|
|
mov eax, [esi + TEXT_VIEW.width]
|
|
sub eax, (FRM_WIDTH + MARGIN) * 2
|
|
shr eax, 3 ; assume that font width is 8 px
|
|
mov [esi + TEXT_VIEW.cols], eax
|
|
xor edx, edx
|
|
mov eax, [esi + TEXT_VIEW.height]
|
|
sub eax, MARGIN * 2
|
|
mov ebx, FONT_HEIGHT + MARGIN
|
|
div ebx
|
|
mov [esi + TEXT_VIEW.rows], eax
|
|
ret
|
|
endp
|
|
|
|
proc tv.draw_single_line uses esi
|
|
; esi = text_view
|
|
; ebx = coordinates: left << 16 + top
|
|
; edi = pointer to the first byte of string in [text_view.buf_data]
|
|
; return: eax = length of the string
|
|
mov ecx, 0x10000000 ; fixed-length string
|
|
or ecx, [esi + TEXT_VIEW.fg_color]
|
|
push esi
|
|
mov esi, edi
|
|
call strlen
|
|
pop esi
|
|
push eax
|
|
cmp eax, [esi + TEXT_VIEW.cols]
|
|
jbe .len_ok
|
|
mov eax, [esi + TEXT_VIEW.cols]
|
|
.len_ok:
|
|
mov esi, eax
|
|
mov edx, edi
|
|
mcall SF_DRAW_TEXT
|
|
pop eax
|
|
ret
|
|
endp
|
|
|
|
proc goto_curr_line uses ebx esi
|
|
; eax = curr line index
|
|
; edi = buf
|
|
mov ebx, eax
|
|
xor ecx, ecx
|
|
mov esi, edi
|
|
cld
|
|
.scan:
|
|
cmp ecx, ebx
|
|
je .exit
|
|
lodsb
|
|
test al, al
|
|
jnz .scan
|
|
inc ecx
|
|
jmp .scan
|
|
.exit:
|
|
mov eax, ebx
|
|
mov edi, esi
|
|
ret
|
|
endp
|
|
|
|
proc draw_frame
|
|
; ebx = left << 16 + width
|
|
; ecx = top << 16 + height
|
|
; edx = color
|
|
push ebx ecx
|
|
mov eax, ebx
|
|
shr eax, 16
|
|
add ebx, eax
|
|
dec ebx
|
|
mov eax, ecx
|
|
shr eax, 16
|
|
add ecx, eax
|
|
dec ecx
|
|
push ecx
|
|
push ecx
|
|
mov eax, ecx
|
|
shr eax, 16
|
|
mov cx, ax
|
|
mcall SF_DRAW_LINE
|
|
pop ecx
|
|
mov eax, ecx
|
|
shl ecx, 16
|
|
mov cx, ax
|
|
mcall SF_DRAW_LINE
|
|
pop ecx
|
|
push ebx
|
|
mov eax, ebx
|
|
shr eax, 16
|
|
mov bx, ax
|
|
mcall SF_DRAW_LINE
|
|
pop ebx
|
|
mov eax, ebx
|
|
shl ebx, 16
|
|
mov bx, ax
|
|
mcall SF_DRAW_LINE
|
|
pop ecx ebx
|
|
ret
|
|
endp
|