;************************************************************************************* ; MODULE: VSMAP32.ASM DATE: APRIL 20,1995 ; AUTHOR: SEAN M. KESSLER ; TARGET: 32 BIT FLAT MODEL ; FUNCTION : VIEW SYSTEM OBJECT MAPPER ; MODIFIED MARCH 9, 1998 TO HANDLE POLYGON MAPPING ;************************************************************************************* .386 .MODEL FLAT LOCALS INCLUDE ..\COMMON\COMMON.INC INCLUDE ..\ENGINE\VSMAP.INC .DATA viewData@@mViewSystem ViewSystem ? viewData@@mPrecision DD 00004000h calculateTempx MACRO mov eax,viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadians ; move cosCameraTwistRadians to eax lMul eax,bov ; multiply cosCameraTwistRadians by bov push eax ; save result mov eax,viewData@@mViewSystem.PureViewSystem@@sinCameraTwistRadians ; move sinCameraTwistRadians to eax lMul eax,acov ; multiply sinCameraTwistRadians by bov pop ebx ; restore prior result to ebx sub ebx,eax ; subtract prior result by current result movsx eax,[edi].Point3D@@xyPoint.Point@@x ; move point3D.x into ebx register lMul eax,ebx ; multiply point3D.x by result round eax ; round off result push eax ; save result mov eax,bov ; move bov into eax register neg eax ; negate bov (eax) mov ebx,viewData@@mViewSystem.PureViewSystem@@sinCameraTwistRadians ; move sinTwist to ebx lMul eax,ebx ; multiply, result to eax push eax ; save the result mov eax,viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadians ; move cosTwist to eax lMul eax,acov ; multiply, result to eax pop ebx ; restore previous result sub ebx,eax ; subtract last result from previous movsx eax,[edi].Point3D@@xyPoint.Point@@y ; move point3D.y to eax lMul eax,ebx ; multiply point3D.y by last result round eax ; round off result pop ebx ; restore first result add ebx,eax ; add to current result movsx eax,viewData@@mViewSystem.PureViewSystem@@cameraPoint.Point3D@@xyPoint.Point@@x ; move cameraPoint.x to eax sub ebx,eax ; sub out cameraPoint.x mov tempx,ebx ; move result to tempx ENDM calculateTempy MACRO mov eax,aov ; move aov to eax register neg eax ; negate aov mov ebx,viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadians ; move cosTwist to ebx lMul eax,ebx ; multiply cosTwist*aov push eax ; save result mov eax,viewData@@mViewSystem.PureViewSystem@@sinCameraTwistRadians ; move sinTwist to eax lMul eax,bcov ; sinTwist*bcov -> eax pop ebx ; restore last result sub ebx,eax ; subtract curr result from last result movsx eax,[edi].Point3D@@xyPoint.Point@@x ; move point3D.x to eax lMul eax,ebx ; multiply it out round eax ; round off result push eax ; save result mov eax,viewData@@mViewSystem.PureViewSystem@@sinCameraTwistRadians ; move sinTwist to eax lMul eax,aov ; sinTwist*aov -> eax push eax ; save result mov eax,viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadians ; move cosTwist to eax lMul eax,bcov ; cosTwist*bcov -> eax pop ebx ; restore last result sub ebx,eax ; subtract curr result from last result movsx eax,[edi].Point3D@@xyPoint.Point@@y ; move point3D.y to eax lMul eax,ebx ; multiply last result by point3D.y round eax ; round off the result pop ebx ; restore prior result add ebx,eax ; add prior result to current result push ebx ; save new result movsx ebx,[edi].Point3D@@Point@@z ; move point3D.z to ebx lMul ebx,v ; now multiply by curr v movsx ebx,viewData@@mViewSystem.PureViewSystem@@cameraPoint.Point3D@@xyPoint.Point@@y ; move cameraPoint.y to eax sub eax,ebx ; sub out last result pop ebx ; restore prior result add eax,ebx ; add prior result to current result mov tempy,eax ; store result in tempy ENDM calculateTempz MACRO mov eax,viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadians ; move cosTwistRadians to eax movsx ebx,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@x ; move focusPoint.x to ebx lMul eax,ebx ; multiply it out push eax ; save result mov eax,viewData@@mViewSystem.PureViewSystem@@sinCameraTwistRadians ; mov sinTwistRadians to eax movsx ebx,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@y ; move focusPoint.y to ebx lMul eax,ebx ; multiply it out pop ebx ; restore previous result to ebx add eax,ebx ; add previous result to current movsx ebx,[edi].Point3D@@xyPoint.Point@@x ; move point3D.x to ebx lMul eax,ebx ; multiply previous result by point3D.x round eax ; round off the result push eax ; save the result mov eax,viewData@@mViewSystem.PureViewSystem@@sinCameraTwistRadians ; move sinTwistRadians to eax movsx ebx,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@x ; mov focusPoint.x to ebx neg ebx ; negate focusPointy.x lMul eax,ebx ; multiply focusPoint.x by sinTwistRadians push eax ; save the result mov eax,viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadians ; move cosTwistRadians to eax movsx ebx,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@y ; mov focusPoint.y to ebx lMul eax,ebx ; multiply focusPoint.y by cosTwistRadians pop ebx ; restore previous result to ebx add eax,ebx ; add current result to previous result movsx ebx,[edi].Point3D@@xyPoint.Point@@y ; move point3D.y to ebx lMul eax,ebx ; multiply previous result by point3D.y round eax ; round off the result pop ebx ; restore previous result add eax,ebx ; add curent result to previous push eax ; save the result movsx eax,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@Point@@z ; mov focusPoint.z to eax movsx ebx,[edi].Point3D@@Point@@z ; mov point3D.z to ebx lMul eax,ebx ; multiply focusPoint.z by point3D.z pop ebx ; restore previous result add eax,ebx ; add current result to previous result movsx ebx,viewData@@mViewSystem.PureViewSystem@@cameraPoint.Point3D@@Point@@z ; move cameraPoint.z to ebx sub eax,ebx ; subtract cameraPoint.z from curr result mov tempz,eax ; move result to tempz ENDM calculatePoint2D MACRO LOCAL @@screenPointZero,@@return cmp tempz,0000h ; is the z-point zero ?? je @@screenPointZero ; it's zero, so set screen point to (0,0) mov eax,tempz ; move tempz into eax register lMul eax,viewData@@mPrecision ; multiply tempz by precision mov ebx,viewData@@mViewSystem.PureViewSystem@@viewPlaneDistance ; move viewPlaneDistance into ebx divide eax,ebx ; divide tempz by viewPlaneDistance push eax ; save the result ... push eax ; twice mov eax,tempx ; move tempx into eax lMul eax,viewData@@mPrecision ; multiply tempx by precision pop ebx ; restore previous result divide eax,ebx ; divide current result by previous mov [edi].Point.Point@@x,ax ; store the result into Point.x mov eax,tempy ; move tempy into eax lMul eax,viewData@@mPrecision ; multiply tempy by precision pop ebx ; restore tempz/viewPlaneDistance divide eax,ebx ; divide tempx/(tempz/viewPlaneDistance) mov [edi].Point.Point@@y,ax ; store the result into Point.y jmp @@return ; we're all done here @@screenPointZero: ; screenPointZero sync address mov [edi].Point.Point@@x,0000h ; zero out screen point-x mov [edi].Point.Point@@y,0000h ; zero out screen point-y @@return: ENDM calculateCartesianPoints MACRO LOCAL @@return cmp eax,0001h ; is mode one ?? jne @@return ; if not then return movzx eax,viewData@@mViewSystem.PureViewSystem@@viewPortWidth ; move viewPortWidth to eax divide eax,02h ; divide viewPortWidth by two movsx ebx,[edi].Point.Point@@x ; move point.x to ebx register add eax,ebx ; add (viewPortWidth/2)+point.x mov [edi].Point.Point@@x,ax ; store result back to point.x movzx eax,viewData@@mViewSystem.PureViewSystem@@viewPortHeight ; move viewPortHeight to eax divide eax,02h ; divide viewPortHeight by two movsx ebx,[edi].Point.Point@@y ; move point.y to ebx add eax,ebx ; add (viewPortHeight/2)+point.y mov [edi].Point.Point@@y,ax ; store result back to point.y @@return: ENDM initializeLocal MACRO LOCAL @@adjustValueOne,@@syncOne,@@zerCheckOne,@@zerCheckTwo,@@zerCheckThree,@@protZero,@@return xor eax,eax ; clear out eax register mov tempValue,0001h ; put one into tempValue mov ax,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@Point@@z ; move focusPoint.z to eax sMul ax,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@Point@@z ; square z-point sub tempValue,eax ; subtract result from one cmp tempValue,0000h ; compare tempValue to zero jge @@adjustValueOne ; jump if greater equal mov v,00001h ; move one into v jmp @@syncOne ; jump around next block @@adjustValueOne: ; value adjust code neg tempValue ; negate tempValue push tempValue ; push tempValue call _sqrt ; get the square root add esp,04h ; readjust the stack mov v,eax ; move sqrt into v @@syncOne: ; sync address cmp v,0000h ; is v zero ?? je @@protZero ; if it is then set locals to one movzx eax,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@x ; move focusPoint.x to eax divide eax,v ; divide focusPoint.x by v mov aov,eax ; mov result to aov movzx eax,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@y ; move focusPoint.y to eax divide eax,v ; divide focusPoint.y by v mov bov,eax ; move result to bov sMul viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@Point@@z,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@x divide eax,v ; divide result by v mov acov,eax ; move result to acov sMul viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@Point@@z,viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@y divide eax,v ; divide result by v mov bcov,eax ; move result to bcov cmp aov,0000h ; compare aov to zero jne @@zerCheckOne ; it's not zero so do next check mov aov,0001h ; it's zero so set it to one @@zerCheckOne: ; next check sync address cmp bov,0000h ; compare bov to zero jne @@zerCheckTwo ; it's not zero so do next check mov bov,0001h ; it's zero so set it to one @@zerCheckTwo: ; next check sync address cmp acov,0000h ; compare acov to zero jne @@zerCheckThree ; it's not zero so do next check mov acov,0001h ; it's zero so set it to one @@zerCheckThree: ; next check sync address cmp bcov,0000h ; compare bcov to zero jne @@return ; it's not zero so we're done mov bcov,0001h ; it's zero so set it to one jmp @@return ; we're all done checking for zero's @@protZero: ; sync address mov bov,0001h ; move one into bov mov aov,0001h ; move one into aov mov acov,0001h ; move one into acov mov bcov,0001h ; move one into bcov @@return: ; return sync address ENDM ; The seeding below allows the MaClaurin series (for square root calcualtion) to converge much ; faster than if a random seed were used. The seeding works by selecting a known square root ; value in between the selected ranges. This proves to be faster, in general, than the standard ; library square root function, and can often times be twice as fast as the standard library. firstGuess MACRO LOCAL @@seedHund,@@seedFiveHund,@@seedThousand,@@seedFiveThousand,@@seedTenThousand,@@seedFiftyThousand, \ @@seedHundThousand,@@seedFiveHundThousand,@@seedMillion,@seedFiveMillion,@@seedTemMillion,@@seedOther cmp ecx,0064h ; compare value one hundred jle @@seedHund ; jump if less equal cmp ecx,01F4h ; compare value to five hundred jle @@seedFiveHund ; jump if less equal cmp ecx,03E8h ; compare value to one thousand jle @@seedThousand ; jump if less equal cmp ecx,1388h ; compare value to five thousand jle @@seedFiveThousand ; jump if less equal cmp ecx,2710h ; compare value to ten thousand jle @@seedTenThousand ; jump if less equal cmp ecx,0C350h ; compare value to fifty thousand jle @@seedFiftyThousand ; jump if less equal cmp ecx,186A0h ; compare value to one hundred thousand jle @@seedHundThousand ; jump if less equal cmp ecx,7A120h ; compare value to five hundred thousand jle @@seedFiveHundThousand ; jump if less equal cmp ecx,0F4240h ; compare value to one million jle @@seedMillion ; jump if less equal cmp ecx,4C4B40h ; compare value to five million jle @@seedFiveMillion ; jump if less equal cmp ecx,989680h ; compare value to ten million jle @@seedTenMillion ; jump if less equal jmp @@seedOther ; jump to default seed handler @@seedHund: ; sync address mov bestGuess,0007h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedFiveHund: ; sync address mov bestGuess,0010h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedThousand: ; sync address mov bestGuess,001Bh ; set initial guess jmp @@nextGuess ; jump to next guess @@seedFiveThousand: ; sync address mov bestGuess,0037h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedTenThousand: ; sync address mov bestGuess,0057h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedFiftyThousand: ; sync address mov bestGuess,00ADh ; set initial guess jmp @@nextGuess ; jump to next guess @@seedHundThousand: ; sync address mov bestGuess,0112h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedFiveHundThousand: ; sync address mov bestGuess,0224h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedMillion: ; sync address mov bestGuess,0362h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedFiveMillion: ; sync address mov bestGuess,06C4h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedTenMillion: ; sync address mov bestGuess,0AB3h ; set initial guess jmp @@nextGuess ; jump to next guess @@seedOther: ; sync address mov bestGuess,0C5Ah ; set initial guess ENDM sMul MACRO varOne,varTwo ; short multiplication push bx ; save bx register mov ax,varOne ; move varOne into ax register mov bx,varTwo ; move varTwo into bx register imul bx ; perform the multiply result to dx:ax push ax ; save ax register result movzx eax,dx ; move dx register to eax zero extend shl eax,16 ; shift eax left by a word pop ax ; restore ax register result pop bx ; restore bx register ENDM lMul MACRO varOne,varTwo ; long multiplication push ebx ; save ebx register mov eax,varOne ; move varOne into eax register mov ebx,varTwo ; move varTwo into ebx register imul ebx ; multiply eax by ebx result to eax:edx pop ebx ; restore ebx register ENDM round MACRO varOne ; round down floating point values stored as longs LOCAL @@roundNeg,@@roundPos,@@return,@@noinc mov eax,varOne ; move varOne into eax register cmp eax,0000h ; is eax register less than zero ?? pushf ; save flags jl @@roundNeg ; if it is, we must take special measure jmp @@roundPos ; otherwise round just round it @@roundNeg: ; sync address neg eax ; negate eax @@roundPos: ; roundPos sync flag mov edx,eax ; move varOne into edx register and edx,00003FFFh ; get remainder into edx register shr eax,14 ; get whole number to eax register cmp edx,8192 ; if remainder > 8192, increment eax jle @@noinc ; otherwise skip passed increment code inc eax ; increment value in eax @@noinc: ; no increment sync address popf ; restore flags jge @@return ; if value was not negative hust return neg eax ; otherwise make it negative again @@return: ; return sync flag ENDM divide MACRO varOne,varTwo ; destroyes eax,edx,ebx LOCAL @@return,@@increment,@@zero mov ebx,varTwo ; move varTwo into ebx register cmp ebx,0000h ; are we going to divide by zero je @@zero ; if so then we'll just return zero mov eax,varOne ; move varOne into eax register cdq ; convert doubleword in eax to quadword at edx:eax idiv ebx ; divide eax/ebx result to eax, rem to edx shr ebx,01h ; divide varTwo by two cmp edx,ebx ; check to see if we have to bump eax jge @@increment ; yes we do jmp @@return ; no we dont @@zero: ; zero handler sync address xor eax,eax ; zero out the return jmp @@return ; we're done here @@increment: ; increment sync address inc eax ; increment eax @@return: ; return sync address ENDM .CODE _sqrt proc near LOCAL bestGuess:DWORD=LocalLength push ebp ; save stack frame mov ebp,esp ; create new frame sub esp,LocalLength ; adjust stack for locals mov ecx,[ebp+08h] ; move target into ecx register cmp ecx,0001h ; is target one ?? je @@noop ; is target equal to one ?? cmp ecx,0000h ; is target equal to zero ?? jle @@erop ; set error if target is less equal zero. firstGuess ; select the first guess value @@nextGuess: ; next guess sync address divide ecx,bestGuess ; divide target by best guess add eax,bestGuess ; add in best guess shr eax,0001h ; divide eax by two adc eax,0000h ; add in any carry cmp eax,bestGuess ; is the result the same, or greater, than our last result?? je @@return ; if so then we're not getting any closer mov bestGuess,eax ; result is next best guess jmp @@nextGuess ; if not then continue along @@erop: ; erop sync address xor eax,eax ; errors in which we must set return to zero jmp @@return ; jump over next handler @@noop: ; null operation sync address mov eax,0001h ; errors return one in eax register @@return: ; return sync address add esp,LocalLength ; readjust stack for locals pop ebp ; restore old stack frame retn ; return near to caller _sqrt endp _initView proc near ; void initView(ViewSystem *lpViewSystem) push ebp ; save stack frame mov ebp,esp ; create new frame push edi ; save destination index register mov edi,[ebp+08h] ; move ViewSystem offset into destination index register mov eax,[edi].PureViewSystem@@cameraTwistRadians ; move cameraTwistRadians to eax mov viewData@@mViewSystem.PureViewSystem@@cameraTwistRadians,eax ; copy same to local mov eax,[edi].PureViewSystem@@cosCameraTwistRadians ; move cosCameraTwistRadians to eax mov viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadians,eax ; copy same to local mov eax,[edi].PureViewSystem@@sinCameraTwistRadians ; move sinCameraTwistRadians to eax mov viewData@@mViewSystem.PureViewSystem@@sinCameraTwistRadians,eax ; copy same to local mov eax,[edi].PureViewSystem@@cosCameraTwistRadiansSinCameraTwistRadians ; move cosCameraTwistRadiansSinCameraTwistRadians to eax mov viewData@@mViewSystem.PureViewSystem@@cosCameraTwistRadiansSinCameraTwistRadians,eax ; copy same to local mov eax,[edi].PureViewSystem@@viewPlaneDistance ; move viewPlaneDistance to eax mov viewData@@mViewSystem.PureViewSystem@@viewPlaneDistance,eax ; copy same to local mov ax,[edi].PureViewSystem@@viewPortWidth ; move viewPortWidth to eax mov viewData@@mViewSystem.PureViewSystem@@viewPortWidth,ax ; copy same to local mov ax,[edi].PureViewSystem@@viewPortHeight ; move viewPortHeight to eax mov viewData@@mViewSystem.PureViewSystem@@viewPortHeight,ax ; copy same to local mov ax,[edi].PureViewSystem@@cameraPoint.Point3D@@xyPoint.Point@@x ; move cameraPoint.x to ax mov viewData@@mViewSystem.PureViewSystem@@cameraPoint.Point3D@@xyPoint.Point@@x,ax ; copy same to local mov ax,[edi].PureViewSystem@@cameraPoint.Point3D@@xyPoint.Point@@y ; move cameraPoint.y to ax mov viewData@@mViewSystem.PureViewSystem@@cameraPoint.Point3D@@xyPoint.Point@@y,ax ; copy same to local mov ax,[edi].PureViewSystem@@cameraPoint.Point3D@@Point@@z ; move cameraPoint.z to ax mov viewData@@mViewSystem.PureViewSystem@@cameraPoint.Point3D@@Point@@z,ax ; copy same to local mov ax,[edi].PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@x ; move focusPoint.x to ax mov viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@x,ax ; copy same to local mov ax,[edi].PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@y ; move focusPoint.y to ax mov viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@xyPoint.Point@@y,ax ; copy same to local mov ax,[edi].PureViewSystem@@focusPoint.Point3D@@Point@@z ; move focusPoint.z to ax mov viewData@@mViewSystem.PureViewSystem@@focusPoint.Point3D@@Point@@z,ax ; copy same to local pop edi ; restore destination index register pop ebp ; restore old frame retn ; return far to caller _initView endp _mapCoordinates proc near ; void mapCoordinates(const Point3D *lpPoint3D,Point *lpPoint,WORD useCartesianSystem) LOCAL tempValue:DWORD,v:DWORD,aov:DWORD,bov:DWORD,acov:DWORD,bcov:DWORD,tempx:DWORD,tempy:DWORD,tempz:DWORD=LocalLength push ebp ; save old stack frame mov ebp,esp ; create new frame sub esp,LocalLength ; adjust stack for local variables pushad ; save all general purpose registers, caller may use inline expansion mov edi,[ebp+08h] ; move (Point3D *) to destination index register initializeLocal ; initialize local variables calculateTempx ; calculate tempx value calculateTempy ; calculate tempy value calculateTempz ; calculate tempz value mov edi,[ebp+0Ch] ; move (Point*) to destination index register calculatePoint2D ; calculate the screen points mov eax,[ebp+10h] ; move mode into eax calculateCartesianPoints ; convert screen points to cartesian points (if need be) @@return: ; return sync address popad ; restore all general purpose registers add esp,LocalLength ; adjust stack for local variables pop ebp ; restore old frame retn ; return near to caller _mapCoordinates endp _mapVectorCoordinates proc near ; void mapCoordinates(const Point3D *lpPoint3D,Point *lpPoint,WORD useCartesianSystem) push ebp ; save frame mov ebp,esp ; create new frame pushad ; save all general purpose registers mov edi,[ebp+08h] ; move (Point3D *) to destination index register initializeLocal ; initialize local variables calculateTempx ; calculate tempx value calculateTempy ; calculate tempy value calculateTempz ; calculate tempz value mov edi,[ebp+0Ch] ; move (Point*) to destination index register calculatePoint2D ; calculate the screen points mov eax,[ebp+10h] ; move mode into eax calculateCartesianPoints ; convert screen points to cartesian points (if need be) mov edi,[ebp+08h] ; move (Point3D *) to destination index register add edi,size Point3D ; increment edi to point to Point3D[1] initializeLocal ; initialize local variables calculateTempx ; calculate tempx value calculateTempy ; calculate tempy value calculateTempz ; calculate tempz value mov edi,[ebp+0Ch] ; move (Point*) to destination index register add edi,size Point ; increment edi to point to Point[1] calculatePoint2D ; calculate the screen points mov eax,[ebp+10h] ; move mode into eax calculateCartesianPoints ; convert screen points to cartesian points (if need be) mov edi,[ebp+08h] ; move (Point3D *) to destination index register add edi,size Point3D*2 ; increment edi to point to Point3D[1] initializeLocal ; initialize local variables calculateTempx ; calculate tempx value calculateTempy ; calculate tempy value calculateTempz ; calculate tempz value mov edi,[ebp+0Ch] ; move (Point*) to destination index register add edi,size Point*2 ; increment edi to point to Point[1] calculatePoint2D ; calculate the screen points mov eax,[ebp+10h] ; move mode into eax calculateCartesianPoints ; convert screen points to cartesian points (if need be) mov edi,[ebp+08h] ; move (Point3D *) to destination index register add edi,size Point3D*3 ; increment edi to point to Point3D[1] initializeLocal ; initialize local variables calculateTempx ; calculate tempx value calculateTempy ; calculate tempy value calculateTempz ; calculate tempz value mov edi,[ebp+0Ch] ; move (Point*) to destination index register add edi,size Point*3 ; increment edi to point to Point[1] calculatePoint2D ; calculate the screen points mov eax,[ebp+10h] ; move mode into eax calculateCartesianPoints ; convert screen points to cartesian points (if need be) popad ; restore all general purpose registers pop ebp ; restore previous frame retn ; return near to caller _mapVectorCoordinates endp _mapPolygonCoordinates proc near ; void mapPolygonCoordinates(Polygon *pPolygon) push ebp ; save prior stack frame mov ebp,esp ; create new stack frame push esi ; save source index register push edi ; save destination index register mov esi,[ebp+08h] ; move pPolygon into source index register mov ecx,Polygon3D[esi].Polygon3D@@mBlockLine3D.BlockLine3D@@mSize ; move Line3D item count into ecx register cmp ecx,0000h ; are there any lines in the Line3D block? je @@endproc ; if not then we're done here cmp ecx,Polygon3D[esi].Polygon3D@@mBlockLine2D.BlockLine2D@@mSize ; check Line3D count against Line2D count jne @@endproc ; must have same number of Line3D's as Line2D's mov edi,Polygon3D[esi].Polygon3D@@mBlockLine3D.BlockLine3D@@mContainer ; get to Line3D container mov esi,Polygon3D[esi].Polygon3D@@mBlockLine2D.BlockLine2D@@mContainer ; get to Line2D container @@protiter: ; iteration sync address cmp edi,0000h ; is this a valid 3D container? je @@endproc ; if not then we're done here mov eax,Line3DNodePtr[edi].Line3DNodePtr@@mItem ; move Line3D ptr to eax lea eax,Line3D[eax].Line3D@@mFirstPoint ; eax contains first Point3D ptr mov ebx,Line2DNodePtr[esi].Line2DNodePtr@@mItem ; move Line2D ptr to ebx lea ebx,Line2D[ebx].Line2D@@mFirstPoint ; ebx contains first Point2D ptr push 0001h ; use cartesian coordinate system push ebx ; save Point2D ptr push eax ; save Point3D ptr call _mapCoordinates ; map the coordinates add esp,000Ch ; adjust stack after call mov eax,Line3DNodePtr[edi].Line3DNodePtr@@mItem ; move Line3D ptr to eax lea eax,Line3D[eax].Line3D@@mSecondPoint ; eax contains first Point3D ptr mov ebx,Line2DNodePtr[esi].Line2DNodePtr@@mItem ; move Line2D ptr to ebx lea ebx,Line2D[ebx].Line2D@@mSecondPoint ; ebx contains first Point2D ptr push 0001h ; use cartesian coordinate system push ebx ; save Point2D ptr push eax ; save Point3D ptr call _mapCoordinates ; map the coordinates add esp,000Ch ; adjust stack after call mov edi,Line3DNodePtr[edi].Line3DNodePtr@@mLine3DNodePtrNext ; advance to next element in Line3D block mov esi,Line2DNodePtr[esi].Line2DNodePtr@@mLine2DNodePtrNext ; advance to next element in Line2D block jmp @@protiter ; continue iteration through polygon @@endproc: ; endproc sync address pop edi ; restore destination index register pop esi ; restore source index register pop ebp ; restore previous stack frame retn ; return near to caller _mapPolygonCoordinates endp public _initView public _mapCoordinates public _mapVectorCoordinates public _mapPolygonCoordinates END