;----------------------------------------------------------------------------- ; Monolith 22. Gouraud 888 ; ; This monolith selects code to draw either left or right. ; ; Globals (ATTENTION. Need to put in stack memory so can multi-process) ; ; uSpans - Count containing the number of spans. ; StackPos - Saves stack position. ; ; Register Usage: ; ; eax - Number of pixels to draw ; ecx - Prim pointer. Same as in non-monolithic loop code. (i.e. C codes pCtx->pPrim) ; edi - Pointer to Screen Buffer. ; ebp - Rast Span Pointer. Same as in non-monolithic loop code. (i.e. pS in C code) ; mm0 - contains four color components. ; mm1 - contains delta color components. ; mm3 - Temp for color conversion. ; mm5 - temp for color conversion. ; ; Both Left to Right and Right to Left are very similar. ; ; Psuedo Code ; ; loop: ; { ; copy mm0 to mm5 ; convert mm5 to 888. ; write color ; } ; if (done drawing) {exit loop} (dec eax / jz NoMorePixelsLtoR) ; increment colors (mm0+=mm1) ; increment screen pointer (add edi, 4) ; jump to top of loop ; ;----------------------------------------------------------------------------- INCLUDE iammx.inc INCLUDE offs_acp.inc ; Names are read LSB to MSB, so B5G6R5 means five bits of blue starting ; at the LSB, then six bits of green, then five bits of red. ;TBD check to see if this value is correct. COLOR_SHIFT equ 8 .586 .model flat ; Big seperating lines seperate code into span code ; and loop code. If span and loop are not going to ; end up being combined then it will be easy to ; seperate the code. .data ; Need externs for all of the variables that are needed for various beads EXTERN MaskRed565to888:MMWORD EXTERN MaskGreen565to888:MMWORD EXTERN MaskBlue565to888:MMWORD EXTERN MaskRed555to888:MMWORD EXTERN MaskGreen555to888:MMWORD EXTERN MaskBlue555to888:MMWORD EXTERN MaskAlpha1555to8888:MMWORD EXTERN MaskRed1555to8888:MMWORD EXTERN MaskGreen1555to8888:MMWORD EXTERN MaskBlue1555to8888:MMWORD ; TBD. I think that I want to do 0xffff instead of 0xff. This will ; have to be checked. There is a value very similiar to this in ; buf write. EXTERN SetAlphato0xffff:MMWORD EXTERN SetAlphato0xff:MMWORD ; TODO This equate are identical to the ones in texread.mas. Maybe they should be in a common .inc file. RedShift565to888 equ 8 GreenShift565to888 equ 5 BlueShift565to888 equ 3 RedShift555to888 equ 9 GreenShift555to888 equ 6 BlueShift555to888 equ 3 AlphaShift1555to8888 equ 16 RedShift1555to8888 equ 9 GreenShift1555to8888 equ 6 BlueShift1555to8888 equ 3 EXTERN Zero:MMWORD EXTERN SetAlphato0xff:MMWORD EXTERN u888to565RedBlueMask:MMWORD EXTERN u888to565GreenMask:MMWORD EXTERN u888to565Multiplier:MMWORD EXTERN uVal0x000007ff03ff07ff:MMWORD EXTERN uVal0x0000078003c00780:MMWORD EXTERN u888to555RedBlueMask:MMWORD EXTERN u888to555GreenMask:MMWORD EXTERN u888to555Multiplier:MMWORD EXTERN uVal0x000007ff07ff07ff:MMWORD EXTERN uVal0x0000078007800780:MMWORD ;----------------------------------------------------------------------------- ; Span Variables StackPos dd ? uSpans dd ? ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ; Loop Variables iSurfaceStep dd ? uPix dd ? ;----------------------------------------------------------------------------- .code PUBLIC _MMXMLRast_22 _MMXMLRast_22: push ebp mov StackPos, esp mov eax, esp sub esp, 0Ch ; This will need to change if stack frame size changes. push ebx push edi xor edi, edi ; Put pCtx into ebx mov ebx, [eax+8] ;PD3DI_RASTPRIM pP = pCtx->pPrim; mov ecx, [ebx+RASTCTX_pPrim] ; ebx is free after this since gouraud does not need information from pCtx. ;while (pP) ;{ PrimLoop: cmp ecx, 0 je ExitPrimLoop ;UINT16 uSpans = pP->uSpans; movzx eax, word ptr [ecx+RASTPRIM_uSpans] mov uSpans, eax ;PD3DI_RASTSPAN pS = (PD3DI_RASTSPAN)(pP + 1); mov ebp, ecx add ebp, SIZEOF_RASTPRIM ;while (uSpans-- > 0) ;{ SpanLoop: mov edx, uSpans mov eax, edx dec eax mov uSpans, eax test edx, edx jle ExitSpanLoop mov edi, dword ptr [ebp+RASTSPAN_pSurface] movzx eax, word ptr [ebp+RASTSPAN_uPix] ;if (pP->uFlags & D3DI_RASTPRIM_X_DEC) ;{ mov edx, [ecx+RASTPRIM_uFlags] and edx, D3DI_RASTPRIM_X_DEC test edx, edx jz LeftToRightSpan ; SCREWED UP RIGHT TO LEFT CASE movq mm0, MMWORD PTR [ebp+RASTSPAN_uB] movq mm1, MMWORD PTR [ecx+RASTPRIM_iDBDX] beginingpixelsRtoL: ;WritePixel ; Convert color. movq mm5, mm0 psrlw mm5, 8 ; Convert color1 from 8.8 two 0.8 packuswb mm5, mm7 ; pack one color1 movd edx, mm5 and edx, 000ffffffh mov [edi], edx dec eax ; Reduce Pixel count jz NoMorePixelsRtoL sub edi, 4 ; decrease destination pointer ;pS->uB += pP->iDBDX; pS->uG += pP->iDGDX; ;pS->uR += pP->iDRDX; pS->uA += pP->iDADX; paddw mm0, mm1 jmp beginingpixelsRtoL NoMorePixelsRtoL: jmp DoneSpanDirif ;else ;{ LeftToRightSpan: ; NORMAL LEFT TO RIGHT CASE movq mm0, MMWORD PTR [ebp+RASTSPAN_uB] movq mm1, MMWORD PTR [ecx+RASTPRIM_iDBDX] beginingpixelsLtoR: ;WritePixel ; Convert color. movq mm5, mm0 psrlw mm5, 8 ; Convert color1 from 8.8 two 0.8 packuswb mm5, mm7 ; pack one color1 movd edx, mm5 and edx, 000ffffffh mov [edi], edx dec eax ; Reduce Pixel count jz NoMorePixelsLtoR add edi, 4 ; Increase destination pointer. ;pS->uB += pP->iDBDX; pS->uG += pP->iDGDX; ;pS->uR += pP->iDRDX; pS->uA += pP->iDADX; paddw mm0, mm1 jmp beginingpixelsLtoR NoMorePixelsLtoR: ;} DoneSpanDirif: ; Setup Code Ends ; ---------------------------------------------------------------------------------------------------------------- ; Loop Code Begins ExitPixelLoop: ; Loop code ends ;----------------------------------------------------------------------------- ; LoopAny code ends here ;----------------------------------------------------------------------------- ;pS++; add ebp, SIZEOF_RASTSPAN ;} jmp SpanLoop ExitSpanLoop: ;pP = pP->pNext; mov ecx, [ecx+RASTPRIM_pNext] ;} jmp PrimLoop ExitPrimLoop: ;_asm{ emms ;} ;return S_OK; xor eax, eax ;} pop edi pop ebx mov esp, StackPos pop ebp ret END