You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

684 lines
17 KiB
NASM

;; %define FONT_BOLDING
;; %define WINDOW_BORDER
FONT_WEIGHT equ 500
; /* WS_BORDER | WS_DLGFRAME =*/ WS_CAPTION | /*WS_GROUP =*/ WS_MINIMIZEBOX | WS_SYSMENU
WINDOW_STYLE equ 0xca0000
%ifdef WINDOW_BORDER
EXTENDED_STYLE equ 0x20200 ; WS_EX_CLIENTEDGE | WS_EX_STATICEDGE
%else
EXTENDED_STYLE equ 0
%endif
bits 32
cpu 386
org 0x400c00
incbin "game.exe.orig", 0, 0x6010
AdjustWindowRectEx equ 0x42d8f0
CFrameWnd_ctor equ 0x41de32
CreateCompatibleDC equ 0x42d53c
CreateFontA equ 0x42d55c
DeleteObject equ 0x42d550
GetDC equ 0x42d8e0
GetGlyphOutlineA equ 0x42d558
GetModuleHandleA equ 0x42d5e8
GetProcAddress equ 0x42d688
GetSystemMetrics equ 0x42d8f4
GlobalLock equ 0x42d760
GlobalUnlock equ 0x42d75c
SelectObject equ 0x42d554
__ismbclegal equ 0x40ec00
rand equ 0x40dd20
afx_global_new_like equ 0x41774c
copy_buf_to_window equ 0x40abd0
create_win_wrap0 equ 0x418fd4
font_face equ 0x427504
free_like equ 0x41777e
norm_float_to_u16fp equ 0x40b3f0
get_text_metrics_cache equ 0x42ca9c
create_win_wrap1:
mov eax,[fs:0x0]
push ebp
db 0x8b, 0xec ;mov ebp,esp
push byte -0x1
push dword 0x406d31
push eax
mov [dword fs:0x0],esp
sub esp,byte +0x1c
push ebx
push esi
mov [ebp-0x20],ecx
push edi
db 0x8b, 0xf1 ; mov esi,ecx
call CFrameWnd_ctor
mov dword [ebp-0x4],0x0
mov dword [esi+0x1c8],0x1
mov dword [ebp-0x1c],0x0
push dword EXTENDED_STYLE
mov dword [esi],0x423080
push byte +0x0
lea eax,[ebp-0x1c]
mov dword [ebp-0x14],0x280
mov dword [ebp-0x18],0x0
mov dword [ebp-0x10],0x190
push dword WINDOW_STYLE
push eax
call [dword AdjustWindowRectEx]
mov ebx,[ebp-0x14]
mov edi,[ebp-0x10]
sub ebx,[ebp-0x1c]
sub edi,[ebp-0x18]
push byte +0x0
call [dword CreateCompatibleDC]
push byte +0x0
call [dword GetSystemMetrics]
push byte +0x1
mov [ebp-0x24],eax
call [dword GetSystemMetrics]
mov [ebp-0x28],eax
call 0x420917
mov ecx,[eax+0x4]
push byte +0x0
push byte +0x0
mov eax,[ebp-0x28]
push byte +0x0
db 0x2b, 0xc7 ;sub eax,edi
cdq
push edi
db 0x2b, 0xc2 ; sub eax,edx
sar eax,byte 0x1
push ebx
push eax
mov eax,[ebp-0x24]
db 0x2b, 0xc3 ;sub eax,ebx
cdq
db 0x2b, 0xc2 ; sub eax,edx
sar eax,byte 0x1
push eax
push dword WINDOW_STYLE
push dword 0x4273e8
mov ecx,[ecx+0xc0]
push ecx
push dword EXTENDED_STYLE
db 0x8b, 0xce ; mov ecx,esi
call create_win_wrap0
mov dword [esi+0x1d8],0x0
mov ecx,[esi+0x1c]
db 0x8b, 0xc6 ;mov eax,esi
pop edi
mov [esi+0x1d4],ecx
mov dword [esi+0x28c],0x0
mov dword [esi+0x290],0x0
mov dword [ebp-0x4],0xffffffff
mov ecx,[ebp-0xc]
pop esi
mov [dword fs:0x0],ecx
pop ebx
db 0x8b, 0xe5 ;mov esp,ebp
pop ebp
ret
times 0x6131-($-$$) int3
incbin "game.exe.orig", 0x6131, 0xa470-0x6131
; ------------------------------------------------------------------------------
struc class
resd 1
.global: resd 1
.window: resd 1
.palette: resd 1
.font_load_height: resw 1
resw 1
.char_width: resd 1
.line_height: resd 1
.rand_height: resd 1
.global_locked: resd 1
endstruc
struc glyph_metrics
.black_box_x: resd 1
.black_box_y: resd 1
.origin_x: resd 1
.origin_y: resd 1
.cell_inc_x: resd 1
.cell_inc_y: resd 1
endstruc
GGO_BITMAP equ 1
draw_text: ; 40b070
.extra_locals equ 0x38
; locals
.glyph_buf_size equ 0x10
.hdc equ 0x14
.font equ 0x18
.fp_1 equ 0x1c
.double_0 equ 0x1c ; overlap
.double_1 equ 0x24
.x_advance equ 0x2c
.orig_xpos equ 0x30
.mat equ 0x34
.fp_0 equ 0x44
.gdi_obj equ 0x48
.glyph_metrics equ 0x4c
.tmp equ 0x60
.metrics equ 0x60 ; overlap
; func parameters
.str equ .extra_locals+0x68
.xpos equ .extra_locals+0x6c
.ypos equ .extra_locals+0x70
.color equ .extra_locals+0x74
.dummy equ .extra_locals+0x78 ; unused parameter of copy_glyph_to_buf
sub esp, 0x54+.extra_locals
push ebx
push esi
push edi
db 0x8b, 0xf1 ; mov esi,ecx
push ebp
push dword font_face ; font face
push byte +0x1 ; pitch and family
push byte +0x0 ; quality
push byte +0x0 ; clip precision
push byte +0x0 ; out precision
push dword 0x80 ; charset
push byte +0x0 ; strikeout
push byte +0x0 ; underline
db 0x33, 0xc0 ; xor eax,eax
mov ax,[esi+class.font_load_height]
push byte +0x0 ; italic
push dword FONT_WEIGHT ; weight
push byte +0x0 ; orientation
push byte +0x0 ; escapement
push byte +0x0 ; font width
push eax ; font height
call [dword CreateFontA]
mov ecx,[esi+class.window]
mov ebx,[dword GetDC]
mov [esp+.font],eax
push ecx
call ebx ; GetDC(window)
mov ecx,[esp+.font]
mov [esp+.hdc],eax
push ecx ; font
push eax ; hdc
call [dword SelectObject]
mov [esp+.gdi_obj],eax ; SelectObject result
; init mat to (1 0; 0 1)
mov eax, 65536
xor ecx, ecx
mov [esp+.mat+0], eax
mov [esp+.mat+4], ecx
mov [esp+.mat+8], ecx
mov [esp+.mat+12], eax
mov edi,[esp+.str]
mov eax,[esp+.xpos]
movsx bx,[edi] ; bx = (char)*str
test bx,bx
mov [esp+.orig_xpos],eax
jz near .return
; get text metrics
mov eax, [get_text_metrics_cache]
test eax, eax
jnz .has_metrics
push gdi32_str
call [dword GetModuleHandleA]
push get_text_metrics_str
push eax
call [dword GetProcAddress]
mov [get_text_metrics_cache], eax
.has_metrics:
lea ecx,[esp+.metrics]
push ecx
push dword [esp+4+.hdc]
call eax ; GetTextMetricsA
.loop:
cmp dword [esi+class.rand_height],byte +0x1
jnz near .no_rand
db 0x33, 0xed ; xor ebp,ebp
push dword font_face ; font face
mov bp,[esi+class.font_load_height]
push byte +0x1 ; pitch and family
push byte +0x0 ; quality
push byte +0x0 ; clip precision
push byte +0x0 ; out precision
push dword 0x80 ; charset
push byte +0x0 ; strike out
push byte +0x0 ; underline
push byte +0x0 ; italic
push dword FONT_WEIGHT ; weight
push byte +0x0 ; orientation
push byte +0x0 ; escapement
push byte +0x0 ; font width
call rand
cdq
idiv ebp
db 0x8b, 0xc2 ; mov eax,edx
mov ecx,0x3
cdq
db 0x2b, 0xc2 ; sub eax,edx
sar eax,byte 0x1
mov [esp+0x34+.glyph_buf_size],eax
lea eax,[nosplit ebp*2+0x0]
cdq
idiv ecx
add [esp+0x34+.glyph_buf_size],eax
mov eax,[esp+0x34+.glyph_buf_size]
push eax ; font height
call [dword CreateFontA]
mov ecx,[esp+.hdc]
push eax
mov [esp+4+.font],eax
push ecx
call [dword SelectObject]
call rand
mov ecx,0x14
sub esp,byte +0x8
cdq
idiv ecx
sub edx,byte +0xa
lea eax,[esp+8+.tmp]
push eax
db 0x8b, 0xce ; mov ecx,esi
mov [esp+0xc+.glyph_buf_size],edx
fild dword [esp+0xc+.glyph_buf_size]
fmul qword [dword 0x423198]
fcos
fstp qword [esp+0x4]
call norm_float_to_u16fp
mov ecx,[eax]
mov [esp+.mat+0],ecx
call rand
mov ecx,0x14
sub esp,byte +0x8
cdq
idiv ecx
sub edx,byte +0xa
mov [esp+8+.glyph_buf_size],edx
fild dword [esp+8+.glyph_buf_size]
fmul qword [dword 0x423198]
fsin
fstp qword [esp]
lea eax,[esp+8+.fp_0]
push eax
db 0x8b, 0xce ; mov ecx,esi
call norm_float_to_u16fp
mov ecx,[eax]
mov [esp+.mat+4],ecx
call rand
mov ecx,0x14
sub esp,byte +0x8
cdq
idiv ecx
sub edx,byte +0xa
lea eax,[esp+8+.double_1]
push eax
db 0x8b, 0xce ; mov ecx,esi
mov [esp+0xc+.glyph_buf_size],edx
fild dword [esp+0xc+.glyph_buf_size]
fmul qword [dword 0x423198]
fsin
fchs
fstp qword [esp+0x4]
call norm_float_to_u16fp
mov ecx,[eax]
mov [esp+.mat+8],ecx
call rand
mov ecx,0x14
sub esp,byte +0x8
cdq
idiv ecx
sub edx,byte +0xa
lea eax,[esp+8+.fp_1]
push eax
db 0x8b, 0xce ; mov ecx,esi
mov [esp+0xc+.glyph_buf_size],edx
fild dword [esp+0xc+.glyph_buf_size]
fmul qword [dword 0x423198]
fcos
fstp qword [esp+0x4]
call norm_float_to_u16fp
mov ecx,[eax]
mov [esp+.mat+12],ecx
.no_rand:
shl bx,byte 0x8 ; bx = cur_char << 8 = str[0] << 8
; cur_char is sign extended, but it is shifted out
lea ebp,[edi+0x1] ; ebp = str+1
movzx ax,[ebp+0x0] ; ax = (byte) str[1]
db 0x66, 0x0b, 0xd8 ; or bx,ax ; bx = (str[0] << 8) | (byte) str[1]
movzx ecx,bx ; ecx = (ushort) ((str[0] << 8) | (byte) str[1])
push ecx
call __ismbclegal
add esp,byte +0x4
cmp eax,byte +0x1
jnz short .illegal_mbc
add edi,byte +0x2 ; edi = str+2
mov eax,[esi+class.char_width]
db 0x03, 0xc0 ;add eax,eax ; eax = 2*char_width
jmp short .after_mbc
.illegal_mbc:
shr bx,byte 0x8 ; bx = (byte) str[0]
db 0x8b, 0xfd ; mov edi,ebp ; edi = str+1
mov eax,[esi+class.char_width]
.after_mbc:
lea ecx,[esp+.glyph_metrics]
mov edx,[esp+.hdc]
movzx ebp,bx ; ebp = (ushort) cur_char
mov [esp+.x_advance],eax
lea eax,[esp+.mat]
push eax ; &mat
push byte +0x0 ; buffer = NULL
push byte +0x0 ; buffer_length = 0
push ecx ; &glyph_metrics
push byte GGO_BITMAP ; format = GGO_BITMAP
push ebp ; (uint) (ushort) cur_char
push edx ; hdc
call [dword GetGlyphOutlineA]
mov [esp+.glyph_buf_size],eax
push eax
call afx_global_new_like
lea ecx,[esp+4+.mat]
lea edx,[esp+4+.glyph_metrics]
add esp,byte +0x4
db 0x8b, 0xd8 ; mov ebx,eax ; ebx = buf
mov eax,[esp+.glyph_buf_size]
push ecx ; &mat
mov ecx,[esp+4+.hdc]
push ebx ; buf
push eax ; glyph_buf_size
push edx ; &glyph_metrics
push byte GGO_BITMAP ; format = GGO_BITMAP
push ebp ; (uint) (ushort) cur_char
push ecx ; hdc
call [dword GetGlyphOutlineA]
mov ecx,[esp+.dummy]
mov edx,[esp+.color]
mov eax,[esp+.glyph_metrics+glyph_metrics.black_box_y]
push ecx ; dummy
push edx ; color
and eax,0xffff ; eax = black_box_y & 0xffff
mov ecx,[esp+8+.ypos]
add ecx,[esp+8+.metrics+4]
sub ecx,[esp+8+.glyph_metrics+glyph_metrics.origin_y]
push eax ; black_box_y & 0xffff
mov eax,[esp+0x0c+.glyph_metrics+glyph_metrics.black_box_x]
and eax,0xffff ; eax = black_box_x & 0xffff
push eax ; black_box_x & 0xffff
push ebx ; buf
mov eax,[esp+0x14+.glyph_metrics+glyph_metrics.origin_x]
push ecx ; ypos
add eax,[esp+0x18+.xpos] ; eax = glyph_metrics.origin_x + xpos
mov ecx,[esi+class.global]
push eax ; glyph_metrics.origin_x + xpos
mov edx,[ecx] ; edx = *global
push edx ; *global
db 0x8b, 0xce ; mov ecx,esi ; this
call copy_glyph_to_buf
mov ecx,[esp+.x_advance]
push ebx ; buf
add [esp+4+.xpos],ecx
call free_like
add esp,byte +0x4
movsx bx,[edi] ; bx = (char) *next_str
test bx,bx
jnz near .loop
.return:
mov eax,[esp+.gdi_obj]
mov ecx,[esp+.hdc]
push eax
push ecx
call [dword SelectObject] ; (hdc, gdi_obj)
mov ecx,[esp+.font]
push ecx
call [dword DeleteObject]
mov ecx,[esi+class.line_height]
mov eax,[esp+.xpos]
sub eax,[esp+.orig_xpos] ; eax = xpos - orig_xpos
push ecx ; line_height
mov ecx,[esp+4+.ypos]
push eax ; xpos - orig_xpos
mov edx,[esp+8+.orig_xpos]
push ecx ; ypos
push edx ; orig_xpos
db 0x8b, 0xce ;mov ecx,esi
call copy_buf_to_window
pop ebp
pop edi
pop esi
pop ebx
add esp, 0x54+.extra_locals
ret 0x14
gdi32_str:
db "gdi32.dll", 0
get_text_metrics_str:
db "GetTextMetricsA", 0
times 0xa7f0-($-$$) int3
incbin "game.exe.orig", 0xa7f0, 0xa810-0xa7f0
; ------------------------------------------------------------------------------
struc bmi_header
.size: resd 1
.width: resd 1
.height: resd 1
.planes: resw 1
.bit_count: resw 1
.compression: resd 1
.size_image: resd 1
.x_pels_per_m: resd 1
.y_pels_per_m: resd 1
.clr_used: resd 1
.clr_important: resd 1
endstruc
struc global_struct
.bmi: resb bmi_header_size
resb 0x428-($-$$)
.buf: resb 1
endstruc
copy_glyph_to_buf: ; 0040b410
; locals
.loop_y equ 0x10
.src_row_ptr equ 0x1c
.glob_buf equ 0x14
.src_cur_ptr equ 0x18
.this equ 0x20
.cur_pixel equ 0x24
.stride equ 0x28
; func parameters
.global equ 0x30
.dst_x equ 0x34
.dst_y equ 0x38
.buf equ 0x3c
.width equ 0x40
.height equ 0x44
.color equ 0x48
.dummy equ 0x4a ; unused parameter
mov eax,[esp-0x2c+.global]
sub esp,byte +0x1c
mov [esp-0x10+.this],ecx
push ebx
push esi
push edi
push ebp
push eax
call [dword GlobalLock]
db 0x8b, 0xf0 ; mov esi,eax ; esi=global
mov ecx,[esp+.this]
lea eax,[esi+global_struct.buf]
mov [esp+.glob_buf],eax
mov dword [esp+.loop_y],0x0
cmp dword [esp+.height],byte +0x0
jng near .return
mov eax,[esp+.buf]
mov [esp+.src_row_ptr],eax
mov ebx,[esp+.color]
mov eax,[esp+.width]
add eax,31
sar eax,byte 0x3
and eax,~3
mov [esp+.stride],eax ; stride = (width+31)/32*4
.row_loop:
mov ecx,[esi+bmi_header.height]
mov edi,[esp+.dst_x]
sub ecx,[esp+.loop_y] ; ecx = bmi_height - loop_y
sub ecx,[esp+.dst_y] ; ecx = bmi_height - loop_y - dst_y
db 0x33, 0xed ; xor ebp,ebp ; ebp: loop x
dec ecx ; ecx = bmi_height - loop_y - dst_y - 1
imul ecx,[esi+bmi_header.width] ; ecx = (bmi_height - loop_y - dst_y - 1) * bmi_wdith
add ecx,[esp+.glob_buf] ; ecx = glob_buf + (bmi_height - loop_y - dst_y - 1) * bmi_wdith
db 0x03, 0xf9 ; add edi,ecx ; edi = glob_buf + (bmi_height - loop_y - dst_y - 1) * bmi_wdith + dst_x
mov ecx,[esp+.src_row_ptr]
mov [esp+.src_cur_ptr],ecx
cmp [esp+.width],ebp
jng short .LAB_0040b528
.column_loop:
mov eax,ebp ; eax = loop_x
mov ecx,[esp+.src_cur_ptr]
and eax,byte +0x7 ; eax = loop_x & 7
movsx edx,byte [ecx] ; edx = *src_cur_ptr
mov cl,0x7
mov [esp+.cur_pixel],edx
mov edx,0x1
sub cl,al ; cl = 7 - (loop & 7)
shl edx,cl ; edx = 1 << cl
test [esp+.cur_pixel],edx
jz short .skip_pixel ; transparent, skip
mov [edi],bl ; *out_pixel = bl = color
%ifdef FONT_BOLDING
mov ecx,[esi+bmi_header.height]
sub ecx,[esp+.loop_y]
sub ecx,[esp+.dst_y]
sub ecx,byte +0x2 ; ecx = bmi_height - loop_y - dst_y - 2
imul ecx,[esi+bmi_header.width] ; ecx = (bmi_height - loop_y - dst_y - 2) * bmi_width
add ecx,[esp+.glob_buf]
add ecx,[esp+.dst_x] ; ecx = glob_buf + (bmi_height - loop_y - dst_y - 2) * bmi_width + dst_x
db 0x03, 0xcd ; add ecx,ebp ; ecx = glob_buf + (bmi_height - loop_y - dst_y - 2) * bmi_width + dst_x + loop_x
mov [ecx],bl
mov [ecx+0x1],bl
%endif
.skip_pixel:
cmp eax,byte +0x7
jnz short .skip_ptr_inc
inc dword [esp+.src_cur_ptr]
.skip_ptr_inc:
inc edi ; ++out_pixel
inc ebp ; ++loop_x
cmp [esp+.width],ebp
jg short .column_loop
.LAB_0040b528:
mov eax,[esp+0x28]
inc dword [esp+.loop_y]
mov ecx,[esp+.loop_y]
add [esp+.src_row_ptr],eax
cmp [esp+.height],ecx
jg near .row_loop
.return:
mov eax,[esp+.global]
push eax
call [dword GlobalUnlock]
mov ecx,[esp+.this]
pop ebp
pop edi
pop esi
pop ebx
mov [ecx+class.global_locked],eax
mov eax,0x1
add esp,byte +0x1c
ret 0x20
times 0xa970-($-$$) int3
incbin "game.exe.orig", 0xa970, 0x1da3d-0xa970
; ------------------------------------------------------------------------------
fuckup_window_style: ;41e63d
push esi
mov esi,[esp+0x8]
cmp dword [esi+0x28],byte +0x0
jnz short .LAB_0041e66e
call 0x420917
test byte [eax+0x18],0x8
mov eax,0x1
jnz short .LAB_0041e65f
push byte +0x8
call 0x41b2f2
.LAB_0041e65f:
test eax,eax
jnz short .LAB_0041e667
db 0x33, 0xc0 ; xor eax,eax
jmp short .return
.LAB_0041e667:
mov dword [esi+0x28],0x423b08
.LAB_0041e66e:
mov eax,[esi+0x20]
test ah,0x80
jz short .return_1
cmp dword [dword 0x42b590],byte +0x0
jz short .return_1
or ah,0x40
mov [esi+0x20],eax
.return_1:
mov eax,0x1
.return:
pop esi
ret 0x4
times 0x1da9b-($-$$) int3
incbin "game.exe.orig", 0x1da9b