mirror of https://github.com/nmlgc/ReC98.git
181 lines
4.2 KiB
NASM
181 lines
4.2 KiB
NASM
.186
|
|
.model use16 large
|
|
locals
|
|
|
|
include libs/master.lib/macros.inc
|
|
include th01/math/subpixel.inc
|
|
include th03/common.inc
|
|
include th03/main/playfld.inc
|
|
include th03/main/collmap.inc
|
|
|
|
extrn _collmap_topleft:Point
|
|
extrn _collmap_stripe_tile_w:word
|
|
extrn _collmap_tile_h:word
|
|
extrn _collmap_bottomright:Point
|
|
extrn _collmap_pid:byte
|
|
extrn _collmap:byte:(PLAYER_COUNT * COLLMAP_SIZE)
|
|
|
|
; Sets @@dst to the offset of column @@x inside [collmap].
|
|
offset_x macro @@dst:req, @@x:req
|
|
if ((@@dst eq ax) and (@@x eq al))
|
|
; MODDERS: This performs a 8→16-bit multiplication of AX = (AH * AL).
|
|
; Effectively limits both COLLMAP_H and COLLMAP_MEMORY_W to 8 bits!
|
|
mov ah, COLLMAP_H
|
|
mul ah
|
|
else
|
|
.err "Come on, just rewrite this in C++."
|
|
endif
|
|
endm
|
|
|
|
MAIN_04 group COLLMAP_TEXT
|
|
|
|
.code
|
|
assume cs:MAIN_04
|
|
|
|
public _collmap_set_vline
|
|
_collmap_set_vline proc far
|
|
@@pattern equ <ah>
|
|
@@first_bit equ <cl>
|
|
@@first_bit_wide equ <cx> ; Just remove this
|
|
@@rows_from_bottom equ <dx> ; Ensures clipping at the bottom edge
|
|
@@collmap_p equ <bx>
|
|
|
|
mov ax, _collmap_topleft.x
|
|
mov dx, _collmap_topleft.y
|
|
|
|
; Clip
|
|
or ax, ax
|
|
js short @@ret
|
|
cmp ax, (PLAYFIELD_W shl 4)
|
|
jge short @@ret
|
|
or dx, dx
|
|
js short @@ret
|
|
cmp dx, (PLAYFIELD_H shl 4)
|
|
jge short @@ret
|
|
|
|
xor @@collmap_p, @@collmap_p
|
|
cmp _collmap_pid, 0
|
|
jz short @@set_collmap_p
|
|
mov @@collmap_p, COLLMAP_SIZE
|
|
|
|
@@set_collmap_p:
|
|
add @@collmap_p, offset _collmap
|
|
|
|
sar ax, (SUBPIXEL_BITS + COLLMAP_TILE_W_BITS)
|
|
sar dx, (SUBPIXEL_BITS + COLLMAP_TILE_H_BITS)
|
|
|
|
mov @@first_bit_wide, ax ; first_bit = AX;
|
|
sar ax, 3 ; AX /= 8; (bits per byte)
|
|
and @@first_bit_wide, (8 - 1) ; first_bit &= (8 - 1);
|
|
add @@collmap_p, dx ; collmap_p += (
|
|
offset_x ax, al ; DX + (AX * COLLMAP_H)
|
|
add @@collmap_p, ax ; );
|
|
|
|
mov ax, COLLMAP_H
|
|
sub ax, dx
|
|
mov @@rows_from_bottom, ax
|
|
mov @@pattern, 80h
|
|
shr @@pattern, @@first_bit
|
|
mov cx, _collmap_tile_h
|
|
even
|
|
|
|
@@row_loop:
|
|
or [@@collmap_p], @@pattern
|
|
inc @@collmap_p
|
|
dec @@rows_from_bottom
|
|
loopne @@row_loop
|
|
|
|
@@ret:
|
|
ret
|
|
_collmap_set_vline endp
|
|
even
|
|
|
|
|
|
public _collmap_set_slope_striped
|
|
_collmap_set_slope_striped proc c far
|
|
uses si, di
|
|
@@collmap_p equ <bx>
|
|
@@first_bit equ <cl>
|
|
@@first_bit_wide equ <cx> ; Just remove this
|
|
@@left equ <si>
|
|
@@y_double equ <di>
|
|
|
|
SLOPE_STRIPES = (COLLMAP_H / COLLMAP_SLOPE_VSTRIPE_DISTANCE)
|
|
|
|
mov bx, (COLLMAP_H - 1)
|
|
cmp _collmap_pid, 0
|
|
jz short @@set_collmap_base
|
|
add bx, COLLMAP_SIZE
|
|
|
|
@@set_collmap_base:
|
|
add bx, offset _collmap
|
|
mov @@collmap_p_base_player_and_row, bx
|
|
|
|
; @@pattern = ~(0xFF >> collmap_sprite_tile_w);
|
|
; AH needs to be 0x00 for the carry pixel rotate trick below.
|
|
mov al, 11111111b
|
|
mov cx, _collmap_stripe_tile_w
|
|
shr al, cl
|
|
not al
|
|
xor ah, ah
|
|
mov @@pattern, ax
|
|
|
|
mov ax, _collmap_bottomright.x
|
|
sub ax, _collmap_topleft.x
|
|
mov @@slope_subpixel_w, ax
|
|
jmp short $+2
|
|
mov @@left, _collmap_bottomright.x
|
|
mov @@y_double, (SLOPE_STRIPES - 1)
|
|
even
|
|
|
|
@@row_loop:
|
|
mov ax, @@left
|
|
shr ax, (SUBPIXEL_BITS + COLLMAP_TILE_W_BITS)
|
|
mov @@first_bit_wide, ax
|
|
and @@first_bit_wide, 7
|
|
shr ax, 3 ; AX = ((AX / BYTE_DOTS) * COLLMAP_H)
|
|
offset_x ax, al ;
|
|
|
|
@@collmap_p_base_player_and_row = word ptr $+1
|
|
mov @@collmap_p, 1234h
|
|
add @@collmap_p, ax
|
|
|
|
; Right-rotate the pattern by [first_bit]. If the pattern then extends into
|
|
; a second bitmap byte, that byte's pattern will end up in AH.
|
|
@@pattern = word ptr $+1
|
|
mov ax, 1234h
|
|
ror ax, @@first_bit
|
|
or [@@collmap_p], al
|
|
or ah, ah
|
|
jz short @@skip_blank
|
|
add @@collmap_p, COLLMAP_H
|
|
or [@@collmap_p], ah
|
|
|
|
@@skip_blank:
|
|
dec @@y_double
|
|
jz short @@ret
|
|
|
|
; Interpolate new left X coordinate
|
|
;
|
|
; left = (collmap_topleft.x + (
|
|
; static_cast<long>(slope_subpixel_w * y_double) / SLOPE_STRIPES
|
|
; ));
|
|
@@slope_subpixel_w = word ptr $+1
|
|
mov ax, 1234h
|
|
imul @@y_double
|
|
mov cx, SLOPE_STRIPES
|
|
idiv cx ; 32-bit division of DX:AX by CX!
|
|
mov @@left, _collmap_topleft.x
|
|
add @@left, ax
|
|
|
|
sub @@collmap_p_base_player_and_row, COLLMAP_SLOPE_VSTRIPE_DISTANCE
|
|
jmp short @@row_loop
|
|
; ---------------------------------------------------------------------------
|
|
|
|
@@ret:
|
|
ret
|
|
_collmap_set_slope_striped endp
|
|
even
|
|
|
|
end
|