📄 bg16oe.asm
字号:
jmp C_LABEL(Render_16x%2_Even_C%1)
%endif ; NO_OFFSET_CHANGE
%ifdef OFFSET_CHANGE_ELIMINATION
;mode 6: 4-plane tiles, split offset table
mov cl,[OffsetChangeDetect3]
test cl,[OC_Flag+edx]
jz C_LABEL(Render_16x%2_Even_C%1)
%endif
cmp byte [Mosaic+edx],0
jnz C_LABEL(Render_Offset_16x%2M_Even_C%1)
%ifndef NO_NP_RENDER
mov ecx,C_LABEL(Plot_Lines_NP_Offset_16x%2_Even_Table_C%1)
test al,al
jnz .have_plotter
%endif
mov ecx,C_LABEL(Plot_Lines_V_Offset_16x%2_Even_Table_C%1)
.have_plotter:
push ecx
push esi
push edx ;BG_Table
push ebx ;Current_Line
push edi ;BaseDestPtr
push ebp ;Lines
sub esp,byte RO16E_Local_Bytes-24
; ch contains bit for determining planes to affect
mov ch,[OC_Flag+edx]
mov eax,[SetAddress+edx]
mov [RO16E_OC_Flag],ch
mov [TilesetAddress],eax
.next_line:
mov edx,[RO16E_BG_Table]
mov eax,[RO16E_Current_Line]
call Sort_Screen_Height
mov eax,[RO16E_Current_Line]
SORT_TILES_%2_TALL [RO16E_MapAddress_Current]
; Corrupts eax,ecx,ebp
mov eax,[TLMapAddress+edx]
mov ecx,[RO16E_Current_Line]
mov edi,[BLMapAddress+edx]
mov ebp,[VScroll+edx]
mov [RO16E_TMapAddress],eax
add ecx,ebp
mov [RO16E_BMapAddress],edi
mov ebp,[RO16E_MapAddress_Current]
and ch,(%2) / 8
;global Tile_Height
;Tile_Height equ $-1 ; 1 = 8x8, 16x8, 2 = 16x16
jz .current_line_in_screen_map_top
mov eax,edi
.current_line_in_screen_map_top:
add eax,ebp
mov ebp,[HScroll+edx]
mov [RO16E_MapAddress_Current],eax
shr ebp,3
mov eax,[TRMapAddress+edx]
add ebp,ebp
mov ecx,[TLMapAddress+edx]
mov [RO16E_FirstTile],ebp ;FirstTile = (HScroll / 8) * 2
sub eax,ecx
mov [RO16E_RMapDifference],eax
mov eax,[C_LABEL(SNES_Screen8)]
mov edi,[RO16E_BaseDestPtr]
add edi,eax
mov esi,[RO16E_Clipped]
mov al,[Win_Count+edx+esi]
test al,al
jz .done
mov ebx,[OffsetChangeMap_VOffset]
mov [RO16E_Runs_Left],eax
lea edx,[Win_Bands+edx+esi]
mov [RO16E_Output],edi
mov [RO16E_RunListPtr],edx
mov [RO16ER_VMapOffset],ebx ;vertical screen map address
xor ebx,ebx
mov bl,[edx]
xor ecx,ecx
mov cl,[edx+1]
mov edx,[RO16E_BG_Table]
sub cl,bl
setz ch
mov [RO16ER_Next_Pixel],ebx
mov [RO16ER_Pixel_Count],ecx
dec al
je .last_run
.not_last_run:
mov [RO16E_Runs_Left],al
call Render_Offset_16_Even_Run
mov edx,[RO16E_RunListPtr]
mov edi,[RO16E_Output]
xor ebx,ebx
xor ecx,ecx
mov bl,[edx+2]
mov cl,[edx+3]
add edx,byte 2
sub cl,bl
mov [RO16E_RunListPtr],edx
mov edx,[RO16E_BG_Table]
mov [RO16ER_Next_Pixel],ebx
mov [RO16ER_Pixel_Count],ecx
mov al,[RO16E_Runs_Left]
dec al
jne .not_last_run
.last_run:
call Render_Offset_16_Even_Run
.done:
%ifndef LAYERS_PER_LINE
mov edi,[RO16E_BaseDestPtr]
inc dword [RO16E_Current_Line]
add edi,GfxBufferLinePitch
dec dword [RO16E_Lines]
mov [RO16E_BaseDestPtr],edi ; Point screen to next line
jnz .next_line
%endif
mov edx,[RO16E_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 RO16E_Local_Bytes
ret
%endmacro
Render_Offset_16_Even 4,8
Render_Offset_16_Even 4,16
;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high, %3 = tile height
%macro Plot_Lines_Offset_16_Even_C4 3
%if %2 > 0
%%return:
ret
ALIGNC
%1_check:
pop ebx
pop esi
%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]
mov dh,[1+esi] ; Horizontal offset change map
push eax
mov ebp,[RO16E_FirstTile+RO16E_Inner+4]
mov eax,[OffsetChangeVMap_VOffset]
test dh,ch ; H-offset enabled?
jz .have_h_offset
mov dl,[esi]
mov ebp,edx
shr ebp,3
add ebp,ebp
.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,[RO16E_Current_Line+RO16E_Inner+4]
add eax,edx
.calc_v_offset:
and ah,(%3) / 8
mov esi,[RO16E_TMapAddress+RO16E_Inner+4]
jz .line_in_screen_map_top
mov esi,[RO16E_BMapAddress+RO16E_Inner+4]
.line_in_screen_map_top:
; al contains real Y offset for next tile
push ecx
%if %3 == 8
mov ecx,0xF8
mov edx,7
and ecx,eax
and eax,byte 7
sub edx,eax
lea esi,[esi+ecx*8] ; Get screen offset
%else
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
%endif
pop ecx
jmp .have_v_offset
.LeftEdge:
push esi
mov ebp,[RO16E_FirstTile+RO16E_Inner+4]
.No_VChange:
mov eax,[LineAddress]
mov esi,[RO16E_MapAddress_Current+RO16E_Inner+4]
mov edx,[LineAddressY]
.have_v_offset:
add ebp,ebx
add ebx,byte 2 ; Update X offset
mov [RO16E_LineAddressOffset+RO16E_Inner+4],eax
push ebx
mov ebx,ebp
and ebp,byte 31*2 ; X offset wrap
mov [RO16E_LineAddressOffsetY+RO16E_Inner+8],edx
add esi,ebp ; Combine X and Y offsets into tile map
and ebx,byte 32*2
mov ebx,[RO16E_RMapDifference+RO16E_Inner+8]
jz .tile_in_screen_map_left
add esi,ebx
.tile_in_screen_map_left:
mov al,[esi+1]
Check_Tile_Priority %2, %1_check
mov ebp,[RO16E_LineAddressOffsetY+RO16E_Inner+8]
test al,al ; Check Y flip
mov si,[esi] ; Get tile #
js .flip_y
mov ebp,[RO16E_LineAddressOffset+RO16E_Inner+8]
.flip_y:
shl esi,3
mov edx,eax
add esi,ebp
and edx,byte 7*4 ; Get palette
push esi
mov ebp,[palette_4bpl+edx]
mov edx,[TilesetAddress]
add al,al ; Get X flip (now in MSB)
js .xflip
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 2 / 8 ; Clip to VRAM
Plot_4_Even_Paletted_Lines_Clip_noflip 0,C_LABEL(TileCache4)+esi*8,0,TileClip1Left
pop esi
add esi,byte 8
mov edx,[TilesetAddress]
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 2 / 8 ; Clip to VRAM
Plot_4_Even_Paletted_Lines_Clip_noflip 0,C_LABEL(TileCache4)+esi*8,4,TileClip1Right
pop ebx
pop esi
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
ALIGNC
.xflip:
add esi,byte 8
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 2 / 8 ; Clip to VRAM
Plot_4_Even_Paletted_Lines_Clip_Xflip 0,C_LABEL(TileCache4)+esi*8,0,TileClip1Left
pop esi
mov edx,[TilesetAddress]
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,edx
and esi,0xFFFF * 2 / 8 ; Clip to VRAM
Plot_4_Even_Paletted_Lines_Clip_Xflip 0,C_LABEL(TileCache4)+esi*8,4,TileClip1Right
pop ebx
pop esi
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],cl
%endif
dec cl
jnz .next_tile
ret
%endmacro
;%1 = depth, %2 = tile height
%macro Generate_Line_Plotters_Offset_16_Even 2
%ifndef NO_NP_RENDER
Plot_Lines_Offset_16_Even_C%1 Plot_Lines_NP_Offset_16x%2_Even_C%1,0,%2
%endif
Plot_Lines_Offset_16_Even_C%1 Plot_Lines_V_Offset_16x%2_Even_C%1,3,%2
%endmacro
Generate_Line_Plotters_Offset_16_Even 4,8
Generate_Line_Plotters_Offset_16_Even 4,16
section .data
%macro Generate_Line_Plotter_Table_Offset_16_Even 3
EXPORT_C Plot_Lines_%1_Offset_16x%3_Even_Table_C%2
dd C_LABEL(Plot_Lines_%1_Offset_16x%3_Even_C%2).LeftEdge
dd C_LABEL(Plot_Lines_%1_Offset_16x%3_Even_C%2)
%endmacro
%ifndef NO_NP_RENDER
Generate_Line_Plotter_Table_Offset_16_Even NP,4,8
Generate_Line_Plotter_Table_Offset_16_Even NP,4,16
%endif
Generate_Line_Plotter_Table_Offset_16_Even V,4,8
Generate_Line_Plotter_Table_Offset_16_Even V,4,16
section .text
ALIGNC
section .data
ALIGND
section .bss
ALIGNB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -