/*
	Software renderer
    Copyright (C) 2006  Darragh Coy.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Renderer.h
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#ifndef RendererH
#define RendererH

        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
        // Includes and pragmas
        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬

        #include <stdlib.h>
        #include <string.h>
        #include <math.h>
        #include <windows.h>
        #include <d3d9.h>
        #include "Win.h"

        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
        // Defines
        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬

        // Quick degrees to radians multiplier

        #define TO_RADIANS 0.017453292f

        // Round macro: only does positive numbers!

        #define ROUND(x)( x - (int)(x) > 0.5f ? (int)(x+1) : x )

        // Truncate up: like an integer truncate but truncates up rather than down
        // i.e: 0.5 becomes 1 -0.25 becomes -1

        #define TRUNCUP(x)( x < 0 ? (x - (int)(x) == 0 ? x : (int)(x-1)) : (x - (int)(x) == 0 ? x : (int)(x+1)) )

        // Minimum and maximum macros

        #define MIN(x,y)( (x) < (y) ? (x) : (y) )
        #define MAX(x,y)( (x) > (y) ? (x) : (y) )
        
        // Polygon flags
        
        #define PF_CLIPPED_NEAR      0x01    // Which planes the polygon has been clipped against
        #define PF_CLIPPED_FAR       0x02
        #define PF_CLIPPED_LEFT      0x04
        #define PF_CLIPPED_RIGHT     0x08
        #define PF_CLIPPED_TOP       0x10        
        #define PF_CLIPPED_BOTTOM    0x20  

        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
        // Structures
        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬

        struct Polygon
        {
                float p1[4];     // first vertex
                float c1[3];     // first color
                float p2[4];     // second vertex...  and so on..
                float c2[3];
                float p3[4];
                float c3[3];
                int polyFlags;   // What clipping has been done, which verts are outside view frustrum..
        };

        struct Plane
        {
                float a;    // Plane normal x component
                float b;    // Plane normal y component
                float c;    // Plane normal z component
                float d;    // Perpendicular distance from plane to origin
        };

        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬
        // Functions
        //¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬¬

        void    R_ClearScreen      ();
        void    R_BeginDraw        ();        
        void    R_EndDraw          ();
        void    R_DrawPoly         ( struct Polygon * poly , bool doTransforms );
        void    R_DrawText         ( int x , int y , char * text );
        void    R_LoadIdentity     ();
        float * R_GetMatrix        ();
        void    R_RotateY          ( float degrees  );
        void    R_MInverseTransform( float * matrix );
        void    R_ShutDown         ();
        void    R_Init             ( HWND hwnd );
		void	R_InitDirect3D	   ();
        void    R_NormaliseVector  ( float * vector );
        void    R_MMult4x4_4x4     ( float * m1 , float * m2  );
        void    R_MMult4x4_4x1     ( float * m1 , float * m2  );
        void    R_Translate        ( float x  , float y , float z );
        void    R_ProjectionMode   ( float near , float far, float hfov );
        bool    R_RejectPoly       ( struct Polygon * pol , struct Plane * pl );
        void    R_ClipPoly         ( struct Polygon * pol , struct Plane * pl );
        void    R_ScanPoly         ( struct Polygon * pol );

        // Performance timing

        unsigned int    R_GetClockCount();
        void            R_UpdatePerformanceCounter();
        
        // External Assembly functions

        extern "C" 
            { 
            
            volatile void __cdecl R_ClearScreenASM
                (
                int numPixels   , 
                int * screenBuf , 
                float * depthBuf 
                ); 
            
            };
                     
        extern "C" 
            { 
            
            volatile void __cdecl R_ScanLineASM   
                (
                int   *         screen , 
                float *         depth  ,
                int             lenght ,                   
                float           zstart , 
                float           rstart , 
                float           gstart , 
                float           bstart ,                                                 
                float           zinc   , 
                float           rinc   , 
                float           ginc   ,                 
                float           binc                                   
                ); 
            };

#endif
