320 lines
7.2 KiB
PHP
320 lines
7.2 KiB
PHP
; ==============================================================================
|
|
; EBLAN ENGINE - 2D Canvas Overlay, Font 8x8 Text & Minimap Radar
|
|
; ==============================================================================
|
|
|
|
.code
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; DrawPixel: Draws a single 32-bit pixel with bounds checking
|
|
; ------------------------------------------------------------------------------
|
|
DrawPixel PROC x:DWORD, y:DWORD, color:DWORD
|
|
mov eax, x
|
|
cmp eax, 0
|
|
jl @F
|
|
cmp eax, SCREEN_W
|
|
jge @F
|
|
|
|
mov edx, y
|
|
cmp edx, 0
|
|
jl @F
|
|
cmp edx, SCREEN_H
|
|
jge @F
|
|
|
|
imul edx, SCREEN_PITCH
|
|
shl eax, 2
|
|
add eax, edx
|
|
add eax, OFFSET screenBuffer
|
|
mov ecx, color
|
|
mov [eax], ecx
|
|
@@:
|
|
ret
|
|
DrawPixel ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; DrawRect: Draws a filled rectangle
|
|
; ------------------------------------------------------------------------------
|
|
DrawRect PROC uses ebx ecx edx edi, x:DWORD, y:DWORD, w:DWORD, h:DWORD, color:DWORD
|
|
LOCAL curY:DWORD, endY:DWORD
|
|
LOCAL curX:DWORD, endX:DWORD
|
|
|
|
mov eax, x
|
|
mov curX, eax
|
|
add eax, w
|
|
mov endX, eax
|
|
|
|
mov eax, y
|
|
mov curY, eax
|
|
add eax, h
|
|
mov endY, eax
|
|
|
|
loop_rect_y:
|
|
mov eax, curY
|
|
cmp eax, endY
|
|
jge rect_done
|
|
cmp eax, 0
|
|
jl next_rect_y
|
|
cmp eax, SCREEN_H
|
|
jge rect_done
|
|
|
|
mov ebx, curX
|
|
loop_rect_x:
|
|
cmp ebx, endX
|
|
jge next_rect_y
|
|
cmp ebx, 0
|
|
jl next_rect_x
|
|
cmp ebx, SCREEN_W
|
|
jge next_rect_y
|
|
|
|
; Pixel address
|
|
mov eax, curY
|
|
imul eax, SCREEN_PITCH
|
|
mov edx, ebx
|
|
shl edx, 2
|
|
add eax, edx
|
|
add eax, OFFSET screenBuffer
|
|
mov edx, color
|
|
mov [eax], edx
|
|
|
|
next_rect_x:
|
|
inc ebx
|
|
jmp loop_rect_x
|
|
|
|
next_rect_y:
|
|
inc curY
|
|
jmp loop_rect_y
|
|
|
|
rect_done:
|
|
ret
|
|
DrawRect ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; DrawRectOutline: Draws a 1-pixel rectangle outline
|
|
; ------------------------------------------------------------------------------
|
|
DrawRectOutline PROC x:DWORD, y:DWORD, w:DWORD, h:DWORD, color:DWORD
|
|
LOCAL x2:DWORD, y2:DWORD
|
|
|
|
mov eax, x
|
|
add eax, w
|
|
dec eax
|
|
mov x2, eax
|
|
|
|
mov eax, y
|
|
add eax, h
|
|
dec eax
|
|
mov y2, eax
|
|
|
|
; Top & Bottom horizontal lines
|
|
mov ecx, x
|
|
@@:
|
|
cmp ecx, x2
|
|
jg @F
|
|
invoke DrawPixel, ecx, y, color
|
|
invoke DrawPixel, ecx, y2, color
|
|
inc ecx
|
|
jmp @B
|
|
@@:
|
|
|
|
; Left & Right vertical lines
|
|
mov edx, y
|
|
@@:
|
|
cmp edx, y2
|
|
jg @F
|
|
invoke DrawPixel, x, edx, color
|
|
invoke DrawPixel, x2, edx, color
|
|
inc edx
|
|
jmp @B
|
|
@@:
|
|
ret
|
|
DrawRectOutline ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; DrawChar8x8: Renders an 8x8 ASCII character with transparent background
|
|
; ------------------------------------------------------------------------------
|
|
DrawChar8x8 PROC uses ebx ecx edx esi edi, posX:DWORD, posY:DWORD, charCode:DWORD, color:DWORD
|
|
LOCAL row:DWORD, col:DWORD
|
|
LOCAL fontPtr:DWORD
|
|
|
|
; Find glyph offset: charCode * 8 (full 256-glyph CP1251 font)
|
|
mov eax, charCode
|
|
and eax, 0FFh
|
|
shl eax, 3 ; * 8 bytes
|
|
add eax, OFFSET font8x8
|
|
mov fontPtr, eax
|
|
|
|
mov row, 0
|
|
loop_char_row:
|
|
mov eax, fontPtr
|
|
add eax, row
|
|
movzx ebx, byte ptr [eax] ; 8-bit glyph row mask
|
|
|
|
mov col, 0
|
|
loop_char_col:
|
|
test ebx, 80h ; Check MSB
|
|
jz next_char_col
|
|
|
|
; Draw text pixel with black drop-shadow for high contrast!
|
|
mov eax, posX
|
|
add eax, col
|
|
inc eax
|
|
mov edx, posY
|
|
add edx, row
|
|
inc edx
|
|
invoke DrawPixel, eax, edx, 00000000h
|
|
|
|
mov eax, posX
|
|
add eax, col
|
|
mov edx, posY
|
|
add edx, row
|
|
invoke DrawPixel, eax, edx, color
|
|
|
|
next_char_col:
|
|
shl ebx, 1
|
|
inc col
|
|
cmp col, 8
|
|
jl loop_char_col
|
|
|
|
inc row
|
|
cmp row, 8
|
|
jl loop_char_row
|
|
|
|
ret
|
|
DrawChar8x8 ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; DrawString8x8: Renders a null-terminated string
|
|
; ------------------------------------------------------------------------------
|
|
DrawString8x8 PROC uses ebx esi, posX:DWORD, posY:DWORD, pText:DWORD, color:DWORD
|
|
mov esi, pText
|
|
mov ebx, posX
|
|
|
|
loop_chars:
|
|
movzx eax, byte ptr [esi]
|
|
test al, al
|
|
jz str_done
|
|
|
|
invoke DrawChar8x8, ebx, posY, eax, color
|
|
add ebx, 8
|
|
inc esi
|
|
jmp loop_chars
|
|
|
|
str_done:
|
|
ret
|
|
DrawString8x8 ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; DrawNumber8x8: Formats and prints an unsigned integer
|
|
; ------------------------------------------------------------------------------
|
|
DrawNumber8x8 PROC uses ebx ecx edx, posX:DWORD, posY:DWORD, value:DWORD, color:DWORD
|
|
LOCAL numBuf[16]:BYTE
|
|
|
|
lea ebx, [numBuf + 15]
|
|
mov byte ptr [ebx], 0 ; null terminator
|
|
mov eax, value
|
|
|
|
format_num_loop:
|
|
xor edx, edx
|
|
mov ecx, 10
|
|
div ecx
|
|
add dl, '0'
|
|
dec ebx
|
|
mov [ebx], dl
|
|
test eax, eax
|
|
jnz format_num_loop
|
|
|
|
invoke DrawString8x8, posX, posY, ebx, color
|
|
ret
|
|
DrawNumber8x8 ENDP
|
|
|
|
; ------------------------------------------------------------------------------
|
|
; DrawMinimap: Renders top-down 2D radar overlay with player & viewing cone
|
|
; ------------------------------------------------------------------------------
|
|
DrawMinimap PROC uses ebx ecx edx esi edi
|
|
LOCAL mapStartX:DWORD, mapStartY:DWORD
|
|
LOCAL cellSize:DWORD
|
|
LOCAL mx:DWORD, my:DWORD
|
|
LOCAL pxScreen:DWORD, pyScreen:DWORD
|
|
|
|
cmp keyShowMap, 0
|
|
je minimap_done
|
|
|
|
mov mapStartX, 250 ; Top-right corner
|
|
mov mapStartY, 10
|
|
mov cellSize, 2 ; 2x2 pixels per cell (64x64 pixel radar)
|
|
|
|
; Background & Border
|
|
invoke DrawRect, mapStartX, mapStartY, 66, 66, 00101010h
|
|
invoke DrawRectOutline, mapStartX, mapStartY, 66, 66, 00FFD000h
|
|
|
|
; Draw Grid Cells
|
|
mov my, 0
|
|
loop_mm_y:
|
|
mov mx, 0
|
|
loop_mm_x:
|
|
invoke GetMapCell, mx, my
|
|
test eax, eax
|
|
jz next_mm_x
|
|
|
|
; Solid wall cell color
|
|
mov edx, 00808080h ; Gray
|
|
cmp eax, CELL_DOOR
|
|
jne @F
|
|
mov edx, 00E0A000h ; Orange door
|
|
@@:
|
|
cmp eax, CELL_DOOR_OPEN
|
|
jne @F
|
|
mov edx, 0000FF00h ; Green open door
|
|
@@:
|
|
mov eax, mx
|
|
shl eax, 1 ; mx * 2
|
|
add eax, mapStartX
|
|
inc eax
|
|
|
|
mov ecx, my
|
|
shl ecx, 1 ; my * 2
|
|
add ecx, mapStartY
|
|
inc ecx
|
|
|
|
invoke DrawRect, eax, ecx, 2, 2, edx
|
|
|
|
next_mm_x:
|
|
inc mx
|
|
cmp mx, MAP_W
|
|
jl loop_mm_x
|
|
|
|
inc my
|
|
cmp my, MAP_H
|
|
jl loop_mm_y
|
|
|
|
; Draw Player Position (Yellow dot)
|
|
mov eax, playerX
|
|
sar eax, 5 ; playerX / 32
|
|
add eax, mapStartX
|
|
inc eax
|
|
mov pxScreen, eax
|
|
|
|
mov eax, playerY
|
|
sar eax, 5 ; playerY / 32
|
|
add eax, mapStartY
|
|
inc eax
|
|
mov pyScreen, eax
|
|
|
|
invoke DrawRect, pxScreen, pyScreen, 2, 2, 00FFFF00h
|
|
|
|
; Draw Direction Cone Pointer
|
|
mov eax, playerAngle
|
|
and eax, ANGLE_MASK
|
|
mov ebx, [tableCos + eax*4]
|
|
imul ebx, 6
|
|
sar ebx, 16
|
|
add ebx, pxScreen
|
|
|
|
mov ecx, [tableSin + eax*4]
|
|
imul ecx, 6
|
|
sar ecx, 16
|
|
add ecx, pyScreen
|
|
|
|
invoke DrawPixel, ebx, ecx, 00FF0000h ; Red direction tip
|
|
|
|
minimap_done:
|
|
ret
|
|
DrawMinimap ENDP
|