void polymap (float *x, float *y, float *z, char nv, Uchar tinta)
{
	if (nv<3 || nv>4) return;
	float tempXsize = XSIZE;
	float tempYsize = YSIZE;

	char  _flares = flares;
	float _uno = 1;

	char  culling = culling_needed;
	char  halfscan = halfscan_needed;

	Word   vr22;
	Dword  bndx;

	Word   i, sections;

	Dword  i_low_lim = -10000;
	Dword  i_hig_lim = +10000;

	Dword  u, v, min_y, max_y;
	Dword  x1, y1, x2, y2, ity, jty;

	float k1, k2, k3, k4;
	float hx, vx, ox, hy, vy, oy, hz, vz, oz, _x, _y, _z;
	float kx, rx, ry, rz, mx, my, mz, nx, ny, nz, xx, yy, zz;

	float midx, midy, midz;
	float trxf[4], tryf[4], trzf[4];

	#ifdef WINDOWS
	Dword min_xDW = min_x;
	Dword max_xDW = max_x;
	#endif
	
	// Polymap ha routines fatte per 4 vertici.
	// Se sono 3, l'ultimo va duplicato.

	if (nv==3) {
		x[3] = x[2];
		y[3] = y[2];
		z[3] = z[2];
	}

	// Rototraslazione dei vertici; i dati rimangono ancora 3d.
	
	asm	{
			#ifdef WINDOWS
			pushad
			#endif
			mov doflag, 0
			// if (gamma)
			MOV_EAX_DWORD_PTR _0
			CMP_EAX_DWORD_PTR gamma
			jne t_axis
			jmp no_t_axis }							//	Note: Something in this comments here is seemingly incorrect, but I don't know what. Now that I have this code working, attempting to translate it to C++ is no longer necessary, so I don't need to bother trying to figure out what was mistranslated here. (SL)
	t_axis: asm {   xor MAYBE_EDI, MAYBE_EDI		//	di=0; si=0;
			xor MAYBE_ESI, MAYBE_ESI }
       _vertex: asm {								//	do {		//Or for (di=0, si=0; di!=4; si+=4, di++) {
       		L_DWORD_PTR(es, MAYBE_EBX, z)
		   	fld dword ptr SEGVAR(es, MAYBE_EBX+MAYBE_ESI)
		    fsub cam_z								//		FPa -= cam_z
			fst zz									//		zz = FPa
			fmul opt_tsinbeta						//		FPa *= opt_tsinbeta
			L_DWORD_PTR(es, MAYBE_EBX, x)
		   	fld dword ptr SEGVAR(es, MAYBE_EBX+MAYBE_ESI)
			fsub cam_x								//		FPb -= cam_x
			fst xx									//		xx = FPb
			fmul opt_tcosbeta						//		FPb *= opt_tcosbeta
			faddp									//		FBb += FPa				//FPb is now ST(0) and FPa no longer exists.
			fstp dword ptr rxf[MAYBE_ESI]					//		rxf[si/4] = FPb			//The FP stack is now empty, FPb no longer exists.
			fld zz									//		FPc = zz					//FPc is now ST(0)
			fmul opt_tcosbeta						//		FPc *= opt_tcosbeta
			fld xx									//		FPd = xx					//FPc is now ST(1) and FPb is now ST(0)
			fmul opt_tsinbeta						//		FPd *= opt_tsinbeta
			fsubp									//		FPc -= FPd					//FPc is now ST(0) and FPd no longer exists.
			fst z2									//		z2 = FPc
			fmul opt_tcosalfa						//		FPc *= opt_tcosalfa
			L_DWORD_PTR(es, MAYBE_EBX, y)
		    fld dword ptr SEGVAR(es, MAYBE_EBX+MAYBE_ESI)				//		FPe = (Dword) y[si/4]		//FPe is now ST(0) and FPc is now FP(1)
			fsub cam_y								//		FPe -= cam_y
			fst yy									//		yy = FPe
			fmul opt_tsinalfa						//		FPe *= opt_tsinalfa
			faddp									//		FPc += FPe					//FPc is now ST(0) and FPe no longer exists.
			fst dword ptr rzf[MAYBE_ESI]					//		((Dword[])rzf)[si/4] = FPc
			fcomp uneg								//		lessThanUneg = (FPc<uneg);		//fcomp compares, fstsw stores status word in ax, and sahf later loads it into eflags, so a jb can be done.	//This also pops FPc off the PF stack, leaving it empty
			fstsw ax								
			fld yy									//		FPf = yy						//FPf is ST(0) now
			fmul opt_tcosalfa						//		FPf *= opt_tcosalfa
			fld z2									//		FPg = z2						//FPf is now ST(1), FPg is ST(0)
			fmul opt_tsinalfa						//		FPg *= opt_tsinalfa
			fsubp									//		FPf -= FPg						//FPf is now ST(0), FPg no longer exists.
			fst my									//		my = FPf
			fmul opt_tcosgamma						//		FPf *= opt_tcosgamma
			fld dword ptr rxf[MAYBE_ESI]					//		FPh = ((Dword[])rxf)[si/4]		//FPh is now ST(0), FPf is now ST(1)
			fmul opt_tsingamma						//		FPh *= opt_tsingamma
			fsubp									//		FPf -= FPh						//FPf is now ST(0), FPh no longer exists.
			fstp dword ptr ryf[MAYBE_ESI]					//		((Dword[])ryf)[si/4] = FPf		//FPf no longer exists
			fld my									//		FPi = my
			fmul opt_tsingamma						//		FPi *= opt_tsingamma
			fld dword ptr rxf[MAYBE_ESI]					//		FPj = ((Dword[])rxf)[si/4]		//FPj is now ST(0), FPi is now ST(1)
			fmul opt_tcosgamma						//		FPj *= opt_tcosgamma
			faddp									//		FPi += FPj						//FPi is now ST(0), FPj no longer exists
			fstp dword ptr rxf[MAYBE_ESI]					//		rxf[si/4] = FPi					//FPi no longer exists, stack is empty.
			sahf
			jb _rzf_min_uneg						//		if (!lessThanUneg) {
			inc doflag								//			doflag++;
			mov byte ptr rwf[MAYBE_EDI], 1			//			((byte[])rwf)[di] = 1
			jmp _convert }							//		} else {
 _rzf_min_uneg: asm     mov byte ptr rwf[MAYBE_EDI], 0	//		((byte[])rwf)[di] = 0
      _convert: asm {   add MAYBE_ESI, 4			//		}
			inc MAYBE_EDI							//		si+=4; di++;
			cmp MAYBE_EDI, 4						//	}
			je _end_convert
			jmp _vertex }
  _end_convert: asm	jmp end_convert
	no_t_axis: asm {   
			xor MAYBE_EDI, MAYBE_EDI
			xor MAYBE_ESI, MAYBE_ESI }
	vertex: asm {
			L_DWORD_PTR(es, MAYBE_EBX, z)
			fld dword ptr SEGVAR(es, MAYBE_EBX+MAYBE_ESI)
			fsub cam_z
			fst zz
			fmul opt_tsinbeta
			L_DWORD_PTR(es, MAYBE_EBX, x)
			fld dword ptr SEGVAR(es, MAYBE_EBX+MAYBE_ESI)
			fsub cam_x
			fst xx
			fmul opt_tcosbeta
			faddp
			fstp dword ptr rxf[MAYBE_ESI]
			fld zz
			fmul opt_tcosbeta
			fld xx
			fmul opt_tsinbeta
			fsubp
			fst z2
			fmul opt_tcosalfa
			L_DWORD_PTR(es, MAYBE_EBX, y)
			fld dword ptr SEGVAR(es, MAYBE_EBX+MAYBE_ESI)
			fsub cam_y
			fst yy
			fmul opt_tsinalfa
			faddp
			fst dword ptr rzf[MAYBE_ESI]
			fcomp uneg
			fstsw ax
			fld yy
			fmul opt_tcosalfa
			fld z2
			fmul opt_tsinalfa
			fsubp
			fstp dword ptr ryf[MAYBE_ESI]
			sahf
			jb rzf_min_uneg
			inc doflag
			mov byte ptr rwf[MAYBE_EDI], 1
			jmp convert }
  rzf_min_uneg: asm     mov byte ptr rwf[MAYBE_EDI], 0
       convert: asm {   add MAYBE_ESI, 4
			inc MAYBE_EDI
			cmp MAYBE_EDI, 4
			je end_convert
			jmp vertex }

   end_convert: asm {// if (!doflag) return;
			cmp doflag, 0
			jne vectors
		#ifdef WINDOWS
	   	popad
	   	#endif
	   }

		return;
	// Calcolo dei vettori di tracciamento del texture mapping.
	#ifdef WINDOWS
	int num;
	#endif
       vectors:
	   	#ifdef WINDOWS
		asm popad
	   	Dword esiTmp = 0;
		#endif
		if (nv == 3) {
			midx = (rxf[0] + rxf[1] + rxf[2]) * 0.3333333;
			midy = (ryf[0] + ryf[1] + ryf[2]) * 0.3333333;
			midz = (rzf[0] + rzf[1] + rzf[2]) * 0.3333333;
			for (vr = 0; vr < 3; vr++) {
				trxf[vr] = (rxf[vr] - midx) * x_antialias + midx;
				tryf[vr] = (ryf[vr] - midy) * y_antialias + midy;
				trzf[vr] = (rzf[vr] - midz) * z_antialias + midz;
			}
			#ifdef WINDOWS
			num = 2;
			esiTmp = 8;	//_ESI = 8;
			#else
			_SI = 8;
			#endif
		}
		else {
			midx = (rxf[0] + rxf[1] + rxf[2] + rxf[3]) * 0.25;
			midy = (ryf[0] + ryf[1] + ryf[2] + ryf[3]) * 0.25;
			midz = (rzf[0] + rzf[1] + rzf[2] + rzf[3]) * 0.25;
			for (vr = 0; vr < 4; vr++) {
				trxf[vr] = (rxf[vr] - midx) * x_antialias + midx;
				tryf[vr] = (ryf[vr] - midy) * y_antialias + midy;
				trzf[vr] = (rzf[vr] - midz) * z_antialias + midz;
			}
			#ifdef WINDOWS
			num = 3;
			esiTmp = 12;	//_ESI = 12;
			#else
			_SI = 12;
			#endif
		}
		/*#ifdef WINDOWS
		rx = trxf[0];
		mx = trxf[1]-rx;
		nx = rx - trxf[num];
		ry = tryf[0];
		my = tryf[1] - ry;
		ny = ry - tryf[num];
		rz = trzf[0];
		mz = trzf[1] - rz;
		nz = rz - trzf[num];
		#else*/
		asm {
			#ifdef WINDOWS
			pushad
			mov esi, esiTmp
			#endif
			// rx = rxf[0];
			fld dword ptr trxf[0]
			fstp rx
		     //	mx = rxf[1] - rx;
			fld dword ptr trxf[4]
			fsub rx
			fstp mx
		     //	nx = rx - rxf[3];
			fld rx
			fsub dword ptr trxf[LOCALVAR MAYBE_ESI]	//[ebp+MAYBE_ESI] assembles to the result we want, but that's due to the "feature" which makes [MAYBE_ESI] assemble wrong...
			fstp nx
		     //	ry = ryf[0];
			fld dword ptr tryf[0]
			fstp ry
		     //	my = ryf[1] - ry;
			fld dword ptr tryf[4]
			fsub ry
			fstp my
		     //	ny = ry - ryf[3];
			fld ry
			fsub dword ptr tryf[LOCALVAR MAYBE_ESI]
			fstp ny
		     //	rz = rzf[0];
			fld dword ptr trzf[0]
			fstp rz
		     //	mz = rzf[1] - rz;
			fld dword ptr trzf[4]
			fsub rz
			fstp mz
		     //	nz = rz - rzf[3];
			fld rz
			fsub dword ptr trzf[LOCALVAR MAYBE_ESI]
			fstp nz
		//#endif
			// hx = (rx * mz - rz * mx) * YCOEFF;
			fld rx
			fmul mz
			fld rz
			fmul mx
			fsubp
			fmul YCOEFF
			fstp hx
		     // hy = (rx * nz - rz * nx) * YCOEFF;
			fld rx
			fmul nz
			fld rz
			fmul nx
			fsubp
			fmul YCOEFF
			fstp hy
		     // hz = (nx * mz - nz * mx) / dpp;
			fld nx
			fmul mz
			fld nz
			fmul mx
			fsubp
			fmul inv_dpp
			fstp hz
		     //	vx = (rz * my - ry * mz) * XCOEFF;
			fld rz
			fmul my
			fld ry
			fmul mz
			fsubp
			fmul XCOEFF
			fstp vx
		     //	vy = (rz * ny - ry * nz) * XCOEFF;
			fld rz
			fmul ny
			fld ry
			fmul nz
			fsubp
			fmul XCOEFF
			fstp vy
		     //	vz = (nz * my - ny * mz) / dpp;
			fld nz
			fmul my
			fld ny
			fmul mz
			fsubp
			fmul inv_dpp
			fstp vz
		     //	ox = (ry * mx - rx * my) * EMU_K;
			fld ry
			fmul mx
			fld rx
			fmul my
			fsubp
			fmul EMU_K
			fstp ox
		     //	oy = (ry * nx - rx * ny) * EMU_K;
			fld ry
			fmul nx
			fld rx
			fmul ny
			fsubp
			fmul EMU_K
			fstp oy
		     //	oz =  ny * mx - nx * my;
			fld ny
			fmul mx
			fld nx
			fmul my
			fsubp
			fstp oz }

	// Fast-load per poligoni completamente visibili.

		asm {// if (doflag==4) {
			cmp doflag, 4
			jne z_clipping
			xor MAYBE_ESI, MAYBE_ESI
			mov MAYBE_ECX, 4
			mov vr2, 4
			mov vr22, 8 }
	load:   asm {
			MOV_EAX_DWORD_PTR rxf[MAYBE_ESI]
			MOV_EBX_DWORD_PTR ryf[MAYBE_ESI]
			MOV_EDX_DWORD_PTR rzf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_x[MAYBE_ESI], MAYBE_EAX
			MOV_DWORD_PTR ultima_y[MAYBE_ESI], MAYBE_EBX
			MOV_DWORD_PTR ultima_z[MAYBE_ESI], MAYBE_EDX
			
			add MAYBE_ESI, 4
			#ifdef WINDOWS
		  	and esi, 0xffff
		  	#endif
			dec MAYBE_ECX
			jnz load
			jmp to_2d }

	/* Conversione punti alle spalle dell'osservatore
	   rispetto al piano dello schermo. */

    z_clipping: asm {
			mov vr, 0
			xor MAYBE_EDI, MAYBE_EDI
			mov dx, 4
			dec dx }
     the_for_1: asm {
		 	MOVZX_MAYBE_ESI, vr
			cmp byte ptr rwf[MAYBE_ESI], 0
			je CONT1
			jmp bypass }
      CONT1:    asm {   mov ax, vr
			sub ax, 1
			jnc pvert1ok
			mov pvert, dx
			jmp pvert1no }
      pvert1ok: asm     mov pvert, ax
      pvert1no: asm {   mov ax, vr
			inc ax
			cmp ax, dx
			jbe nvert1ok
			mov nvert, 0
			jmp nvert1no }
      nvert1ok: asm     mov nvert, ax
      nvert1no: asm {
		  	MOVZX_MAYBE_ESI, pvert
			cmp byte ptr rwf[MAYBE_ESI], 0
			je ctrl1
			jmp JMPR11 }
      ctrl1:    asm {
		  	MOVZX_MAYBE_ESI, nvert
			cmp byte ptr rwf[MAYBE_ESI], 0
			jne JMPR11
			jmp STOP1 }
      JMPR11:   asm {
		  	mov bx, vr
			shl bx, 2
			MOVZX_MAYBE_ESI, pvert
			mov al, byte ptr rwf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			add al, byte ptr rwf[MAYBE_ESI]
			cmp al, 2
			je if11
			jmp else11 }
      if11:     asm {
		  	shl pvert, 2
			shl nvert, 2
			MOVZX_MAYBE_ESI, bx
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, pvert
			fcomp dword ptr rzf[MAYBE_ESI]
			fstsw ax
			sahf
			jne if12
			jmp else12 }
      if12:     asm {
		  	fld dword ptr uneg
			fsub dword ptr rzf[MAYBE_ESI]
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, bx
			fsubr dword ptr rzf[MAYBE_ESI]
			fdivp
			fst zk
			fld dword ptr rxf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, pvert
			fsub dword ptr rxf[MAYBE_ESI]
			fmulp
			fadd dword ptr rxf[MAYBE_ESI]
			fstp dword ptr ultima_x[MAYBE_EDI]
			fld zk
			MOVZX_MAYBE_ESI, bx
			fld dword ptr ryf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, pvert
			fsub dword ptr ryf[MAYBE_ESI]
			fmulp
			fadd dword ptr ryf[MAYBE_ESI]
			fstp dword ptr ultima_y[MAYBE_EDI]
			jmp JMPR12 }
      else12:   asm {
		  	MOVZX_MAYBE_ESI, bx
			MOV_EAX_DWORD_PTR rxf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_x[MAYBE_EDI], MAYBE_EAX
			MOV_EAX_DWORD_PTR ryf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_y[MAYBE_EDI], MAYBE_EAX
			}
      JMPR12:   asm {
      		MOV_EAX_DWORD_PTR uneg
			MOV_DWORD_PTR ultima_z[MAYBE_EDI], MAYBE_EAX
			MOVZX_MAYBE_ESI, bx
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			fcomp dword ptr rzf[MAYBE_ESI]
			fstsw ax
			sahf
			jne neq1
			jmp eq1 }
      neq1:     asm {
			fld dword ptr uneg
			fsub dword ptr rzf[MAYBE_ESI]
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, bx
			fsubr dword ptr rzf[MAYBE_ESI]
			fdivp
			fst zk
			fld dword ptr rxf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			fsub dword ptr rxf[MAYBE_ESI]
			fmulp
			fadd dword ptr rxf[MAYBE_ESI]
			fstp dword ptr ultima_x[MAYBE_EDI+4]
			fld zk
			MOVZX_MAYBE_ESI, bx
			fld dword ptr ryf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, nvert
			fsub dword ptr ryf[MAYBE_ESI]
			fmulp
			fadd dword ptr ryf[MAYBE_ESI]
			fstp dword ptr ultima_y[MAYBE_EDI+4]
			jmp JMPR13 }
      eq1:      asm {
		  	MOVZX_MAYBE_ESI, bx
			MOV_EAX_DWORD_PTR rxf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_x[MAYBE_EDI+4], MAYBE_EAX
			MOV_EAX_DWORD_PTR ryf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_y[MAYBE_EDI+4], MAYBE_EAX }
      JMPR13:   asm {
		  	MOV_EAX_DWORD_PTR uneg
			MOV_DWORD_PTR ultima_z[MAYBE_EDI+4], MAYBE_EAX
			add MAYBE_EDI, 8
			jmp STOP1 }
      else11:   asm {
		  	MOVZX_MAYBE_ESI, pvert
			cmp byte ptr rwf[MAYBE_ESI], 0
			jne vpvert1
			mov ax, nvert
			mov vvert, ax
			jmp vnvert1 }
      vpvert1:  asm {
		  	mov ax, pvert
			mov vvert, ax }
      vnvert1:  asm {
		  	shl vvert, 2
			MOVZX_MAYBE_ESI, bx
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, vvert
			fcomp dword ptr rzf[MAYBE_ESI]
			fstsw ax
			sahf
			jne neq2
			jmp eq2 }
      neq2:     asm {
		  	fld dword ptr uneg
			fsub dword ptr rzf[MAYBE_ESI]
			fld dword ptr rzf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, bx
			fsubr dword ptr rzf[MAYBE_ESI]
			fdivp
			fst zk
			fld dword ptr rxf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, vvert
			fsub dword ptr rxf[MAYBE_ESI]
			fmulp
			fadd dword ptr rxf[MAYBE_ESI]
			fstp dword ptr ultima_x[MAYBE_EDI]
			fld zk
			MOVZX_MAYBE_ESI, bx
			fld dword ptr ryf[MAYBE_ESI]
			MOVZX_MAYBE_ESI, vvert
			fsub dword ptr ryf[MAYBE_ESI]
			fmulp
			fadd dword ptr ryf[MAYBE_ESI]
			fstp dword ptr ultima_y[MAYBE_EDI]
			jmp JMPR14 }
      eq2:      asm {
		  	MOVZX_MAYBE_ESI, bx
			MOV_EAX_DWORD_PTR rxf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_x[MAYBE_EDI], MAYBE_EAX
			MOV_EAX_DWORD_PTR ryf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_y[MAYBE_EDI], MAYBE_EAX }
      JMPR14:   asm {
		  	MOV_EAX_DWORD_PTR uneg
			MOV_DWORD_PTR ultima_z[MAYBE_EDI], MAYBE_EAX
			add MAYBE_EDI, 4
			#ifdef WINDOWS
		  	and edi, 0xffff
		  	#endif
			jmp STOP1 }
      bypass:   asm {
		  	shl MAYBE_ESI, 2
		  	#ifdef WINDOWS
		  	and esi, 0xffff
		  	#endif
			MOV_EAX_DWORD_PTR rxf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_x[MAYBE_EDI], MAYBE_EAX
			MOV_EAX_DWORD_PTR ryf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_y[MAYBE_EDI], MAYBE_EAX
			MOV_EAX_DWORD_PTR rzf[MAYBE_ESI]
			MOV_DWORD_PTR ultima_z[MAYBE_EDI], MAYBE_EAX
		  	add MAYBE_EDI, 4
		  	#ifdef WINDOWS
		  	and edi, 0xffff
		  	#endif
		  }
      STOP1:    asm {   inc vr
			mov ax, vr
			cmp ax, 4
			jnb cutting_end_1
			jmp the_for_1 }

 cutting_end_1: asm {   mov ax, di
			shr ax, 1
			mov vr22, ax
			shr ax, 1
			mov vr2, ax }

			#ifdef WINDOWS
			asm popad
			#endif
			if (vr2<3) {
				return;
			}

	   // Queste sono le proiezioni prospettiche da 3d a 2d.
	   // Contemporaneamente, il ciclo ricerca il minimo ed il massimo
	   // verticale dell'estensione del poligono sullo schermo.

	 to_2d: asm {
		 	#ifdef WINDOWS
		 	pushad
		 	xor esi, esi
		 	xor edi, edi
		 	#endif
		 	MOV_EDX_DWORD_PTR ubyl
			MOV_EBX_DWORD_PTR lbyl
			mov si, vr2
			dec si
			shl si, 2
			mov di, si
			add di, si
		 }
     projector: asm {
		 	fld dpp
			fdiv dword ptr ultima_z[MAYBE_ESI]
			fld st(0)
			fmul dword ptr ultima_x[MAYBE_ESI]
			fadd dword ptr x_centro_f
			fistp dword ptr mp[MAYBE_EDI]
			fmul dword ptr ultima_y[MAYBE_ESI]
			fadd dword ptr y_centro_f
			fistp dword ptr mp[MAYBE_EDI+4]
			CMP_DWORD_PTR mp[MAYBE_EDI+4], MAYBE_EDX
			jnl outr_3
			MOV_EDX_DWORD_PTR mp[MAYBE_EDI+4] }
     outr_3:	asm {	CMP_DWORD_PTR mp[MAYBE_EDI+4], MAYBE_EBX
			jle outr_4
			MOV_EBX_DWORD_PTR mp[MAYBE_EDI+4] }
			
     outr_4:	asm {
		 	sub di, 8
			sub si, 4
			jnc projector
			MOV_DWORD_PTR max_y, MAYBE_EBX
			MOV_DWORD_PTR min_y, MAYBE_EDX
			}
			
	// Eventuale esclusione di poligoni non visibili.

	asm {// if (min_y>uby) return;
       	MOV_EAX_DWORD_PTR min_y
       	CMP_EAX_DWORD_PTR ubyl
		jle ct1ok
	     // if (max_y<lby) return;
       	MOV_EAX_DWORD_PTR max_y
       	CMP_EAX_DWORD_PTR lbyl
		jnl ct1ok }

       	#ifdef WINDOWS
		asm popad
		#endif
		return;

	// Normalizzazione dei limiti.

ct1ok:	asm {// if (min_y<lby) min_y = lby;
       	MOV_EAX_DWORD_PTR min_y
       	CMP_EAX_DWORD_PTR lbyl
		jnl step_1
       	MOV_EAX_DWORD_PTR lbyl
       	MOV_DWORD_PTR min_y, MAYBE_EAX }

step_1:	asm {// if (max_y>uby) max_y = uby;
      	MOV_EAX_DWORD_PTR max_y
      	CMP_EAX_DWORD_PTR ubyl
		jle step_2
		MOV_EAX_DWORD_PTR ubyl
      	MOV_DWORD_PTR max_y, MAYBE_EAX }

step_2:	asm {// if (min_y>max_y) return;
       	MOV_EAX_DWORD_PTR min_y
       	CMP_EAX_DWORD_PTR max_y
		jle ct2ok }

	#ifdef WINDOWS
	asm popad
	#endif
	return;

	// Inizializzazione costanti di ottimizzazione.

ct2ok:	asm {// k1 = vx * 16;
		fld  vx
		fmul _16
		fstp k1
	     //	k2 = vy * 16;
		fld  vy
		fmul _16
		fstp k2
	     //	k3 = vz * 16;
		fld  vz
		fmul _16
		fstp k3
		#ifdef WINDOWS
		popad
		#endif
	}

	if (culling) {
		k1 *= 2;
		k2 *= 2;
		k3 *= 2;
	}

	// Inizializzazione delle matrici dei confini orizzontali.

	
	asm {
		#ifdef WINDOWS
		pushad
		#endif
		// for (i=min_y; i<=max_y; i++)
		//MAYBECHANGE: Maybe this should be reverted back to working with words, but xor edi still.
		MOV_EDI_DWORD_PTR min_y	//Previously: mov di, word ptr min_y
		MOV_ECX_DWORD_PTR max_y	//Previously: mov cx, word ptr max_y
		
		MOV_EAX_DWORD_PTR lbxl
		MOV_EBX_DWORD_PTR ubxl
		sub MAYBE_ECX, MAYBE_EDI
		shl MAYBE_EDI, 1
		inc MAYBE_ECX
		 }
ol_init:asm {//	fpart[i] = lbxl;
		mov word ptr fpart[MAYBE_EDI], ax
	     // ipart[i] = ubxl;
		mov word ptr ipart[MAYBE_EDI], bx
		add MAYBE_EDI, 2
		dec MAYBE_ECX
		jnz ol_init }
		/*sub MAYBE_ECX, MAYBE_EDI
		shl MAYBE_EDI, 1
		inc MAYBE_ECX }
ol_init:asm {//	fpart[i] = lbxl;
		mov word ptr fpart[MAYBE_EDI], ax
	     // ipart[i] = ubxl;
		mov word ptr ipart[MAYBE_EDI], bx
		add MAYBE_EDI, 2
		dec MAYBE_ECX
		jnz ol_init }
		*/

	// Calcolo confini orizzontali.

	asm {//	mp[vr22]   = mp[0];
	     // mp[vr22+1] = mp[1];
		MOVZX_MAYBE_EDI, vr22
		shl di, 2
       	MOV_EAX_DWORD_PTR mp[0]
	  	MOV_EBX_DWORD_PTR mp[4]
	   	MOV_DWORD_PTR mp[MAYBE_EDI], MAYBE_EAX
	   	MOV_DWORD_PTR mp[MAYBE_EDI+4], MAYBE_EBX
		 // for (i = 0; i < vr22; i += 2)
		xor MAYBE_ESI, MAYBE_ESI
		shr vr22, 1 }
extfor: asm {//	y1 = mp[i+1];
	     //	y2 = mp[i+3];
	     //	x1 = mp[i];
	     //	x2 = mp[i+2];
       	MOV_EBX_DWORD_PTR mp[MAYBE_ESI+4]
	  	MOV_EDX_DWORD_PTR mp[MAYBE_ESI+12]
       	MOV_EAX_DWORD_PTR  mp[MAYBE_ESI]
       	MOV_ECX_DWORD_PTR  mp[MAYBE_ESI+8]
	     //	if (y2<y1)
       	CMP MAYBE_EDX, MAYBE_EBX
		jnl noex
       	MOV_DWORD_PTR x1, MAYBE_ECX
      	MOV_DWORD_PTR y1, MAYBE_EDX
      	MOV_DWORD_PTR x2, MAYBE_EAX
       	MOV_DWORD_PTR y2, MAYBE_EBX
		jmp exch }
  noex: asm {// niente scambio
       	MOV_DWORD_PTR x1, MAYBE_EAX
       	MOV_DWORD_PTR y1, MAYBE_EBX
       	MOV_DWORD_PTR x2, MAYBE_ECX
       	MOV_DWORD_PTR y2, MAYBE_EDX
	   }
  exch: asm {// scambio effettuato
	     // if (y2!=y1) [nessuno ha alterato i flags]
		jne ol
		jmp nool } // niente calcolo del bordo: il segmento non si sviluppa in altezza
    ol: asm {// kx = (float)(x2 - x1) / (float)(y2 - y1);
		fild x2
		fisub x1
		fild y2
		fisub y1
		fdivp
		fstp kx
	     // if (y1<lbyl)
       	MOV_EAX_DWORD_PTR y1
       	CMP_EAX_DWORD_PTR lbyl
		jnl nocr
	     // ity = lbyl;
       	MOV_EAX_DWORD_PTR lbyl
       	MOV_DWORD_PTR ity, MAYBE_EAX
		 // x1 += (float)(lbyl-y1) * kx;
		fild x1
		fild lbyl
		fisub y1
		fmul kx
		faddp
		fistp x1
		jmp crct }
  nocr: asm {// ity = y1;
      	MOV_EAX_DWORD_PTR y1
       	MOV_DWORD_PTR ity, MAYBE_EAX }
  crct: asm {// if (y2>ubyl)
       	MOV_EAX_DWORD_PTR y2
       	CMP_EAX_DWORD_PTR ubyl
		jng _nocr
	     // jty = ubyl;
       	MOV_EAX_DWORD_PTR ubyl
       	MOV_DWORD_PTR jty, MAYBE_EAX
		jmp _crct }
 _nocr: asm {// jty = y2;
       	MOV_EAX_DWORD_PTR y2
       	MOV_DWORD_PTR jty, MAYBE_EAX }
 _crct: asm {// bndx = x1;
		fild x1
	     // for (h=ity; h<=jty; h++)
       	MOV_EDI_DWORD_PTR ity
       	MOV_ECX_DWORD_PTR jty
       	CMP MAYBE_EDI, MAYBE_ECX
		jnl noifor
       	SUB MAYBE_ECX, MAYBE_EDI
		shl MAYBE_EDI, 1
		inc MAYBE_ECX }
intfor: asm {// _EAX = bndx;
		fist bndx
		MOV_EAX_DWORD_PTR bndx
		CMP_EAX_DWORD_PTR i_low_lim
		jnl ct01
		MOV_EAX_DWORD_PTR i_low_lim }
ct01:	asm {	CMP_EAX_DWORD_PTR i_hig_lim
		jng ct02
		MOV_EAX_DWORD_PTR i_hig_lim
		}
ct02:	asm {// if (bndx > fpart[h])
		cmp ax, word ptr fpart[MAYBE_EDI]
		jng ct1n
	     //	if (bndx < ubx)
		cmp ax, word ptr ubxl
		jnl ct2n
	     //	fpart[h] = bndx;
		mov word ptr fpart[MAYBE_EDI], ax
		jmp ct1n }
  ct2n: asm {// fpart[h] = ubx;
		mov dx, word ptr ubxl
		mov word ptr fpart[MAYBE_EDI], dx }
  ct1n: asm {// if (bndx < ipart[h])
		cmp ax, word ptr ipart[MAYBE_EDI]
		jnl ct3n
	     //	if (bndx > lbx)
		cmp ax, word ptr lbxl
		jng ct4n
	     //	ipart[h] = bndx;
		mov word ptr ipart[MAYBE_EDI], ax
		jmp ct3n }
  ct4n: asm {//	ipart[h] = lbx;
		mov dx, word ptr lbxl
		mov word ptr ipart[MAYBE_EDI], dx }
  ct3n: asm {// bndx += kx;
		fadd kx
		add di, 2
		dec MAYBE_ECX
		jnz intfor }
noifor:	
		asm FSTP_ST
  nool: asm {   add MAYBE_ESI, 8
		dec vr22
		jz  ol_end
		jmp extfor }

	// Pre-assegnamenti di lavoro.

ol_end:
	/*#ifdef WINDOWS
		//fs is txtr
		//es is adapted
		asm {
			mov esi, [adapted]
			mov al, tinta
			mov byte ptr [esi+0xFA00], al
			mov al, escrescenze
			mov byte ptr [esi+0xFA01], al
		}
	#else*/
	asm {
		L_DWORD_PTR(es, MAYBE_EDX, txtr)
	#ifndef WINDOWS
		mov ax, es			// .
		shr dx, 4			// .
		add ax, dx			// .
		db 0x8e, 0xe0		// mov fs, ax
	#endif
	
		L_DWORD_PTR(es, MAYBE_EAX, adapted)	// caricamento indirizzo area video
		#ifdef WINDOWS
		mov esi, [adapted]
		#endif
		mov al, tinta		// caricamento del primo colore
		mov WONLY_BYTE_PTR RAWSEGVAR(es, esi, 0xFA00+4), al
		//asm mov es:[0xFA00], al		// .
		mov al, escrescenze		// caricamento primo colore bumps
		mov WONLY_BYTE_PTR RAWSEGVAR(es, esi, 0xFA01+4), al
		//asm mov es:[0xFA01], al		// .
		
		// Ciclo di tracciamento.
	
				 // for (i=min_y; i<=max_y; i++)
			
		mov ax, word ptr min_y
		mov i, ax
	}
	 trace: asm {//	_z = oz + (hz * (i - y_centro)) + (vz * (ipart[i] - x_centro + 1));
			MOVZX_MAYBE_ESI, i		//zx since we use esi as an index
			shl MAYBE_ESI, 1
			fild word ptr ipart[MAYBE_ESI]
			fsub x_centro_f
			fadd uno
			fld st(0) // duplica (ipart[i] - x_centro + 1)
			fld st(0) // due volte, Š lo stesso per tre calcoli
			fmul vz
			fild i
			fsub y_centro_f
			fmul hz
			faddp
			fadd oz
			fst _z
		     //	k4 = 1 / _z;
			fdivr uno
			fstp k4
		     // _x = ox + (hx * (i - y_centro)) + (vx * (ipart[i] - x_centro + 1));
			fmul vx
			fild i
			fsub y_centro_f
			fmul hx
			faddp
			fadd ox
			fstp _x
		     // _y = oy + (hy * (i - y_centro)) + (vy * (ipart[i] - x_centro + 1));
			fmul vy
			fild i
			fsub y_centro_f
			fmul hy
			faddp
			fadd oy
			fstp _y
		     // u  = (_x * tempXsize) * k4; // Seq. stabile
		     //	v  = (_y * tempYsize) * k4; // Ma usare _control87
			fld _y
			fmul tempYsize
			fmul k4
			fld _x
			fmul tempXsize
			fmul k4
			fxch
			fistp v
			fistp u
		     //	sections = fpart[i] - ipart[i];	// Sequenza stabile.
		     //	_DI = i * 320 + ipart[i];       // Moltiplicazione per 320 in tabella.
		     // SI Š gi… caricato con I * 2.
			MOVSX_MAYBE_EDX, word ptr ipart[MAYBE_ESI]
			MOVSX_MAYBE_EAX, word ptr fpart[MAYBE_ESI]
			mov MAYBE_EDI, RIGA(MAYBE_ESI)
			sub MAYBE_EAX, MAYBE_EDX
			add MAYBE_EDI, MAYBE_EDX
			mov sections, ax
			#ifndef WINDOWS
			push ds
			push es
			pop  ds
//adapted is now ds too.
			#endif
			test culling, 1
			jz row
			jmp c_row }
	 // tracciamento di una scanline: versione ad alto dettaglio
	   row: asm {   cmp sections, 0
			jg  again
			jmp row_end }
	 again:	asm {	cmp sections, 16
			jg  complete
			mov ax, sections
			mov cl, al
			jmp unfinished }
      complete: asm 	mov cl, 16
    unfinished: asm {	sub sections, 16
			cmp cl, 0
			je  row
		     // x += k1;               // Sequenza stabile.
		     // y += k2;	       // Traduzione ASM ok.
		     // z += k3;               // Nessun ritardo grazie a FXCH.
		     // if (z) {               // !! Sequenza instabile.
		     //	k4 = 1 / z;	       // correzione da parte di "_control87"
		     //	u2 = (x * XSIZE) * k4; // Problema: le FISTP possono provocare
		     //	v2 = (y * YSIZE) * k4; // errori di dominio in virgola mobile.
			fld   _z	       // 1 cycle   stack: z
			fadd  k3               // 1 cycle   stack: z+k3
			fld   _x	       // 1 cycle   stack: x, z+k3
			fadd  k1               // 1 cycle   stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fst   _z               // 2 cycles  stack: z+k3, x+k1
			fxch                   // no time   stack: x+k1, z+k3
			fst   _x               // 2 cycles  stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fdivr _uno             // 39 cycles stack: k4, x+k1
			MOV_EAX_DWORD_PTR u     // while FPU is working,
			MOV_EDX_DWORD_PTR v     // this group takes 0 cycles.
			mov ch, flares	       //
			DB_0x66; push MAYBE_EBP         //This was just push bp before - but since we manipulate ebp later, we had better push the whole thing
			fxch                   // no time   stack: x+k1, k4
			fmul  tempXsize        // 1 cycle   stack: x..., k4
			fld   _y               // 1 cycle   stack: y, x..., k4
			fadd  k2	       // 1 cycle   stack: y+k2, x..., k4
			fst   _y               // 3 cycles  stack: y+k2, x..., k4
			fmul  tempYsize        // 1 cycle   stack: y..., x..., k4
			fxch                   // no time   stack: x..., y..., k4
			fmul  st, st(2)        // 1 cycle   stack: u, y..., k4
			fxch                   // no time   stack: y..., u, k4
			fmul  st, st(2)        // 1 cycle   stack: v, u, k4
			fxch                   // no time   stack: u, v, k4
			fistp u                // 6 cycles  stack: v, k4
			fistp v                // 6 cycles  stack: k4
			FSTP_ST
	       	MOV_ESI_DWORD_PTR v
			MOV_EBP_DWORD_PTR u
			SUB MAYBE_ESI, MAYBE_EDX
			SUB MAYBE_EBP, MAYBE_EAX
			SAR MAYBE_ESI, 4
			SAR MAYBE_EBP, 4
			test ch, 15		// NORMALE = 0
			jz internal
			test ch, 1		// LUCIDO = 1
			jnz transp
			test ch, 2		// BRILLANTE = 2
			jnz bright
			test ch, 4		// TRASLUCIDO = 4
			jnz merger
			jmp bumper }		// BUMP MAPPING = 8
      internal:	asm {
		  	xor MAYBE_EBX, MAYBE_EBX
		  	mov bh, dh		// 1 (riempimento normale)
			inc MAYBE_EDI			// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	#endif
		  	mov ch, RAWSEGVAR(ds, esi, 0xFA00+4)	// *
			#ifdef WINDOWS
			cmp edx, 0
		  	jl bypass_internal_1
		  	push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]
			pop esi
	  } bypass_internal_1: asm {
		  	#else
		  	db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			#endif
		  	add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
		  	cmp edi, 1
		  	jl bypass_internal_2
		  	mov byte ptr [esi+edi-1], ch		// 1	//mov byte ptr [esi+edi+3], ch		//REMOVE4?
	  } bypass_internal_2: asm {
		  	#else
		  	mov [MAYBE_EDI+3], ch		// 1
			#endif
		  	#ifdef WINDOWS
			pop esi
			#endif
		  	add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz internal  		// 7 cicli.
			jmp common }
      transp:  	asm {
		  	xor MAYBE_EBX, MAYBE_EBX
		  	mov bh, dh		// 1 (riempimento lucido)
			inc MAYBE_EDI			// *
			mov bl, ah		// 1
			#ifdef WINDOWS
		  	cmp edi, 1
		  	jl bypass_transp_1
		  	push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi-1]		// *	//mov ch, byte ptr [esi+edi+3]	//REMOVE4?
			cmp edx, 0
		  	jl bypass_transp_2
		  	push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
		} bypass_transp_2: asm {
		  	add eax, ebp		// *
			mov byte ptr [esi+edi-1], ch		// 1	//mov byte ptr [esi+edi+3], ch		//REMOVE4?
		  	pop esi
	  	} bypass_transp_1: asm {
		  	#else
		  	mov ch, [di+3]		// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
		  	add ax, bp		// *
			mov [di+3], ch		// 1
			#endif
			add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz transp		// 7 cicli.
			jmp common }
      bright:  	asm {
		  	#ifdef WINDOWS
		  	cmp edi, 0
		  	jl bypass_bright_1
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi]	//REMOVED4: Was mov ch, byte ptr [esi+edi+4]
		  	pop esi
	    	#else
		  	mov ch, [di+4]		// 1 (riempimento brillante)
			#endif
		  	mov bh, dh		// *
			inc MAYBE_EDI			// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			cmp edx, 0
		  	jl bypass_bright_2
		  	push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
	  	} bypass_bright_2: asm {
			#else
		  	db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			#endif
		  	add MAYBE_EDX, MAYBE_ESI		// *
			cmp ch, 0x3E		// 1
			jbe antibloom		// * (antiblooming)
			jmp bypass_bypass_bright_1
		} bypass_bright_1: asm {
			add MAYBE_EDX, MAYBE_ESI		// *
			
		} bypass_bypass_bright_1: asm {
			mov ch, 0x3E }		// 1
      antibloom:asm {
			#ifdef WINDOWS
		  	cmp edi, 1
		  	jl bypass_antibloom_1
			push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi-1], 0xC0	//and byte ptr [esi+edi+3], 0xC0		//REMOVED4
		  	or byte ptr [esi+edi-1], ch		//or byte ptr [esi+edi+3], ch		//REMOVED4
		  	pop esi
	  } bypass_antibloom_1: asm {
		  	#else
		  	and byte ptr [di+3],0xC0// 1
			or  [di+3], ch		// 1
			#endif
		  	dec cl			// *
			jnz bright		// 1/0 (9-10 cicli.)
			jmp common }
      merger:  	asm {
		  	#ifdef WINDOWS
			cmp edi, 0
		  	jl bypass_merger_1
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi]	//mov ch, byte ptr [esi+edi+4]		//REMOVED4
		  	pop esi
	  	  	and ebx, 0xffff
		  	#else
		  	mov ch, [di+4]		// 1 (traslucido)
			#endif
		  	mov bh, dh		// *
			inc MAYBE_EDI			// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			cmp edx, 0
		  	jl bypass_merger_2
			push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
		} bypass_merger_2: asm {
			push esi
		  	mov esi, [adapted]
		  	add ch, byte ptr [esi+0xFA00+4]
		  	pop esi
		  	#else
		  	db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			add ch, ds:[0xFA00]
			#endif
			add MAYBE_EDX, MAYBE_ESI		// *
			shr ch, 1		// 1
			#ifdef WINDOWS
			cmp edi, 1
		  	jl bypass_merger_1
			push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi-1], 0xC0	//REMOVED4, was +3
		  	or byte ptr [esi+edi-1], ch		//REMOVED4, was +3
			pop esi
			#else
		  	and byte ptr [di+3],0xC0// 1
			or  [di+3], ch		// 1
			#endif
			jmp bypass_bypass_merger_1
		} bypass_merger_1: asm {
			add MAYBE_EAX, MAYBE_EBP		// *
		} bypass_bypass_merger_1: asm {
			dec cl			// *
			jnz merger		// 1 (9 cicli.)
			jmp common }
      bumper:  	asm {
		  	xor MAYBE_EBX, MAYBE_EBX
		  	mov bh, dh		// 1 (bump mapping)
			inc MAYBE_EDI			// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			cmp edx, 0
		  	jl bypass_bumper_1
		  	push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+0xFA00+4]
			pop esi
		  	push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
	  	  	#else
			mov ch, ds:[0xFA00]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			#endif
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			cmp edi, 1
		  	jl bypass_bumper_2
		  	push esi
		  	mov esi, [adapted]
		  	mov byte ptr [esi+edi-1], ch		// 1			//REMOVED4, was +3
			pop esi
		} bypass_bumper_2: asm {
		  	#else
			mov [di+3], ch
			#endif
			jmp bypass_bypass_bumper_1
		} bypass_bumper_1: asm {
			add MAYBE_EAX, MAYBE_EBP
		} bypass_bypass_bumper_1: asm {
			push MAYBE_EDI
			push cx
			and ch, 0x7
		}
		bmpm320:
		asm {
			sub MAYBE_EDI, 320
			dec ch
			jns bmpm320
			pop cx
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	sub ch, byte ptr [esi+0xFA00+4]
			add ch, byte ptr [esi+0xFA01+4]
			//cmp bx, 4
		  	//jl bypass_bmpm320_1
		  	push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
		} bypass_bmpm320_1: asm {
			cmp edi, -639
		  	jl bypass_bmpm320_2
		  	cmp edi, DISPLAYBYTES-639
		  	jg bypass_bmpm320_2
		  	mov byte ptr [esi+edi+640-1], ch	//REMOVED4, was +3
			pop esi
		} bypass_bmpm320_2: asm {
			#else
			sub ch, ds:[0xFA00]
			add ch, ds:[0xFA01]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			mov byte ptr [di+640+3], ch
			#endif
			pop MAYBE_EDI
			add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz bumper } 		// ? cicli.
	common:	asm {
			DB_0x66; pop MAYBE_EBP
			jmp row }
	 // tracciamento di una scanline: versione a basso dettaglio
	 c_row: asm {   cmp sections, 0
			jg  c_again
			jmp row_end }
       c_again:	asm {	cmp sections, 32
			jg  c_complete
			mov ax, sections
			add ax, 2
			mov cl, al
			jmp c_unfinished }
    c_complete: asm  	mov cl, 32
  c_unfinished: asm {	sub sections, 32
			cmp cl, 2
			jl  c_row
			fld   _z	       // 1 cycle   stack: z
			fadd  k3               // 1 cycle   stack: z+k3
			fld   _x	       // 1 cycle   stack: x, z+k3
			fadd  k1               // 1 cycle   stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fst   _z               // 2 cycles  stack: z+k3, x+k1
			fxch                   // no time   stack: x+k1, z+k3
			fst   _x               // 2 cycles  stack: x+k1, z+k3
			fxch                   // no time   stack: z+k3, x+k1
			fdivr _uno             // 39 cycles stack: k4, x+k1
	       	MOV_EAX_DWORD_PTR u 	// while FPU is working,
	  		MOV_EDX_DWORD_PTR v     // this group takes 0 cycles.
			shr cl, 1	       //
			DB_0x66; push MAYBE_EBP         //This was just push bp before - but since we manipulate ebp later, we had better push the whole thing
			
			mov ch, flares	       //
			DB_0x66; push MAYBE_EDI		       //
			fxch                   // no time   stack: x+k1, k4
			fmul  tempXsize        // 1 cycle   stack: x..., k4
			fld   _y               // 1 cycle   stack: y, x..., k4
			fadd  k2	       // 1 cycle   stack: y+k2, x..., k4
			fst   _y               // 3 cycles  stack: y+k2, x..., k4
			fmul  tempYsize        // 1 cycle   stack: y..., x..., k4
			fxch                   // no time   stack: x..., y..., k4
			fmul  st, st(2)        // 1 cycle   stack: u, y..., k4
			fxch                   // no time   stack: y..., u, k4
			fmul  st, st(2)        // 1 cycle   stack: v, u, k4
			fxch                   // no time   stack: u, v, k4
			fistp u                // 6 cycles  stack: v, k4
			fistp v                // 6 cycles  stack: k4
			FSTP_ST
			MOV_ESI_DWORD_PTR v
	       	MOV_EBP_DWORD_PTR u
	       	DB_0x66; SUB MAYBE_ESI, MAYBE_EDX
	       	DB_0x66; SUB MAYBE_EBP, MAYBE_EAX
	       	DB_0x66; SAR MAYBE_ESI, 4
	       	DB_0x66; SAR MAYBE_EBP, 4
	       	test ch, 15 		// NORMALE = 0
			jz c_internal
			test ch, 1		// LUCIDO = 1
			jnz c_transp
			test ch, 2		// BRILLANTE = 2
			jnz c_bright
			test ch, 4		// TRASLUCIDO = 4
			jnz c_merger
			jmp c_bumper }		// BUMP MAPPING = 8
    c_internal:	asm {
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// 1 (riempimento normale)
			add MAYBE_EDI, 2		// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+0xFA00+4]
			cmp edx, 0
			jl bypass_c_internal_1
			mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
		} bypass_c_internal_1: asm {
			pop esi
			#else
			mov ch, ds:[0xFA00]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			#endif
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			cmp edi, 2
			jl bypass_c_internal_2
			push esi
		  	mov esi, [adapted]
		  	mov [esi+edi-2], ch	//REMOVED4, was +2
			cmp edi, 1
			jl bypass_c_internal_3
			mov [esi+edi-1], ch	//REMOVED4, was +3
		} bypass_c_internal_3: asm {
			pop esi
		} bypass_c_internal_2: asm {
			#else
			mov [di+2], ch		// 1
			mov [di+3], ch		// *
			#endif
			add MAYBE_EDX, MAYBE_ESI		// 1
			dec cl   		// *
			jnz c_internal  	// 1 (8 cicli).
			jmp c_common }
    c_transp:  	asm {
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// 1 (riempimento lucido)
			add MAYBE_EDI, 2		// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			cmp edi, 1
			jl bypass_c_transp_1
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi-1]	//REMOVED4, was +3
			mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
			#else
			mov ch, [di+3]		// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			#endif
			add MAYBE_EAX, MAYBE_EBP		// *
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov byte ptr [esi+edi-2], ch	//REMOVED4, was +2
			mov byte ptr [esi+edi-1], ch	//REMOVED4, was +3
			pop esi
			#else
			mov [di+2], ch		// 1
			mov [di+3], ch		// *
			#endif
			jmp bypass_bypass_c_transp_1
		} bypass_c_transp_1: asm {
			add MAYBE_EAX, MAYBE_EBP
		} bypass_bypass_c_transp_1: asm {
			add MAYBE_EDX, MAYBE_ESI		// 1
			dec cl   		// *
			jnz c_transp		// 1 (8 cicli).
			jmp c_common }
    
	c_bright:  	asm {
			#ifdef WINDOWS
    		cmp edi, 0
			jl bypass_c_bright_1
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi]	//REMOVED4, was +4
    		pop esi
			#else
    		mov ch, [di+4]		// 1 (riempimento brillante)
    		#endif
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// *
			add MAYBE_EDI, 2		// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			cmp edx, 0
			jl bypass_c_bright_2
			cmp bx, 4
			jl special_c_bright_1
			#ifdef WINDOWS
			push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
		
		/*
		Access violation exception:
		eax=00000000 ebx=0000f000 ecx=00001601 edx=fffff0d5 esi=00a32cd8 edi=00007eb0
		eip=00414d99 esp=00d6f610 ebp=00000000 iopl=0         nv up ei pl zr na po nc
		cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
		image00400000!polymap+0x11cb:
		00414d99 026c1efc         add     ch,[esi+ebx-0x4]        ds:0023:00a41cd4=??
		*/
			pop esi
			#else
			db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			#endif
			jmp bypass_c_bright_2
		} special_c_bright_1: asm {
			nop
		} bypass_c_bright_2: asm {
			add MAYBE_EDX, MAYBE_ESI		// *
			cmp ch, 0x3E		// 1
			jbe c_antibloom		// * (antiblooming)
			jmp bypass_bypass_c_bright_1
		} bypass_c_bright_1: asm {
			add MAYBE_EAX, MAYBE_EBP		// *
			add MAYBE_EDX, MAYBE_ESI		// *
			
		} bypass_bypass_c_bright_1: asm {
			mov ch, 0x3E }		// 1
    c_antibloom:asm {
//ds and es are still adapted, fs is still txtr
    		cmp edi, 2
			jl bypass_c_antibloom_1
	   		#ifdef WINDOWS
    		push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi-2], 0xC0	//REMOVED4, was +2
    		or ch, byte ptr [esi+edi-2]	//REMOVED4, was +2
    		dec cl
    		mov byte ptr [esi+edi-2], ch	//REMOVED4, was +2
    		mov byte ptr [esi+edi-1], ch	//REMOVED4, was +3
    		pop esi
			#else
    		and byte ptr [di+2],0xC0// 1
			or  ch, [di+2]		// 1
			dec cl    		// 1
			mov [di+2], ch		// *
			mov [di+3], ch		// 1
			#endif
		} bypass_c_antibloom_1: asm {
			jnz c_bright		// 0 (11 cicli.)
			jmp c_common }
    c_merger:  	asm {
    		cmp edi, 0
			jl bypass_c_merger_1
	   		#ifdef WINDOWS
    		push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+edi]	//REMOVED4, was +4
			pop esi
    		#else
    		mov ch, [di+4]		// 1 (traslucido)
			#endif
			xor MAYBE_EBX, MAYBE_EBX
			mov bh, dh		// *
			add MAYBE_EDI, 2		// 1
			mov bl, ah		// *
			and ch, 0x3F		// 1
			add MAYBE_EAX, MAYBE_EBP		// *
			cmp edx, 0
			jl bypass_c_merger_2
	   		#ifdef WINDOWS
			push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
			push esi
		  	mov esi, [adapted]
		  	add ch, [esi+0xFA00+4]
			pop esi
			#else
			db 0x64, 0x02, 0x2F 	// 1+PFX (add ch, fs:[bx])
			add ch, ds:[0xFA00]
			#endif
		} bypass_c_merger_2: asm {
			add MAYBE_EDX, MAYBE_ESI		// *
			shr ch, 1		// 1
			cmp edi, 2
			jl bypass_c_merger_3
	   		#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	and byte ptr [esi+edi-2],0xC0// *	//REMOVED4, was +2
			or  ch, byte ptr [esi+edi-2]		// 1	//REMOVED4, was +2
			mov byte ptr [esi+edi-2], ch		// 1	//REMOVED4, was +2
			mov byte ptr [esi+edi-1], ch		// *	//REMOVED4, was +3
			pop esi
			dec cl   		// *
			#else
			and byte ptr [di+2],0xC0// *
			or  ch, [di+2]		// 1
			dec cl   		// *
			mov [di+2], ch		// 1
			mov [di+3], ch		// *
			#endif
			jnz c_merger
			jmp c_common
		} bypass_c_merger_3: asm {
			dec cl
			jnz c_merger		// 1 (9 cicli.)
			jmp c_common
		} bypass_c_merger_1: asm {
			add MAYBE_EAX, MAYBE_EBP		// *
			add MAYBE_EDX, MAYBE_ESI		// *
			
			jmp c_common }
      c_bumper: asm {
      		xor MAYBE_EBX, MAYBE_EBX
      		mov bh, dh		// 1 (bump mapping)
			add MAYBE_EDI, 2		// *
			mov bl, ah		// 1
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	mov ch, byte ptr [esi+0xFA00+4]	// *
			cmp edx, 0
			jl bypass_c_bumper_1
	   		push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
	  	} bypass_c_bumper_1: asm {
		  	add eax, ebp		// *
			cmp edi, 2
			jl bypass_c_bumper_2
	   		mov byte ptr [esi+edi-2], ch		// 1	//REMOVED4, was +2
			mov byte ptr [esi+edi-1], ch		// 1	//REMOVED4, was +3
		} bypass_c_bumper_2: asm {
			pop esi
		  	push edi
			#else
			mov ch, ds:[0xFA00]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			add ax, bp		// *
			
			mov [di+2], ch		// 1
			mov [di+3], ch		// 1
			push di
			#endif
			push cx
			and ch, 0x7 }
      c_bmpm320:asm {
      		sub MAYBE_EDI, 320
			dec ch
			jns c_bmpm320
			pop cx
			#ifdef WINDOWS
			push esi
		  	mov esi, [adapted]
		  	sub ch, byte ptr [esi+0xFA00+4]
			add ch, byte ptr [esi+0xFA01+4]
			//cmp bx, 4
		  	//jl bypass_c_bmpm320_1
		  	push esi
		  	mov esi, [txtr]
		  	add ch, byte ptr [esi+ebx-4]	//add ch, byte ptr txtr[ebx]
			pop esi
	  	} bypass_c_bmpm320_1: asm {
			cmp edi, -638
		  	jl bypass_c_bmpm320_2
		  	cmp edi, DISPLAYBYTES-638
		  	jg bypass_c_bmpm320_2
		  	mov byte ptr [esi+edi+640-2], ch	//REMOVED4, was +2
		  	mov byte ptr [esi+edi+640-1], ch	//REMOVED4, was +3
		} bypass_c_bmpm320_2: asm {
			pop esi
		  	#else
			sub ch, ds:[0xFA00]
			add ch, ds:[0xFA01]	// *
			db 0x64, 0x02, 0x2F 	// 1+PFX+AGI (add ch, fs:[bx])
			mov byte ptr [di+640+2], ch
			mov byte ptr [di+640+3], ch
			#endif
			DB_0x66; pop MAYBE_EDI
			add MAYBE_EDX, MAYBE_ESI		// *
			dec cl			// 1
			jnz c_bumper } 		// ? cicli.
      c_common:	asm {
      		DB_0x66; pop MAYBE_EDI
			DB_0x66; pop MAYBE_EBP
			add MAYBE_EDI, 32
			jmp c_row }
	// codice inter-scanline: fra una scanline e la successiva...
       row_end: asm {	test halfscan, 1
			jz do_singlescan
			inc i
			mov MAYBE_EAX, MAYBE_DWORD_PTR max_y
			cmp ax, i
			#ifndef WINDOWS
			pop ds
			#endif
			jb trace_end
			MOVZX_MAYBE_ESI, i	//Since we use esi as an index
			shl MAYBE_ESI, 1
			mov dx, word ptr ipart[MAYBE_ESI-2]
			mov ax, word ptr fpart[MAYBE_ESI-2]
			#ifdef WINDOWS
			mov edi, dword ptr riga[MAYBE_ESI*2]
			#else
			mov di, word ptr riga[MAYBE_ESI]
			push ds
			push es
			pop  ds
			#endif
			//and now ds is adapted again
			sub MAYBE_EAX, MAYBE_EDX
			jc do_singlescan
			jz do_singlescan
			add MAYBE_EDI, MAYBE_EDX }
     duplicate: asm {
     		cmp edi, 320
		  	jl bypass_duplicate_1
		  	cmp edi, DISPLAYBYTES+320
		  	jg bypass_duplicate_1
		  	#ifdef WINDOWS
     		push esi
		  	mov esi, [adapted]
		  	mov dl, byte ptr [esi+edi-320]	//REMOVED4, was -316
			mov byte ptr [esi+edi], dl	//REMOVED4, was +4
			mov byte ptr [esi+edi+320], dl	//REMOVED4, was +324
			pop esi
		 	#else
     		mov dl, [di-316]
			mov [di+4], dl
			mov [di+324], dl
			#endif
	 	} bypass_duplicate_1: asm {
			inc MAYBE_EDI
			dec MAYBE_EAX
			jnz duplicate }
 do_singlescan:	asm {	inc i
			mov MAYBE_EAX, MAYBE_DWORD_PTR max_y
			cmp ax, i
			#ifndef WINDOWS
			pop ds
			#endif
			jb trace_end
			jmp trace }
     trace_end:      // Fine tracciamento.
			#ifdef WINDOWS
			asm popad
			#endif
	//error("polymap finished");
}
