#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include "main.h"
#include "atoms.h"

extern atom atoms[MAXATOMS];

atompoint atompoints[MAXATOMPOINTS];
triangle2d triangles[MAXTRIANGLES];
int atompoint_num = 0, triangle_num = 0;

short edgeXL[GameScreenHeight], edgeXR[GameScreenHeight];
vertex *tp1, *tp2, *tp3;
vertex fp1, fp2, fp3;

void RenderLine (int x1, int y1, int x2, int y2, unsigned int *vram, int c)
{
	int dx, dy, n, l;
	int x00, y00;
	int fp = 12;
	int vramofs;

	int x, y;

	dx = x2 - x1;
	dy = y2 - y1;

	if (abs(dy) < abs(dx))
	{
		if (x1>x2)
		{
			n = x1; x1 = x2; x2 = n;
			n = y1; y1 = y2; y2 = n;
		}

        if (dx!=0) l = (dy<<fp)/dx;
        y00 = y1<<fp;
		for (x=x1; x<x2; x++)
		{
			vramofs = ((y00 += l)>>fp)*GameScreenWidth + x;
            if (vramofs>=0 && vramofs<GameScreenSize) *(vram + vramofs) = c;
		}
	}
	else
	{

		if (y1>y2)
		{
			n = y1; y1 = y2; y2 = n;
			n = x1; x1 = x2; x2 = n;
		}

        if (dy!=0) l = (dx<<fp)/dy;
        x00 = x1<<fp;

		for (y=y1; y<y2; y++)
		{
			vramofs = y*GameScreenWidth + ((x00 += l)>>fp);
            if (vramofs>=0 && vramofs<GameScreenSize)  * (vram + vramofs) = c;
		}

	}
}


void RenderAntialiasedLine(int x1, int y1, int x2, int y2,unsigned int *vram, int c)
{
	int a = (c>>24) & 255;
	int r = (c>>16) & 255;
	int g = (c>>8) & 255;
	int b = c & 255;

    // ==== Clipping ====

    int outcode1 = 0, outcode2 = 0;

    if (y1 < 1) outcode1 |= 0x0001;
        else if (y1 > GameScreenHeight-2) outcode1 |= 0x0010;
    if (x1 < 1) outcode1 |= 0x0100;
        else if (x1 > GameScreenWidth-2) outcode1 |= 0x1000;

    if (y2 < 1) outcode2 |= 0x0001;
        else if (y2 > GameScreenHeight-2) outcode2 |= 0x0010;
    if (x2 < 1) outcode2 |= 0x0100;
        else if (x2 > GameScreenWidth-2) outcode2 |= 0x1000;

    if ((outcode1 & outcode2)!=0) return;
    if ((outcode1 | outcode2)!=0) return; // normally, should check for possible clip
    // ==================

	int dx, dy, l;
	int x00, y00;
	int vramofs;

	int x, y;
	int frac, alpha;

	dx = x2 - x1;
	dy = y2 - y1;

	int temp;
	int c0;
	int r1, g1, b1;
	int r2, g2, b2;

    int chdx = dx, chdy = dy;
    if (dx<0) chdx = -dx;
    if (dy<0) chdy = -dy;

	if (chdy < chdx)
	{
		if (x1 > x2)
		{
			temp = x1; x1 = x2; x2 = temp;
			temp = y1; y1 = y2; y2 = temp;
		}

        if (dx!=0) l = (dy << FPSHR) / dx;
        y00 = y1 << FPSHR;
		for (x=x1; x<x2; x++)
		{
			vramofs = (y00>>FPSHR)*GameScreenWidth + x;
			frac = y00 & FPAND;

			c0 = *(vram + vramofs);
			r2 = (c0 >> 16) & 255;
			g2 = (c0 >> 8) & 255;
			b2 = c0 & 255;

			alpha = (((65535 - frac)>>8) * a) >> 8;
			r1 = r2 + (((r - r2) * alpha) >> 8);
			g1 = g2 + (((g - g2) * alpha) >> 8);
			b1 = b2 + (((b - b2) * alpha) >> 8);

            *(vram + vramofs) = (r1 << 16) | (g1 << 8) | b1;


			c0 = *(vram + vramofs+GameScreenWidth);
			r2 = (c0 >> 16) & 255;
			g2 = (c0 >> 8) & 255;
			b2 = c0 & 255;

			alpha = ((frac >> 8) * a) >> 8;
			r1 = r2 + (((r - r2) * alpha) >> 8);
			g1 = g2 + (((g - g2) * alpha) >> 8);
			b1 = b2 + (((b - b2) * alpha) >> 8);

            *(vram + vramofs+GameScreenWidth) = (r1 << 16) | (g1 << 8) | b1;
            y00+=l;
		}
	}
	else
	{

		if (y1 > y2)
		{
			temp = x1; x1 = x2; x2 = temp;
			temp = y1; y1 = y2; y2 = temp;
		}

        if (dy!=0) l = (dx << FPSHR) / dy;
        x00 = x1 << FPSHR;

		for (y=y1; y<y2; y++)
		{
			vramofs = y*GameScreenWidth + (x00>>FPSHR);
			frac = x00 & FPAND;

			c0 = *(vram + vramofs);
			r2 = (c0 >> 16) & 255;
			g2 = (c0 >> 8) & 255;
			b2 = c0 & 255;

			alpha = (((65535 - frac)>>8) * a) >> 8;
			r1 = r2 + (((r - r2) * alpha) >> 8);
			g1 = g2 + (((g - g2) * alpha) >> 8);
			b1 = b2 + (((b - b2) * alpha) >> 8);

            *(vram + vramofs) = (r1 << 16) | (g1 << 8) | b1;


			c0 = *(vram + vramofs + 1);
			r2 = (c0 >> 16) & 255;
			g2 = (c0 >> 8) & 255;
			b2 = c0 & 255;

			alpha = ((frac >> 8) * a) >> 8;
			r1 = r2 + (((r - r2) * alpha) >> 8);
			g1 = g2 + (((g - g2) * alpha) >> 8);
			b1 = b2 + (((b - b2) * alpha) >> 8);

            *(vram + vramofs + 1) = (r1 << 16) | (g1 << 8) | b1;

            x00+=l;
		}

	}
}

void DrawLine(int x1, int y1, int x2, int y2, unsigned int *vram, int c, bool antialiased)
{
	if (!antialiased) RenderLine(x1, y1, x2, y2, vram, c);
	    else RenderAntialiasedLine(x1, y1, x2, y2, vram, c);
}


static inline int SetupTriangle(triangle2d *triangle)
{
    atompoint *a0 = &atompoints[triangle->p0];
    atompoint *a1 = &atompoints[triangle->p1];
    atompoint *a2 = &atompoints[triangle->p2];

	vertex *sp1 = &fp1;
	vertex *sp2 = &fp2;
	vertex *sp3 = &fp3;

    sp1->x = atoms[a0->a].pos.x; sp1->y = atoms[a0->a].pos.y;
    sp2->x = atoms[a1->a].pos.x; sp2->y = atoms[a1->a].pos.y;
    sp3->x = atoms[a2->a].pos.x; sp3->y = atoms[a2->a].pos.y;

    // ==== Clipping ====

    int outcode1 = 0, outcode2 = 0, outcode3 = 0, outcode4 = 0;

    if (sp1->y < 0) outcode1 |= 0x0001;
        else if (sp1->y > GameScreenHeight-1) outcode1 |= 0x0010;
    if (sp1->x < 0) outcode1 |= 0x0100;
        else if (sp1->x > GameScreenWidth-1) outcode1 |= 0x1000;

    if (sp2->y < 0) outcode2 |= 0x0001;
        else if (sp2->y > GameScreenHeight-1) outcode2 |= 0x0010;
    if (sp2->x < 0) outcode2 |= 0x0100;
        else if (sp2->x > GameScreenWidth-1) outcode2 |= 0x1000;

    if (sp3->y < 0) outcode3 |= 0x0001;
        else if (sp3->y > GameScreenHeight-1) outcode3 |= 0x0010;
    if (sp3->x < 0) outcode3 |= 0x0100;
        else if (sp3->x > GameScreenWidth-1) outcode3 |= 0x1000;

    if ((outcode1 & outcode2 & outcode3)!=0) return 0;
    if ((outcode1 | outcode2 | outcode3)!=0) return 0; // normally, should check for possible clip
    // ==================

    short *edge1, *edge2;
    int x, y, dx;

    // ==== Y sorting ====

    if ((sp1->y < sp2->y) && (sp1->y < sp3->y))
    {
        tp1 = sp1;
        if (sp2->y < sp3->y)
        {
            tp2 = sp2; tp3 = sp3;
        }
        else
        {
            tp2 = sp3; tp3 = sp2;
        }
    }
    else if (sp2->y < sp3->y)
    {
        tp1 = sp2;
        if (sp3->y < sp1->y)
        {
            tp2 = sp3; tp3 = sp1;
        }
        else
        {
            tp2 = sp1; tp3 = sp3;
        }
    }
    else
    {
        tp1 = sp3;
        if (sp1->y < sp2->y)
        {
            tp2 = sp1; tp3 = sp2;
        }
        else
        {
            tp2 = sp2; tp3 = sp1;
        }
    }

	int checkx;
    // ==== L13 edge side check ====

    if (tp1->y!=tp3->y) dx = ((tp3->x - tp1->x) << FPSHR) / (tp3->y - tp1->y);
    	else return 0;
    checkx = ((tp1->x << FPSHR) + (tp2->y - tp1->y) * dx) >> FPSHR;

    if (checkx<tp2->x)
    {
        edge1 = edgeXL;
        edge2 = edgeXR;
    }
    else
    {
        edge1 = edgeXR;
        edge2 = edgeXL;
    }

	if (tp1->y < 0) tp1->y =0;	if (tp1->y > GameScreenHeight-1) tp1->y = GameScreenHeight - 1;
	if (tp2->y < 0) tp2->y =0;	if (tp2->y > GameScreenHeight-1) tp2->y = GameScreenHeight - 1;
	if (tp3->y < 0) tp3->y =0;	if (tp3->y > GameScreenHeight-1) tp3->y = GameScreenHeight - 1;

    // ==== Interpolation X ====

	// --- L13 ---
    x = tp1->x << FPSHR;
    for (y = tp1->y; y<=tp3->y; y++)
    {
        edge1[y] = x >> FPSHR;
        x+=dx;
    }

    // --- L12 ---
    if (tp1->y!=tp2->y)
    {
		dx = ((tp2->x - tp1->x) << FPSHR) / (tp2->y - tp1->y);
	    x = tp1->x << FPSHR;
	    for (y = tp1->y; y<=tp2->y; y++)
	    {
	        edge2[y] = x >> FPSHR;
	        x+=dx;
	    }
	}

    // --- L23 ---
    if (tp2->y!=tp3->y)
    {
		dx = ((tp3->x - tp2->x) << FPSHR) / (tp3->y - tp2->y);
	    x = tp2->x << FPSHR;
	    for (y = tp2->y; y<=tp3->y; y++)
	    {
	        edge2[y] = x >> FPSHR;
	        x+=dx;
	    }
	}
    return 1;
}

static inline void RenderFlatTriangleBlob(unsigned char *src, unsigned int *vram)
{
    int x, y;
    int c = 0xFFFFFF;
    int x1, x2;

    vram += tp1->y * GameScreenWidth;
    src += tp1->y * GameScreenWidth;
    for (y = tp1->y; y<=tp3->y; y++)
    {
        x1 = edgeXL[y];
        x2 = edgeXR[y];
        for (x = x1; x<=x2; x++)
        {
            *(vram + x) = c;
            c += *(src+x);
            if (c>255) c = 255;
            *(src+x) = c;
            *(vram+x) = (c<<16) | (c<<8) | c;
        }
        vram += GameScreenWidth;
        src += GameScreenWidth;
    }
}


void DrawFlatTriangleBlob(triangle2d *triangle, unsigned char *src, unsigned int *vram)
{
	if (SetupTriangle(triangle))
	    RenderFlatTriangleBlob(src, vram);
}


void RenderBackground(image *img, unsigned int *vram)
{
	unsigned int *src = img->data;
	int size = img->width * img->height;

	while(size--!=0)
		*vram++ = *src++;
}


void Blit(SDL_Surface *src, SDL_Surface *dst, int xp, int yp)
{
	int x, y;
	unsigned int *destination = (unsigned int*)dst->pixels;
	unsigned int *source = (unsigned int*)src->pixels;
	destination+=(xp+yp*dst->w);
	for (y=0; y<src->h; y++)
	{
	    for (x=0; x<src->w; x++)
		{
			*(destination+x) = *source++;
		}
		destination+=dst->w;
	}
}


void RenderSprite(int px, int py, image *img, unsigned int *vram, int surf_width, int surf_height)
{
    int x, y;
    int x0 = 0, y0 = 0;
    int x1 = img->width - 1, y1 = img->height - 1;

	px -= img->width/2;
	py -= img->height/2;

    if ((px < surf_width) && (px > -img->width) && (py < surf_height) && (py > -img->height))
    {
        if (px<0)
        {
            x0 = - px; px = 0;
        }
        if (py<0)
        {
            y0 = - py; py = 0;
        }
        if (px > surf_width - img->width) x1 = surf_width + x0 - px - 1;
        if (py > surf_height - img->height) y1 = surf_height + y0 - py - 1;

        int vofs = px + py * surf_width;
        int bofs = x0 + y0 * img->width;

		unsigned int *src = img->data + bofs;
		vram += vofs;

        unsigned char alpha, r1, g1, b1, r2, g2, b2;
        unsigned int c;

        for (y = y0; y<=y1; y++)
        {
            for (x = x0; x<=x1; x++)
            {
				c = *src++;
				alpha = c >> 24;
				r1 = (c >> 16) & 255;
				g1 = (c >> 8) & 255;
				b1 = c & 255;

				c = *vram;
				r2 = (c >> 16) & 255;
				g2 = (c >> 8) & 255;
				b2 = c & 255;

				r1 = r2 + (((r1 - r2) * alpha) >> 8);
				g1 = g2 + (((g1 - g2) * alpha) >> 8);
				b1 = b2 + (((b1 - b2) * alpha) >> 8);

				*vram++ = (r1<<16) | (g1<<8) | b1;
            }
            vram += -(x1-x0+1) + surf_width;
            src += -(x1-x0+1) + img->width;
        }
    }
}

void RenderCursor(int px, int py, image *img, unsigned int *vram)
{
    int x, y;
    int x0 = 0, y0 = 0;
    int x1 = img->width - 1, y1 = img->height - 1;

	px -= img->width/2;
	py -= img->height/2;

    if ((px < ScreenWidth) && (px > -img->width) && (py < ScreenHeight) && (py > -img->height))
    {
        if (px<0)
        {
            x0 = - px; px = 0;
        }
        if (py<0)
        {
            y0 = - py; py = 0;
        }
        if (px > ScreenWidth - img->width) x1 = ScreenWidth + x0 - px - 1;
        if (py > ScreenHeight - img->height) y1 = ScreenHeight + y0 - py - 1;

        int vofs = px + py * ScreenWidth;
        int bofs = x0 + y0 * img->width;

		unsigned int *src = img->data + bofs;
		vram += vofs;

        unsigned char alpha, r1, g1, b1, r2, g2, b2;
        unsigned int c;

        for (y = y0; y<=y1; y++)
        {
            for (x = x0; x<=x1; x++)
            {
				c = *src++;
				alpha = c >> 24;
				r1 = (c >> 16) & 255;
				g1 = (c >> 8) & 255;
				b1 = c & 255;

				c = *vram;
				r2 = (c >> 16) & 255;
				g2 = (c >> 8) & 255;
				b2 = c & 255;

				r1 = r2 + (((r1 - r2) * alpha) >> 8);
				g1 = g2 + (((g1 - g2) * alpha) >> 8);
				b1 = b2 + (((b1 - b2) * alpha) >> 8);

				*vram++ = (r1<<16) | (g1<<8) | b1;
            }
            vram += -(x1-x0+1) + ScreenWidth;
            src += -(x1-x0+1) + img->width;
        }
    }
}

void RenderZoomSpriteNearest(int px, int py, float zx, float zy, image *img, unsigned int *vram, int surf_width, int surf_height)
{
    int xc = px;
    int yc = py;

    int imgSHR = (int)(float)(log(img->width)/log(2));

    int x, y;
    int x0 = 0, y0 = 0;
    int x1 = (int)(img->width * zx - 1), y1 = (int)(img->height * zy - 1);

    int xi = (int)(xc - (img->width >> 1) * zx);
    int yi = (int)(yc - (img->height >> 1) * zy);

    if ((xi < surf_width) && (xi > -img->width * zx) && (yi < surf_height) && (yi > -img->height * zy))
    {
    	int fp = 16, mulfp = (int)pow(2,fp);
        int su = 0, sv = 0;

        if (xi<0)
        {
            x0 = - xi; xi = 0;
            su = (int)((x0<<fp)/zx);
        }
        if (yi<0)
        {
            y0 = - yi; yi = 0;
            sv = (int)((y0<<fp)/zy);
        }
        if (xi > surf_width - (zx * img->width)) x1 = surf_width + x0 - xi - 1;
        if (yi > surf_height - (zy * img->width)) y1 = surf_height + y0 - yi - 1;

        int vofs= xi + yi * surf_width;
        unsigned char alpha, r1, g1, b1, r2, g2, b2;
        unsigned int c;

        int dix = (int)(mulfp/zx);
        int diy = (int)(mulfp/zy);
        int u, v, up;
        int i = vofs;

        v = sv;
        for (y = y0; y<=y1; y++)
        {
            u = su;
            up = ((v>>fp)<<imgSHR);
            for (x = x0; x<=x1; x++)
            {
                c = img->data[(u>>fp) + up];

				alpha = c >> 24;
				r1 = (c >> 16) & 255;
				g1 = (c >> 8) & 255;
				b1 = c & 255;

				c = *(vram + i);
				r2 = (c >> 16) & 255;
				g2 = (c >> 8) & 255;
				b2 = c & 255;

				r1 = r2 + (((r1 - r2) * alpha) >> 8);
				g1 = g2 + (((g1 - g2) * alpha) >> 8);
				b1 = b2 + (((b1 - b2) * alpha) >> 8);

				*(vram + i) = (r1<<16) | (g1<<8) | b1;
                i++;
                u+=dix;
            }
            v+=diy;
            i += -(x1-x0+1) + surf_width;
        }
    }
}


void RenderZoomSpriteBilinear(int px, int py, float zx, float zy, image *img, unsigned int *vram, int surf_width, int surf_height)
{
    int xc = px;
    int yc = py;

	int fpshr = 16;
	int fpmul = pow(2,fpshr);

    int imgSHR = (int)(float)(log(img->width)/log(2));

    int x, y;
    int x0 = 0, y0 = 0;
    int x1 = (int)(img->width * zx - 1), y1 = (int)(img->height * zy - 1);

    int xi = (int)(xc - (img->width >> 1) * zx);
    int yi = (int)(yc - (img->height >> 1) * zy);

    if ((xi < surf_width) && (xi > -img->width * zx) && (yi < surf_height) && (yi > -img->height * zy))
    {
    	int fp = 16, mulfp = (int)pow(2,fp);
        int su = 0, sv = 0;

        if (xi<0)
        {
            x0 = - xi; xi = 0;
            su = (int)((x0<<fp)/zx);
        }
        if (yi<0)
        {
            y0 = - yi; yi = 0;
            sv = (int)((y0<<fp)/zy);
        }
        if (xi > surf_width - (zx * img->width)) x1 = surf_width + x0 - xi - 1;
        if (yi > surf_height - (zy * img->width)) y1 = surf_height + y0 - yi - 1;

        int vofs= xi + yi * surf_width;
        unsigned char alpha, r4, g4, b4, r5, g5, b5;
        unsigned int c, a, r, g, b;

	    int mxh0, myh0, mxh1, myh1;
	    int mxl, myl;

	    int a0, r0, g0, b0;
	    int a1, r1, g1, b1;
	    int a2, r2, g2, b2;
	    int a3, r3, g3, b3;
	    int ax_top, rx_top, gx_top, bx_top;
	    int ax_bottom, rx_bottom, gx_bottom, bx_bottom;

        int dix = (int)(mulfp/zx);
        int diy = (int)(mulfp/zy);
        int u, v, up;
        int i = vofs;

        v = sv;
        for (y = y0; y<=y1; y++)
        {
            u = su;
            up = ((v>>fp)<<imgSHR);
            for (x = x0; x<=x1; x++)
            {
                mxl = u & (fpmul - 1); myl = v & (fpmul - 1);
                mxh0 = (u >>fpshr) % img->width; myh0 = ((v >> fpshr) % img->height) * img->width;
                mxh1 = (mxh0 + 1) % img->width; myh1 = (((v >> fpshr)+1) % img->height) * img->width;

                c = img->data[mxh0 + myh0]; a0 = (c >> 24) & 255; r0 = (c >> 16) & 255; g0 = (c >> 8) & 255; b0 = c & 255;
                c = img->data[mxh1 + myh0]; a1 = (c >> 24) & 255; r1 = (c >> 16) & 255; g1 = (c >> 8) & 255; b1 = c & 255;
                c = img->data[mxh0 + myh1]; a2 = (c >> 24) & 255; r2 = (c >> 16) & 255; g2 = (c >> 8) & 255; b2 = c & 255;
                c = img->data[mxh1 + myh1]; a3 = (c >> 24) & 255; r3 = (c >> 16) & 255; g3 = (c >> 8) & 255; b3 = c & 255;

                ax_top = a0 + (((a1 - a0) * mxl) >> fpshr);
                rx_top = r0 + (((r1 - r0) * mxl) >> fpshr);
                gx_top = g0 + (((g1 - g0) * mxl) >> fpshr);
                bx_top = b0 + (((b1 - b0) * mxl) >> fpshr);

                ax_bottom = a2 + (((a3 - a2) * mxl) >> fpshr);
                rx_bottom = r2 + (((r3 - r2) * mxl) >> fpshr);
                gx_bottom = g2 + (((g3 - g2) * mxl) >> fpshr);
                bx_bottom = b2 + (((b3 - b2) * mxl) >> fpshr);

                a = ax_top + (((ax_bottom - ax_top) * myl) >> fpshr);
                r = rx_top + (((rx_bottom - rx_top) * myl) >> fpshr);
                g = gx_top + (((gx_bottom - gx_top) * myl) >> fpshr);
                b = bx_top + (((bx_bottom - bx_top) * myl) >> fpshr);

				c = (a<<24) | (r<<16) | (g<<8) | b;

				alpha = c >> 24;
				r4 = (c >> 16) & 255;
				g4 = (c >> 8) & 255;
				b4 = c & 255;

				c = *(vram + i);
				r5 = (c >> 16) & 255;
				g5 = (c >> 8) & 255;
				b5 = c & 255;

				r4 = r5 + (((r4 - r5) * alpha) >> 8);
				g4 = g5 + (((g4 - g5) * alpha) >> 8);
				b4 = b5 + (((b4 - b5) * alpha) >> 8);

				*(vram + i) = (r4<<16) | (g4<<8) | b4;
                i++;
                u+=dix;
            }
            v+=diy;
            i += -(x1-x0+1) + surf_width;
        }
    }
}


void RenderZoomSprite(int px, int py, float zx, float zy, image *img, unsigned int *vram, int surf_width, int surf_height, bool filtering)
{
    if (filtering) RenderZoomSpriteBilinear(px, py, zx, zy, img, vram, surf_width, surf_height);
        else RenderZoomSpriteNearest(px, py, zx, zy, img, vram, surf_width, surf_height);
}

void RenderBox(int x1, int y1, int x2, int y2, unsigned int c, unsigned int *vram)
{
	int x, y;
	int yp = y1 * GameScreenWidth;

	int r0, g0, b0;
	int r1, g1, b1;
	int r2, g2, b2;
	int alpha;

	alpha = (c>>24) & 255;

	if (alpha==255)
	{
		for (y=y1; y<=y2; y++)
		{
		    for (x=x1; x<=x2; x++)
		    {
		        *(vram+x+yp) = c;
			}
			yp+=GameScreenWidth;
		}
	}
	else
	{
		r1 = (c>>16) & 255;
		g1 = (c>>8) & 255;
		b1 = c & 255;

		for (y=y1; y<=y2; y++)
		{
		    for (x=x1; x<=x2; x++)
		    {
				c = *(vram+x+yp);
				r0 = (c>>16) & 255;
				g0 = (c>>8) & 255;
				b0 = c & 255;

				r2 = r0 + (((r1 - r0) * alpha) >> 8);
				g2 = g0 + (((g1 - g0) * alpha) >> 8);
				b2 = b0 + (((b1 - b0) * alpha) >> 8);
				c = (r2<<16) | (g2<<8) | b2;
		        *(vram+x+yp) = c;
			}
			yp+=GameScreenWidth;
		}
	}
}

void RenderBoxLine(int x1, int y1, int x2, int y2, unsigned int c, unsigned int *vram, int swidth)
{
	int x, y, i;
	for (y=y1; y<=y2; y++)
	{
        *(vram+x1+y*swidth) = c;
        *(vram+x2+y*swidth) = c;
	}
	for (x=x1; x<=x2; x++)
	{
	    *(vram+x+y1*swidth) = c;
	    *(vram+x+y2*swidth) = c;
	}
}

void ColorInterpolation(colorARGB c1, colorARGB c2, float percentage, colorARGB *c)
{
	c->a = percentage * c2.a + (1 - percentage) * c1.a;
	c->r = percentage * c2.r + (1 - percentage) * c1.r;
	c->g = percentage * c2.g + (1 - percentage) * c1.g;
	c->b = percentage * c2.b + (1 - percentage) * c1.b;
}

unsigned int ColorARGB2int(colorARGB *col)
{
	unsigned int c = (col->a << 24) | (col->r << 16) | (col->g << 8) | col->b;
	return c;
}

void CopyColor(colorARGB c1, colorARGB *c)
{
	c->a = c1.a;
	c->r = c1.r;
	c->g = c1.g;
	c->b = c1.b;
}
