📄 bg16o.asm
字号:
mov [RO16x16_BaseDestPtr],edi ; Point screen to next line
jnz .next_line
%endif
mov edx,[RO16x16_BG_Table]
mov al,[Tile_Priority_Used]
mov [Priority_Used+edx],al
mov ah,[Tile_Priority_Unused]
mov [Priority_Unused+edx],ah
add esp,byte RO16x16_Local_Bytes
ret
;%define RO16x16_Inner 4
;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high
%macro Plot_Lines_Offset_16x16_C4 2
%if %2 > 0
%%return:
ret
ALIGNC
%1_check:
pop ebx
pop esi
pop ecx
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Unused],cl
%endif
add edi,byte 8
dec cl
jz %%return
%else
ALIGNC
%endif
EXPORT_C %1 ; Define label, entry point
.next_tile:
lea eax,[esi+2]
push ecx
mov dh,[1+esi] ; Horizontal offset change map
push eax
mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
mov eax,[OffsetChangeVMap_VOffset]
test dh,ch ; H-offset enabled?
jz .have_h_offset
mov dl,[esi]
mov ebp,edx
shr ebp,3
.have_h_offset:
mov dh,[1+esi+eax] ; Vertical offset change map
test dh,ch ; V-offset enabled?
jz .No_VChange
mov dl,[esi+eax]
mov eax,[RO16x16_Current_Line+RO16x16_Inner+8]
add eax,edx
.calc_v_offset:
and ah,2
mov esi,[RO16x16_TMapAddress+RO16x16_Inner+8]
jz .line_in_screen_map_top
mov esi,[RO16x16_BMapAddress+RO16x16_Inner+8]
.line_in_screen_map_top:
; al contains real Y offset for next tile
shl eax,2 ; Get screen offset
mov ecx,0x1F0*4 ; Current line + V scroll * 32words
and ecx,eax
and eax,byte 0x0F*4 ; Offset into table of line offsets
mov edx,16*8+7
mov eax,[Tile_Offset_Table_16_8+eax]
sub edx,eax
add esi,ecx
jmp .have_v_offset
.LeftEdge:
push ecx
push esi
mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
.No_VChange:
mov eax,[LineAddress]
mov esi,[RO16x16_MapAddress_Current+RO16x16_Inner+8]
mov edx,[LineAddressY]
.have_v_offset:
add ebp,ebx
inc ebx ; Update X offset
mov [RO16x16_LineAddressOffset+RO16x16_Inner+8],eax
push ebx
mov ebx,ebp
and ebp,byte 63 ; X offset wrap
and ebx,byte 64
mov [RO16x16_LineAddressOffsetY+RO16x16_Inner+12],edx
mov ebx,[RO16x16_RMapDifference+RO16x16_Inner+12]
jz .tile_in_screen_map_left
add esi,ebx
.tile_in_screen_map_left:
mov ebx,ebp
and ebp,byte ~1
mov al,[esi+ebp+1] ; Combine X and Y offsets into tile map
Check_Tile_Priority %2, %1_check
mov si,[esi+ebp] ; Get tile #
mov ebp,[RO16x16_LineAddressOffsetY+RO16x16_Inner+12]
test al,al ; Check Y flip
js .flip_y
mov ebp,[RO16x16_LineAddressOffset+RO16x16_Inner+12]
.flip_y:
shl esi,3
mov edx,eax
add esi,ebp
and edx,byte 7*4 ; Get palette
and ebx,byte 1
add al,al ; Get X flip (now in MSB)
mov ebp,[palette_4bpl+edx]
mov edx,[TilesetAddress]
js .xflip
lea esi,[esi+ebx*8]
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 2 / 8 ; Clip to VRAM
Plot_8_Paletted_Lines_noflip 0,C_LABEL(TileCache4)+esi*8,0
pop ebx
pop esi
pop ecx
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
ALIGNC
.xflip:
shl ebx,3
add esi,byte 8
sub esi,ebx
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 2 / 8 ; Clip to VRAM
Plot_8_Paletted_Lines_Xflip 0,C_LABEL(TileCache4)+esi*8,0
pop ebx
pop esi
pop ecx
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
%endmacro
;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high
%macro Plot_Lines_Offset_16x16_C2 2
%if %2 > 0
%%return:
ret
ALIGNC
%1_check:
pop ebx
pop esi
pop ecx
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Unused],cl
%endif
add edi,byte 8
dec cl
jz %%return
%else
ALIGNC
%endif
EXPORT_C %1 ; Define label, entry point
.next_tile:
mov eax,esi
push ecx
add eax,byte 2
mov dh,[1+esi] ; Offset change map
push eax
mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
mov eax,[RO16x16_Current_Line+RO16x16_Inner+8]
test dh,ch ; Offset enabled?
jz .No_VChange
test dh,dh ; vertical offset?
jnz .calc_v_offset
mov dl,[esi]
mov ebp,edx
shr ebp,3
jmp .No_VChange
.calc_v_offset:
mov dl,[esi]
add eax,edx
and ah,2
mov esi,[RO16x16_TMapAddress+RO16x16_Inner+8]
jz .line_in_screen_map_top
mov esi,[RO16x16_BMapAddress+RO16x16_Inner+8]
.line_in_screen_map_top:
; al contains real Y offset for next tile
shl eax,2 ; Get screen offset
mov ecx,0x1F0*4 ; Current line + V scroll * 32words
and ecx,eax
and eax,byte 0x0F*4 ; Offset into table of line offsets
mov edx,16*8+7
mov eax,[Tile_Offset_Table_16_8+eax]
sub edx,eax
add esi,ecx
jmp .have_v_offset
.LeftEdge:
push ecx
push esi
mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
.No_VChange:
mov eax,[LineAddress]
mov esi,[RO16x16_MapAddress_Current+RO16x16_Inner+8]
mov edx,[LineAddressY]
.have_v_offset:
add ebp,ebx
inc ebx ; Update X offset
mov [RO16x16_LineAddressOffset+RO16x16_Inner+8],eax
push ebx
mov ebx,ebp
and ebp,byte 63 ; X offset wrap
and ebx,byte 64
mov [RO16x16_LineAddressOffsetY+RO16x16_Inner+12],edx
mov ebx,[RO16x16_RMapDifference+RO16x16_Inner+12]
jz .tile_in_screen_map_left
add esi,ebx
.tile_in_screen_map_left:
mov ebx,ebp
and ebp,byte ~1
mov al,[esi+ebp+1] ; Combine X and Y offsets into tile map
Check_Tile_Priority %2, %1_check
mov si,[esi+ebp] ; Get tile #
mov ebp,[RO16x16_LineAddressOffsetY+RO16x16_Inner+12]
test al,al ; Check Y flip
js .flip_y
mov ebp,[RO16x16_LineAddressOffset+RO16x16_Inner+12]
.flip_y:
shl esi,3
mov edx,eax
add esi,ebp
and edx,byte 7*4 ; Get palette
and ebx,byte 1
add al,al ; Get X flip (now in MSB)
mov ebp,[palette_2bpl+edx]
mov edx,[TilesetAddress]
js .xflip
lea esi,[esi+ebx*8]
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 4 / 8 ; Clip to VRAM
Plot_8_Paletted_Lines_noflip 0,C_LABEL(TileCache2)+esi*8,0
pop ebx
pop esi
pop ecx
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
ALIGNC
.xflip:
shl ebx,3
add esi,byte 8
sub esi,ebx
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 4 / 8 ; Clip to VRAM
Plot_8_Paletted_Lines_Xflip 0,C_LABEL(TileCache2)+esi*8,0
pop ebx
pop esi
pop ecx
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
%endmacro
;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high
%macro Plot_Lines_Offset_16x16_C8 2
%if %2 > 0
%%return:
ret
ALIGNC
%1_check:
pop ebx
pop esi
pop ecx
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Unused],cl
%endif
add edi,byte 8
dec cl
jz %%return
%else
ALIGNC
%endif
EXPORT_C %1 ; Define label, entry point
.next_tile:
mov eax,esi
push ecx
add eax,byte 2
mov dh,[1+esi] ; Offset change map
push eax
mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
mov eax,[RO16x16_Current_Line+RO16x16_Inner+8]
test dh,ch ; Offset enabled?
jz .No_VChange
test dh,dh ; vertical offset?
jnz .calc_v_offset
mov dl,[esi]
mov ebp,edx
shr ebp,3
jmp .No_VChange
.calc_v_offset:
mov dl,[esi]
add eax,edx
and ah,2
mov esi,[RO16x16_TMapAddress+RO16x16_Inner+8]
jz .line_in_screen_map_top
mov esi,[RO16x16_BMapAddress+RO16x16_Inner+8]
.line_in_screen_map_top:
; al contains real Y offset for next tile
shl eax,2 ; Get screen offset
mov ecx,0x1F0*4 ; Current line + V scroll * 32words
and ecx,eax
and eax,byte 0x0F*4 ; Offset into table of line offsets
mov edx,16*8+7
mov eax,[Tile_Offset_Table_16_8+eax]
sub edx,eax
add esi,ecx
jmp .have_v_offset
.LeftEdge:
push ecx
push esi
mov ebp,[RO16x16_FirstTile+RO16x16_Inner+8]
.No_VChange:
mov eax,[LineAddress]
mov esi,[RO16x16_MapAddress_Current+RO16x16_Inner+8]
mov edx,[LineAddressY]
.have_v_offset:
add ebp,ebx
inc ebx ; Update X offset
mov [RO16x16_LineAddressOffset+RO16x16_Inner+8],eax
push ebx
mov ebx,ebp
and ebp,byte 63 ; X offset wrap
and ebx,byte 64
mov [RO16x16_LineAddressOffsetY+RO16x16_Inner+12],edx
mov ebx,[RO16x16_RMapDifference+RO16x16_Inner+12]
jz .tile_in_screen_map_left
add esi,ebx
.tile_in_screen_map_left:
mov ebx,ebp
and ebp,byte ~1
mov al,[esi+ebp+1] ; Combine X and Y offsets into tile map
Check_Tile_Priority %2, %1_check
mov si,[esi+ebp] ; Get tile #
mov ebp,[RO16x16_LineAddressOffsetY+RO16x16_Inner+12]
test al,al ; Check Y flip
js .flip_y
mov ebp,[RO16x16_LineAddressOffset+RO16x16_Inner+12]
.flip_y:
shl esi,3
add esi,ebp
and ebx,byte 1
add al,al ; Get X flip (now in MSB)
mov edx,[TilesetAddress]
js .xflip
lea esi,[esi+ebx*8]
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF / 8 ; Clip to VRAM
Plot_8_Lines_noflip 0,C_LABEL(TileCache8)+esi*8,0
pop ebx
pop esi
pop ecx
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
ALIGNC
.xflip:
shl ebx,3
add esi,byte 8
sub esi,ebx
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF / 8 ; Clip to VRAM
Plot_8_Lines_Xflip 0,C_LABEL(TileCache8)+esi*8,0
pop ebx
pop esi
pop ecx
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
%endmacro
;%1 = depth
%macro Generate_Line_Plotters_Offset_16x16 1
%ifndef NO_NP_RENDER
Plot_Lines_Offset_16x16_C%1 Plot_Lines_NP_Offset_16x16_C%1,0
%endif
Plot_Lines_Offset_16x16_C%1 Plot_Lines_V_Offset_16x16_C%1,3
%endmacro
Generate_Line_Plotters_Offset_16x16 4
Generate_Line_Plotters_Offset_16x16 2
Generate_Line_Plotters_Offset_16x16 8
section .data
%macro Generate_Line_Plotter_Table_Offset_16x16 2
EXPORT_C Plot_Lines_%1_Offset_16x16_Table_C%2
dd C_LABEL(Plot_Lines_%1_Offset_16x16_C%2).LeftEdge
dd C_LABEL(Plot_Lines_%1_Offset_16x16_C%2)
%endmacro
%ifndef NO_NP_RENDER
Generate_Line_Plotter_Table_Offset_16x16 NP,4
Generate_Line_Plotter_Table_Offset_16x16 NP,2
Generate_Line_Plotter_Table_Offset_16x16 NP,8
%endif
Generate_Line_Plotter_Table_Offset_16x16 V,4
Generate_Line_Plotter_Table_Offset_16x16 V,2
Generate_Line_Plotter_Table_Offset_16x16 V,8
section .text
ALIGNC
section .data
ALIGND
section .bss
ALIGNB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -