/* * "ESCGBOXF.C" * * Part of The Escotia Playstation Library * * Author: ScoTT Campbell * Date: 10/9/98 * * Updated: 17/9/98 */ #include "..\headers\escgboxf.h" /* Prototypes for local functions */ static void SetColourArray(unsigned char* colourArray, unsigned char colour1, unsigned char colour2, int y1, int y2); /* An adaptation of Bresenham's algorithm used to work out colour gradation */ /******************************/ /* Start of EsGBOXF functions */ /******************************/ void InitGBoxF(EsGBOXF* boxPtr, int xPosition, int yPosition, int width, int height) { boxPtr->x = xPosition; boxPtr->y = yPosition; boxPtr->w = width; boxPtr->h = height; boxPtr->attribute = 0; boxPtr->r0 = boxPtr->g0 = boxPtr->b0 = 255; boxPtr->r1 = 0; boxPtr->g1 = 0; boxPtr->b1 = 255; boxPtr->r2 = 0; boxPtr->g2 = 255; boxPtr->b2 = 0; boxPtr->r3 = 255; boxPtr->g3 = 0; boxPtr->b3 = 0; }/* InitGBoxF */ void SetGBoxFPosition(EsGBOXF* boxPtr, int xPosition, int yPosition) { boxPtr->x = xPosition; boxPtr->y = yPosition; }/* SetGBoxFPosition */ void SetGBoxFXPosition(EsGBOXF* boxPtr, int xPosition) { boxPtr->x = xPosition; }/* SetGBoxFXPosition */ void SetGBoxFYPosition(EsGBOXF* boxPtr, int yPosition) { boxPtr->y = yPosition; }/* SetGBoxFYPosition */ void MoveGBoxF(EsGBOXF* boxPtr, int xAmount, int yAmount) { boxPtr->x += xAmount; boxPtr->y += yAmount; }/* MoveGBoxF */ void SetGBoxFSize(EsGBOXF* boxPtr, unsigned short int width, unsigned short int height) { boxPtr->w = width; boxPtr->h = height; }/* SetGBoxFSize */ void SetGBoxFWidth(EsGBOXF* boxPtr, unsigned short int width) { boxPtr->w = width; }/* SetGBoxFWidth */ void SetGBoxFHeight(EsGBOXF* boxPtr, unsigned short int height) { boxPtr->h = height; }/*SetGBoxFHeight */ int AdjustGBoxFHeight(EsGBOXF* boxPtr, int amount) { if((amount < 0) && (abs(amount) > boxPtr->h)) { boxPtr->h = 0; return 1; } else { boxPtr->h += amount; return 0; } } int AdjustGBoxFWidth(EsGBOXF* boxPtr, int amount) { if((amount < 0) && (abs(amount) > boxPtr->w)) { boxPtr->w = 0; return 1; } else { boxPtr->w += amount; return 0; } } void SetGBoxFAttributes(EsGBOXF* boxPtr, unsigned long int attributes) { /* Clear top 4 bits ready to set*/ boxPtr->attribute &= 0x0FFFFFFF; /* Set the bits we want */ boxPtr->attribute |= attributes; } void SetGBoxFColourVectors(EsGBOXF* boxPtr, CVECTOR* topLeftVectorPtr, CVECTOR* bottomLeftVectorPtr, CVECTOR* topRightVectorPtr, CVECTOR* bottomRightVectorPtr) { boxPtr->r0 = topLeftVectorPtr->r; boxPtr->g0 = topLeftVectorPtr->g; boxPtr->b0 = topLeftVectorPtr->b; boxPtr->r1 = bottomLeftVectorPtr->r; boxPtr->g1 = bottomLeftVectorPtr->g; boxPtr->b1 = bottomLeftVectorPtr->b; boxPtr->r2 = topRightVectorPtr->r; boxPtr->g2 = topRightVectorPtr->g; boxPtr->b2 = topRightVectorPtr->b; boxPtr->r3 = bottomRightVectorPtr->r; boxPtr->g3 = bottomRightVectorPtr->g; boxPtr->b3 = bottomRightVectorPtr->b; } void SetGBoxFTopLeftColourVector(EsGBOXF* boxPtr, CVECTOR* colourVectorPtr) { boxPtr->r0 = colourVectorPtr->r; boxPtr->g0 = colourVectorPtr->g; boxPtr->b0 = colourVectorPtr->b; } void SetGBoxFTopRightColourVector(EsGBOXF* boxPtr, CVECTOR* colourVectorPtr) { boxPtr->r2 = colourVectorPtr->r; boxPtr->g2 = colourVectorPtr->g; boxPtr->b2 = colourVectorPtr->b; } void SetGBoxFBottomLeftColourVector(EsGBOXF* boxPtr, CVECTOR* colourVectorPtr) { boxPtr->r1 = colourVectorPtr->r; boxPtr->g1 = colourVectorPtr->g; boxPtr->b1 = colourVectorPtr->b; } void SetGBoxFBottomRightColourVector(EsGBOXF* boxPtr, CVECTOR* colourVectorPtr) { boxPtr->r3 = colourVectorPtr->r; boxPtr->g3 = colourVectorPtr->g; boxPtr->b3 = colourVectorPtr->b; } void SetGBoxFColours(EsGBOXF* boxPtr, unsigned char r0, unsigned char g0, unsigned char b0, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2, unsigned char r3, unsigned char g3, unsigned char b3) { boxPtr->r0 = r0; boxPtr->g0 = g0; boxPtr->b0 = b0; boxPtr->r1 = r1; boxPtr->g1 = g1; boxPtr->b1 = b1; boxPtr->r2 = r2; boxPtr->g2 = g2; boxPtr->b2 = b2; boxPtr->r3 = r3; boxPtr->g3 = g3; boxPtr->b3 = b3; } void SetGBoxFTopLeftColour(EsGBOXF* boxPtr, unsigned char r, unsigned char g, unsigned char b) { boxPtr->r0 = r; boxPtr->g0 = g; boxPtr->b0 = b; } void SetGBoxFTopRightColour(EsGBOXF* boxPtr, unsigned char r, unsigned char g, unsigned char b) { boxPtr->r2 = r; boxPtr->g2 = g; boxPtr->b2 = b; } void SetGBoxFBottomLeftColour(EsGBOXF* boxPtr, unsigned char r, unsigned char g, unsigned char b) { boxPtr->r1 = r; boxPtr->g1 = g; boxPtr->b1 = b; } void SetGBoxFBottomRightColour(EsGBOXF* boxPtr, unsigned char r, unsigned char g, unsigned char b) { boxPtr->r3 = r; boxPtr->g3 = g; boxPtr->b3 = b; } int EsSortGBoxFill(EsGBOXF* boxPtr, GsOT* otPtr, unsigned short int pri) /* Creates the GBOXF using GLINEs */ { int i; GsGLINE line; int x0 = boxPtr->x; // Box x values int x1 = x0 + (boxPtr->w - 1); int y0 = boxPtr->y; // Box y values int y1 = y0 + (boxPtr->h - 1); unsigned char *r0Array, *r1Array; // red arrays unsigned char *g0Array, *g1Array; // green arrays unsigned char *b0Array, *b1Array; // blue arrays /* Check that something needs to be drawn */ if((boxPtr->w) && (boxPtr->h)) { /* Get the storage space for our arrays */ if(((r0Array = (unsigned char*) calloc((boxPtr->h), sizeof(unsigned char))) == NULL) || ((r1Array = (unsigned char*) calloc((boxPtr->h), sizeof(unsigned char))) == NULL) || ((g0Array = (unsigned char*) calloc((boxPtr->h), sizeof(unsigned char))) == NULL) || ((g1Array = (unsigned char*) calloc((boxPtr->h), sizeof(unsigned char))) == NULL) || ((b0Array = (unsigned char*) calloc((boxPtr->h), sizeof(unsigned char))) == NULL) || ((b1Array = (unsigned char*) calloc((boxPtr->h), sizeof(unsigned char))) == NULL)) return 1; // Can't get the space required /* Do the least we can in software */ if(boxPtr->w >= boxPtr->h) { /* Set our arrays with their colour values */ SetColourArray(r0Array, (boxPtr->r0), (boxPtr->r1), y0, y1); SetColourArray(r1Array, (boxPtr->r2), (boxPtr->r3), y0, y1); SetColourArray(g0Array, (boxPtr->g0), (boxPtr->g1), y0, y1); SetColourArray(g1Array, (boxPtr->g2), (boxPtr->g3), y0, y1); SetColourArray(b0Array, (boxPtr->b0), (boxPtr->b1), y0, y1); SetColourArray(b1Array, (boxPtr->b2), (boxPtr->b3), y0, y1); /* Draw the box with the values from the arrays */ line.attribute = boxPtr->attribute; line.x0 = x0; line.x1 = x1; line.y0 = line.y1 = y0; for(i=0;i<(boxPtr->h);i++) { line.r0 = r0Array[i]; line.r1 = r1Array[i]; line.g0 = g0Array[i]; line.g1 = g1Array[i]; line.b0 = b0Array[i]; line.b1 = b1Array[i]; GsSortGLine(&line, otPtr, pri); line.y0++; line.y1++; } } else { /* Set our arrays with their colour values */ SetColourArray(r0Array, (boxPtr->r0), (boxPtr->r2), x0, x1); SetColourArray(r1Array, (boxPtr->r1), (boxPtr->r3), x0, x1); SetColourArray(g0Array, (boxPtr->g0), (boxPtr->g2), x0, x1); SetColourArray(g1Array, (boxPtr->g1), (boxPtr->g3), x0, x1); SetColourArray(b0Array, (boxPtr->b0), (boxPtr->b2), x0, x1); SetColourArray(b1Array, (boxPtr->b1), (boxPtr->b3), x0, x1); /* Draw the box with the values from the arrays */ line.attribute = boxPtr->attribute; line.x0 = line.x1 = x0; line.y0 = y0; line.y1 = y1; for(i=0;i<(boxPtr->w);i++) { line.r0 = r0Array[i]; line.r1 = r1Array[i]; line.g0 = g0Array[i]; line.g1 = g1Array[i]; line.b0 = b0Array[i]; line.b1 = b1Array[i]; GsSortGLine(&line, otPtr, pri); line.x0++; line.x1++; } } /* Free up the memory assigned for the arrays */ free((void*)r0Array); free((void*)r1Array); free((void*)g0Array); free((void*)g1Array); free((void*)b0Array); free((void*)b1Array); } return 0; } /****************************/ /* End of EsGBOXF functions */ /****************************/ /************************/ /* Local Functions */ /************************/ static void SetColourArray(unsigned char* colourArray, unsigned char colour1, unsigned char colour2, int position1, int position2) /* An adaptation of Bresenham's algorithm */ { int i; int total = colour1; int count=1; int error; int colourIncrement, positionIncrement; int colour = colour1; int position = 0; int deltaColour = ((int)colour2) - colour1; int deltaPosition = ((int)position2) - position1; int absDeltaColour = abs(deltaColour); int absDeltaPosition = abs(deltaPosition); char colourMajor = abs(deltaColour) > abs(deltaPosition); if(deltaColour >= 0) colourIncrement = 1; else colourIncrement = -1; if(deltaPosition >= 0) positionIncrement = 1; else positionIncrement = -1; if(colourMajor) { /* This part of the function has an non-cumulative error of + or - 1 for each element */ error = (absDeltaPosition<<1) - absDeltaColour; for(i=0;i= 0) { colourArray[position] = total/count; position += positionIncrement; error -= (absDeltaColour<<1); total = 0; count = 0; } error += (absDeltaPosition<<1); total += colour; count++; } /* Make sure that our start and end elements are spot on */ colourArray[0] = colour1; colourArray[absDeltaPosition] = colour2; } else { /* Bresenham's algorithm */ colourArray[0] = colour1; error = (absDeltaColour<<1) - absDeltaPosition; for(i=0;i= 0) { colour += colourIncrement; error -= (absDeltaPosition<<1); } error += (absDeltaColour<<1); colourArray[position] = colour; } } }/* SetColourArray */