1 ; $Header: r:/t2repos/thief2/src/portal/ptsurf.asm,v 1.15 1998/04/06 12:43:14 MAT Exp $
3 ; PORTAL Texture Mappers
19 assume cs:_TEXT
, ds:_DATA
23 _DATA
segment dword public USE32
'DATA'
38 externdef
__portal_surface_texture_row: dword
39 externdef
__portal_surface_output_row: dword
40 externdef
__portal_surface_lightmap_row: dword
41 externdef
__portal_surface_texture: dword
42 externdef
__portal_surface_output: dword
43 externdef
__portal_surface_lightmap: dword
48 _TEXT
segment para
public USE32
'CODE'
53 ; ecx bytes being processed
54 ; edx bytes being processed
197 ; ESI = texture source
198 ; EDI = output location
199 ; EDX = lightmap source
204 _FUNCDEF_ASM pt_surfbuild_16
215 mov eax, [__portal_surface_texture_row
]
217 mov ebx, [__portal_surface_output_row
]
218 mov ebp, [__portal_surface_lightmap_row
]
220 mov edx, [__portal_surface_lightmap
]
223 mov esi, [__portal_surface_texture
]
230 mov cl,[edx + ebp + 1]
235 and ebx, 0f0f0h
; mask off all but upper 4 bits of light levels
238 mov edi, [__portal_surface_output
]
241 jne pt_surfbuild_gouraud_16
245 je pt_surfbuild_uniform_16
247 pt_surfbuild_gouraud_16:
257 sub ebx,eax ; ebx == di(0)dx * 16
260 shl eax,4 ; eax == i(0)*16
263 sub edx,ecx ; edx == di(16)dx * 16
265 shl ecx,4 ; ecx == i(16)*16
266 sub edx,ebx ; edx == di(0)dxdy * 256
268 shl ebx,4 ; ebx == di(0)dx * 64
269 sub ecx,eax ; ecx == di(0)dy * 256
271 shl eax,4 ; eax == i(0)*256
278 mov ebx,_grd_light_table
283 ; eax = 0..15 * 256*16
284 ; eax derived from number from 0..255, so
294 shr edx, 28 ; round negative didx towards 0
297 mov cl,[edi] ; cache prefetch
306 mov cl,[edi] ; cache prefetch
312 ; wait for 2-cycle instructions
321 ; wait for 2-cycle instructions
324 jnz pt_surf16_looptop
326 jmp pt_surfbuild_done_16
328 pt_surfbuild_uniform_16:
330 mov ebp, _grd_light_table
338 pt_surfbuild_uniform_16_loop:
339 mov al, [edi] ; prefetch
342 ; first set of 4 texels
361 ; second set of 4 texels
380 ; third set of 4 texels
399 ; fourth set of 4 texels
418 add esi, [__portal_surface_texture_row
]
419 add edi, __portal_surface_output_row
423 jnz pt_surfbuild_uniform_16_loop
425 pt_surfbuild_done_16:
438 _FUNCDEF_ASM pt_surfbuild_8
449 mov eax, [__portal_surface_texture_row
]
451 mov ebx, [__portal_surface_output_row
]
452 mov ebp, [__portal_surface_lightmap_row
]
454 mov edx, [__portal_surface_lightmap
]
457 mov esi, [__portal_surface_texture
]
461 mov cl, [edx + ebp + 1]
469 mov edi, [__portal_surface_output
]
472 jne pt_surfbuild_gouraud_8
476 je pt_surfbuild_uniform_8
478 pt_surfbuild_gouraud_8:
488 sub ebx, eax ; ebx == di(0)dx * 16
491 shl eax, 3 ; eax == i(0)*8
494 sub edx,ecx ; edx == di(16)dx * 16
496 shl ecx,3 ; ecx == i(16)*16
497 sub edx,ebx ; edx == di(0)dxdy * 256
499 shl ebx,3 ; ebx == di(0)dx * 64
500 sub ecx,eax ; ecx == di(0)dy * 256
502 shl eax,3 ; eax == i(0)*256
509 mov ebx,_grd_light_table
521 shr edx, 30 ; round negative didx towards 0
524 mov cl,[edi] ; cache prefetch
533 ; wait for 2-cycle instructions
542 ; wait for 2-cycle instructions
547 jmp pt_surfbuild_done_8
549 pt_surfbuild_uniform_8:
551 mov ebp, [_grd_light_table
]
559 pt_surfbuild_uniform_8_loop:
560 mov al, [edi] ; prefetch
563 ; first set of 4 texels
582 ; second set of 4 texels
601 add esi, [__portal_surface_texture_row
]
602 add edi, [__portal_surface_output_row
]
605 jnz pt_surfbuild_uniform_8_loop
618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
622 _FUNCDEF_ASM pt_surfbuild_4
633 mov edi, [__portal_surface_output
]
635 mov ebp, [__portal_surface_lightmap_row
]
636 mov al, [edi] ; prefetch first row
638 mov esi, [__portal_surface_texture
]
639 mov edx, [__portal_surface_lightmap
]
641 ; setup has four light levels-- a---b
642 ; we want our results x16 | |
643 ; for our light table lookups c---d
652 mov dl, [edx + ebp + 1]
663 shl ebp, 2 ; initial didx = (-4a + 4b) / 16
666 shl ecx, 2 ; didy = (-4a + 4c) / 16
667 sub edx, ebx ; didxdy = (a - b - c + d) / 16
669 shl eax, 4 ; i0 = (16a) / 16
673 mov dl, [edi + 0999999h]; prefetch second row
676 ; eax left edge intensity
677 ; ebx first point being processed
678 ; ecx second point being processed
681 ; edi surface being built + misc.
684 lea ebx, [eax + 2 * ebp]
685 lea ecx, [eax + 2 * ebp]
687 mov bl, [esi + 2] ; We process the right-hand texels first
688 add ecx, ebp ; so we can shift them into upper 16 of edx.
693 mov dl, [ebx + 0999999h]; self-modifying reference to light table
694 gouraud_4_self_mod_1:
697 mov dh, [ecx + 0999999h]
698 gouraud_4_self_mod_2:
705 add ebp, edi ; didx += didxdy
707 mov dl, [ebx + 0999999h]
708 gouraud_4_self_mod_3:
709 mov edi, [__portal_surface_output
]
711 mov dh, [ecx + 0999999h]
712 gouraud_4_self_mod_4:
715 mov ecx, [__portal_surface_texture_row
]
716 add eax, ebx ; left edge i += didy
719 add esi, ecx ; texture pointer += texture row
721 mov dl, [edi + 0999999h] ; prefetch third row
726 lea ebx, [eax + 2 * ebp]
727 lea ecx, [eax + 2 * ebp]
729 mov bl, [esi + 2] ; We process the second pair of texels first
730 add ecx, ebp ; so we can shift them into upper 16 of edx.
735 mov dl, [ebx + 0999999h]; self-modifying reference to light table
736 gouraud_4_self_mod_5:
739 mov dh, [ecx + 0999999h]
740 gouraud_4_self_mod_6:
747 add ebp, edi ; didx += didxdy
749 mov dl, [ebx + 0999999h]
750 gouraud_4_self_mod_7:
751 mov edi, [__portal_surface_output
]
753 mov dh, [ecx + 0999999h]
754 gouraud_4_self_mod_8:
757 mov ecx, [__portal_surface_texture_row
]
758 add eax, ebx ; left edge i += didy
760 mov [edi + 0999999h], edx
762 add esi, ecx ; texture pointer += texture row
764 mov dl, [edi + 0999999h]; prefetch fourth row
769 lea ebx, [eax + 2 * ebp]
770 lea ecx, [eax + 2 * ebp]
772 mov bl, [esi + 2] ; We process the second pair of texels first
773 add ecx, ebp ; so we can shift them into upper 16 of edx.
778 mov dl, [ebx + 0999999h]; self-modifying reference to light table
779 gouraud_4_self_mod_9:
782 mov dh, [ecx + 0999999h]
783 gouraud_4_self_mod_10:
790 add ebp, edi ; didx += didxdy
792 mov dl, [ebx + 0999999h]
793 gouraud_4_self_mod_11:
794 mov edi, [__portal_surface_output
]
796 mov dh, [ecx + 0999999h]
797 gouraud_4_self_mod_12:
800 mov ecx, [__portal_surface_texture_row
]
801 add eax, ebx ; left edge i += didy
803 mov [edi + 0999999h], edx
805 add esi, ecx ; texture pointer += texture row
808 lea ebx, [eax + 2 * ebp]
809 lea ecx, [eax + 2 * ebp]
811 mov bl, [esi + 2] ; We process the second pair of texels first
812 add ecx, ebp ; so we can shift them into upper 16 of edx.
817 mov dl, [ebx + 0999999h]; self-modifying reference to light table
818 gouraud_4_self_mod_13:
821 mov dh, [ecx + 0999999h]
822 gouraud_4_self_mod_14:
831 mov dl, [ebx + 0999999h]
832 gouraud_4_self_mod_15:
835 mov dh, [ecx + 0999999h]
836 gouraud_4_self_mod_16:
842 mov [edi + 0999999h], edx
850 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
854 _FUNCDEF_ASM pt_surfbuild_2
868 ; We'll build one pixel/light combo in ecx and one in edx.
869 ; While the light for the upper-left pixel is raw data, the
870 ; light for the upper-right is the average of two values.
871 mov edi, [_grd_light_table
]
872 mov esi, [__portal_surface_lightmap
]
874 mov ebx, [__portal_surface_texture
]
875 mov al, [edi] ; prefetch
881 mov [temp_light1
], ecx ; We'll be averaging these light values
883 ; We move our light bytes into ch and dh with bit shifts to
884 ; get them down to 4 bits each.
886 mov [temp_light2
], edx ; with others for the lower pixels.
888 shl edx, 3 ; average of two lightmap points
892 mov cl, [edi + ecx] ; clut upper-left
894 mov eax, [__portal_surface_output
]
895 mov dl, [edi + edx] ; clut upper-right
900 add esi, [__portal_surface_lightmap_row
]
902 ; The light for the lower two pixels is a little more involved
903 ; since they are both averages.
910 add edx, [temp_light2
]; average of two right-hand lights
911 add ebx, [__portal_surface_texture_row
]
913 add edx, ecx ; lower-right light * 4
914 add eax, [__portal_surface_output_row
]
916 add ecx, [temp_light1
]; lower-left light * 2
918 shl edx, 2 ; average of four lightmap points
920 shl ecx, 3 ; average of two lightmap points
922 mov cl, [ebx] ; get texture points
925 mov cl, [edi + ecx] ; clut upper-left
926 mov dl, [edi + edx] ; clut upper-right
941 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
945 ; We prefetch here since this is called on seqential bytes.
947 _FUNCDEF_ASM pt_surfbuild_1
954 mov eax, [__portal_surface_lightmap
]
955 mov ebx, [__portal_surface_output
]
958 mov ecx, [__portal_surface_texture
]
960 mov dh, [eax] ; high byte is light level
961 mov al, [ebx] ; prefetch
963 shr dh, 4 ; 16 levels of shading
964 mov eax, [_grd_light_table
]
966 mov dl, [ecx] ; low byte is texture data
968 mov al, [eax + edx] ; translate light
980 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
982 ; voif pt_surfbuild_setup (void)
984 ; These set up some self-modifying offsets. Actually, only one of
987 _FUNCDEF_ASM pt_surfbuild_setup_1
990 _FUNCDEF_ASM pt_surfbuild_setup_2
993 _FUNCDEF_ASM pt_surfbuild_setup_4
997 mov eax, [_grd_light_table
]
998 mov edx, dword ptr ds:[gouraud_4_self_mod_1
- 4]
1001 je pt_surfbuild_setup_4_light_done
1003 mov dword ptr ds:gouraud_4_self_mod_1
- 4, eax
1004 mov dword ptr ds:gouraud_4_self_mod_2
- 4, eax
1005 mov dword ptr ds:gouraud_4_self_mod_3
- 4, eax
1006 mov dword ptr ds:gouraud_4_self_mod_4
- 4, eax
1007 mov dword ptr ds:gouraud_4_self_mod_5
- 4, eax
1008 mov dword ptr ds:gouraud_4_self_mod_6
- 4, eax
1009 mov dword ptr ds:gouraud_4_self_mod_7
- 4, eax
1010 mov dword ptr ds:gouraud_4_self_mod_8
- 4, eax
1011 mov dword ptr ds:gouraud_4_self_mod_9
- 4, eax
1012 mov dword ptr ds:gouraud_4_self_mod_10
- 4, eax
1013 mov dword ptr ds:gouraud_4_self_mod_11
- 4, eax
1014 mov dword ptr ds:gouraud_4_self_mod_12
- 4, eax
1015 mov dword ptr ds:gouraud_4_self_mod_13
- 4, eax
1016 mov dword ptr ds:gouraud_4_self_mod_14
- 4, eax
1017 mov dword ptr ds:gouraud_4_self_mod_15
- 4, eax
1018 mov dword ptr ds:gouraud_4_self_mod_16
- 4, eax
1020 pt_surfbuild_setup_4_light_done:
1021 mov eax, __portal_surface_output_row
1022 mov edx, dword ptr ds:[gouraud_4_self_mod_1
- 4]
1025 je pt_surfbuild_setup_4_row_done
1027 mov dword ptr ds:row_4_self_mod_1
- 4, eax
1028 mov dword ptr ds:row_4_self_mod_3
- 4, eax
1030 lea edx, [eax + eax * 2] ; row * 3
1031 add eax, eax ; row * 2
1033 mov dword ptr ds:row_4_self_mod_4
- 4, edx
1034 mov dword ptr ds:row_4_self_mod_6
- 4, edx
1036 mov dword ptr ds:row_4_self_mod_2
- 4, eax
1037 mov dword ptr ds:row_4_self_mod_5
- 4, eax
1039 pt_surfbuild_setup_4_row_done:
1046 _FUNCDEF_ASM pt_surfbuild_setup_8
1049 _FUNCDEF_ASM pt_surfbuild_setup_16
1054 ;pt_buildspan_8_pal:
1099 ; ; ESI = texture source
1100 ; ; EDI = output location
1101 ; ; EDX = lightmap source
1103 ; ; EAX = texture row
1104 ; ; EBX = output row
1105 ; ; ECX = lightmap row
1106 ;pt_surfbuild_16_pal:
1110 ; mov texture_row,eax
1113 ; mov output_row,ebx
1125 ; sub ebx,eax ; ebx == di(0)dx * 16
1126 ; mov dl,[edx+ebp+1]
1128 ; shl eax,4 ; eax == i(0)*16
1131 ; sub edx,ecx ; edx == di(16)dx * 16
1133 ; shl ecx,4 ; ecx == i(16)*16
1134 ; sub edx,ebx ; edx == di(0)dxdy * 256
1136 ; shl ebx,4 ; ebx == di(0)dx * 64
1137 ; sub ecx,eax ; ecx == di(0)dy * 256
1139 ; shl eax,4 ; eax == i(0)*256
1149 ; mov ebx,_grd_light_table
1154 ;pt_surf16_looptop_pal:
1161 ; call pt_buildspan_8_pal
1167 ; call pt_buildspan_8_pal
1169 ; add esi,texture_row
1170 ; add edi,output_row
1172 ; ; wait for 2-cycle instructions
1180 ; ; wait for 2-cycle instructions
1183 ; jnz pt_surf16_looptop_pal
1188 ;pt_surfbuild_8_pal:
1190 ; mov texture_row,eax
1192 ; mov output_row,ebx
1204 ; sub ebx,eax ; ebx == di(0)dx * 16
1205 ; mov dl,[edx+ebp+1]
1207 ; shl eax,3 ; eax == i(0)*16
1210 ; sub edx,ecx ; edx == di(16)dx * 16
1212 ; shl ecx,3 ; ecx == i(16)*16
1213 ; sub edx,ebx ; edx == di(0)dxdy * 256
1215 ; shl ebx,3 ; ebx == di(0)dx * 64
1216 ; sub ecx,eax ; ecx == di(0)dy * 256
1218 ; shl eax,3 ; eax == i(0)*256
1228 ; mov ebx,_grd_light_table
1233 ;pt_surf8_looptop_pal:
1240 ; call pt_buildspan_8_pal
1242 ; add esi,texture_row
1243 ; add edi,output_row
1245 ; ; wait for 2-cycle instructions
1253 ; ; wait for 2-cycle instructions
1256 ; jnz pt_surf8_looptop_pal