www.pudn.com > sn068s.zip > BG8.NI
section .bss
ALIGNB
LineCount8x8:skipl
section .text
%define R8x8_Local_Bytes 20
%define R8x8_Plotter esp+16
%define R8x8_BG_Table esp+12
%define R8x8_Current_Line esp+8
%define R8x8_BaseDestPtr esp+4
%define R8x8_Lines esp
%macro Render_8x8 1
ALIGNC
EXPORT_C Render_8x8_C%1
cmp byte [Mosaic+edx],0
jnz near _Render_8x8M_C%1
%ifndef NO_NP_RENDER
mov ecx,_Plot_Lines_Unclipped_NP_8x8_Table_C%1
test al,al
jnz .have_plotter
%endif
%ifndef NO_PLOTTER_PER_PRIORITY
;cmp byte [Tile_priority_bit],0
cmp [Tile_priority_bit],al
mov ecx,_Plot_Lines_Unclipped_H_8x8_Table_C%1
jz .have_plotter
mov ecx,_Plot_Lines_Unclipped_L_8x8_Table_C%1
%else
mov ecx,_Plot_Lines_Unclipped_V_8x8_Table_C%1
%endif
.have_plotter:
%if %1 == 2
mov eax,[M0_Color+edx]
mov [Palette_Base],eax
%endif
jmp short Render_8x8_Base
%endmacro
Render_8x8 2
Render_8x8 4
Render_8x8 8
ALIGNC
Render_8x8_Base:
push ecx
push edx
push ebx
push edi
push ebp
.next_line:
mov edx,[R8x8_BG_Table]
mov eax,[R8x8_Current_Line]
call Sort_Screen_Height
mov eax,[R8x8_Current_Line]
SORT_TILES_8_TALL ; This sets up the screen vert 2!
mov eax,[SetAddress+edx]
mov ebp,[R8x8_Lines]
mov [TilesetAddress],eax
cmp ebp,byte 1
je .no_multi
mov edi,[VScroll+edx]
mov eax,[R8x8_Current_Line]
add edi,eax
mov eax,8
and edi,byte 7
sub eax,edi
cmp eax,ebp
ja .no_multi
mov ebp,eax
.no_multi:
mov ecx,[R8x8_Lines]
mov eax,[R8x8_Current_Line]
sub ecx,ebp
add eax,ebp
mov [R8x8_Lines],ecx
mov edi,[R8x8_BaseDestPtr]
mov [R8x8_Current_Line],eax
mov eax,ebp
shl eax,8
lea ecx,[edi+ebp*GfxBufferLineSlack]
add eax,ecx
mov ecx,[R8x8_Plotter]
mov [R8x8_BaseDestPtr],eax
mov eax,[_SNES_Screen8]
add edi,eax
mov ecx,[ecx+ebp*4-4]
mov [LineCount8x8],ebp ;*
mov ah,[TileCount2+edx]
push ecx
push ebx
push eax
mov eax,[FirstPixel+edx]
add ebx,[VLMapAddress+edx]
sub edi,eax
mov ch,[TileCount1+edx]
%ifndef NO_EARLY_CACHE_LOAD
Cache_Load_Lines ebp,edi,edx,esi
%endif
call dword [esp+8]
mov edx,[R8x8_BG_Table+12]
pop ecx
pop ebx
test ch,ch
jz .no_second_set
add ebx,[VRMapAddress+edx]
call dword [esp]
.no_second_set:
pop ecx
%ifndef LAYERS_PER_LINE
cmp dword [R8x8_Lines],0
jnz near .next_line
%endif
mov edx,[R8x8_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 R8x8_Local_Bytes
ret
;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high, %3 = lines
%macro Plot_Lines_Unclipped_8x8_C2 3
%if %2 > 0
%%return:
ret
ALIGNC
%1_check:
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Unused],ch
%endif
add ebx,byte 2 ; Update screen pointer
add edi,byte 8
dec ch
jz %%return
%endif
EXPORT_C %1 ; Define label, entry point
%%next_tile:
mov al,[ebx+1]
Check_Tile_Priority %2, %1_check
%if %3 > 1
push ecx
mov ecx,-1
%endif
mov ebp,[LineAddressY]
test al,al ; Check Y flip
mov si,[ebx] ; Get tile #
js %%flip_y
%if %3 > 1
add ecx,byte (1 * 2)
%endif
mov ebp,[LineAddress]
%%flip_y:
shl esi,3
mov dl,al
add esi,ebp
mov ebp,[TilesetAddress]
and esi,0x3FF * 8 + 7 ; Clip to tileset
and edx,byte 7*4 ; Get palette
add esi,ebp
mov ebp,[Palette_Base]
and esi,0xFFFF * 4 / 8 ; Clip to VRAM
mov edx,[palette_2bpl+edx]
add ebx,byte 2 ; Update screen pointer
or ebp,edx ; Adjust palette for mode 0
%if %3 > 1
push ebx
mov ebx,[LineCount8x8]
%endif
add al,al ; Get X flip (now in MSB)
js near %%xflip
Plot_8_Paletted_Lines_noflip (%3),_TileCache2+esi*8,0
%if %3 > 1
pop ebx
%endif
%if %3 > 1
pop ecx
%endif
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],ch
%endif
dec ch
jnz near %%next_tile
ret
ALIGNC
%%xflip:
Plot_8_Paletted_Lines_Xflip (%3),_TileCache2+esi*8,0
%if %3 > 1
pop ebx
%endif
%if %3 > 1
pop ecx
%endif
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],ch
%endif
dec ch
jnz near %%next_tile
ret
%endmacro
;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high, %3 = lines
%macro Plot_Lines_Unclipped_8x8_C4 3
%if %2 > 0
%%return:
ret
ALIGNC
%1_check:
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Unused],ch
%endif
add ebx,byte 2 ; Update screen pointer
add edi,byte 8
dec ch
jz %%return
%endif
EXPORT_C %1 ; Define label, entry point
%%next_tile:
mov al,[ebx+1]
Check_Tile_Priority %2, %1_check
%if %3 > 1
push ecx
mov ecx,-1
%endif
mov ebp,[LineAddressY]
test al,al ; Check Y flip
mov si,[ebx] ; Get tile #
js %%flip_y
%if %3 > 1
add ecx,byte (1 * 2)
%endif
mov ebp,[LineAddress]
%%flip_y:
shl esi,3
mov dl,al
add esi,ebp
mov ebp,[TilesetAddress]
and esi,0x3FF * 8 + 7 ; Clip to tileset
and edx,byte 7*4 ; Get palette
add esi,ebp
add ebx,byte 2 ; Update screen pointer
and esi,0xFFFF * 2 / 8 ; Clip to VRAM
mov ebp,[palette_4bpl+edx]
%if %3 > 1
push ebx
mov ebx,[LineCount8x8]
%endif
add al,al ; Get X flip (now in MSB)
js near %%xflip
Plot_8_Paletted_Lines_noflip (%3),_TileCache4+esi*8,0
%if %3 > 1
pop ebx
%endif
%if %3 > 1
pop ecx
%endif
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],ch
%endif
dec ch
jnz near %%next_tile
ret
ALIGNC
%%xflip:
Plot_8_Paletted_Lines_Xflip (%3),_TileCache4+esi*8,0
%if %3 > 1
pop ebx
%endif
%if %3 > 1
pop ecx
%endif
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],ch
%endif
dec ch
jnz near %%next_tile
ret
%endmacro
;for mosaic, keep track of # pixels done, return # tiles in next set skipped
;%1 = label, %2 = priority - 0 = none, 1 = low, 2 = high, %3 = lines
%macro Plot_Lines_Unclipped_8x8_C8 3
%if %2 > 0
%%return:
ret
ALIGNC
%1_check:
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Unused],ch
%endif
add ebx,byte 2 ; Update screen pointer
add edi,byte 8
dec ch
jz %%return
%endif
EXPORT_C %1 ; Define label, entry point
%%next_tile:
mov al,[ebx+1]
Check_Tile_Priority %2, %1_check
mov si,[ebx] ; Get tile #
add ebx,byte 2 ; Update screen pointer
shl esi,3 ; 8
%if %3 > 1
push ecx
mov ecx,-1
%endif
test al,al ; Check Y flip
mov ebp,[LineAddressY]
js %%flip_y
%if %3 > 1
add ecx,byte (1 * 2)
%endif
mov ebp,[LineAddress]
%%flip_y:
add esi,ebp
mov ebp,[TilesetAddress]
and esi,0x3FF * 8 + 7 ; Clip to tileset
add esi,ebp
and esi,0xFFFF / 8 ; Clip to VRAM
%if %3 > 1
push ebx
mov ebx,[LineCount8x8]
%endif
add al,al ; Get X flip (now in MSB)
js near %%xflip
Plot_8_Lines_noflip (%3),_TileCache8+esi*8,0
%if %3 > 1
pop ebx
%endif
%if %3 > 1
pop ecx
%endif
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],ch
%endif
dec ch
jnz near %%next_tile
ret
ALIGNC
%%xflip:
Plot_8_Lines_Xflip (%3),_TileCache8+esi*8,0
%if %3 > 1
pop ebx
%endif
%if %3 > 1
pop ecx
%endif
add edi,byte 8
%if %2 == 1 || %2 == 3
mov [Tile_Priority_Used],ch
%endif
dec ch
jnz near %%next_tile
ret
%endmacro
;%1 = depth, %2 = count
%macro Generate_Line_Plotters_8x8 2
%ifndef NO_NP_RENDER
Plot_Lines_Unclipped_8x8_C%1 Plot_Lines_%2_Unclipped_NP_8x8_C%1,0,%2
%endif
%ifndef NO_PLOTTER_PER_PRIORITY
Plot_Lines_Unclipped_8x8_C%1 Plot_Lines_%2_Unclipped_L_8x8_C%1,1,%2
Plot_Lines_Unclipped_8x8_C%1 Plot_Lines_%2_Unclipped_H_8x8_C%1,2,%2
%else
Plot_Lines_Unclipped_8x8_C%1 Plot_Lines_%2_Unclipped_V_8x8_C%1,3,%2
%endif
%endmacro
%macro Generate_Line_Plotters_8x8_Depth 1
Generate_Line_Plotters_8x8 %1,1
Generate_Line_Plotters_8x8 %1,2
%endmacro
Generate_Line_Plotters_8x8_Depth 2
Generate_Line_Plotters_8x8_Depth 4
Generate_Line_Plotters_8x8_Depth 8
section .data
;%1 = type, %2 = depth
%macro Generate_Line_Plotter_Table_8x8 2
ALIGND
EXPORT_C Plot_Lines_Unclipped_%1_8x8_Table_C%2
dd _Plot_Lines_1_Unclipped_%1_8x8_C%2
dd _Plot_Lines_2_Unclipped_%1_8x8_C%2
dd _Plot_Lines_2_Unclipped_%1_8x8_C%2
dd _Plot_Lines_2_Unclipped_%1_8x8_C%2
dd _Plot_Lines_2_Unclipped_%1_8x8_C%2
dd _Plot_Lines_2_Unclipped_%1_8x8_C%2
dd _Plot_Lines_2_Unclipped_%1_8x8_C%2
dd _Plot_Lines_2_Unclipped_%1_8x8_C%2
%endmacro
%ifndef NO_NP_RENDER
Generate_Line_Plotter_Table_8x8 NP,2
Generate_Line_Plotter_Table_8x8 NP,4
Generate_Line_Plotter_Table_8x8 NP,8
%endif
%ifndef NO_PLOTTER_PER_PRIORITY
Generate_Line_Plotter_Table_8x8 L,2
Generate_Line_Plotter_Table_8x8 H,2
Generate_Line_Plotter_Table_8x8 L,4
Generate_Line_Plotter_Table_8x8 H,4
Generate_Line_Plotter_Table_8x8 L,8
Generate_Line_Plotter_Table_8x8 H,8
%else
Generate_Line_Plotter_Table_8x8 V,2
Generate_Line_Plotter_Table_8x8 V,4
Generate_Line_Plotter_Table_8x8 V,8
%endif
section .text
%include "bg8m.ni"