// lib2d.h // 2D Yaroze Development Library v1.0.0 // High performance macros & functions // Developed & compiled by Harvey Cotton // Copyright © 1998/1999 // E-mail: harvey.c@lineone.net // ****************************************************************************************************************** Defines // A collection of defines, most of which govern the control of this library. I would have stored the // values in constants or globals, but it is faster this way. // // Comment out the DEBUG line to prevent display of the vsyncs. // You must set the screen dimensions according to your game requirements. Allowable resolutions: // Horizontal: 256,320,368,512,640 and Vertical: 240,256,480,512 // The BG defines represent the RGB of the background each time the screen is cleared. The default is black. // You may want to adjust the OT length and packets as well. Use 256000 for packet length is you wish to trade // memory for performance. // Use DCACHE for local operations, it is about 5-6 times faster than addressing main memory. #define DEBUG #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 256 #define HALF_WIDTH 160 #define HALF_HEIGHT 128 #define BG_RED 0 #define BG_GREEN 0 #define BG_BLUE 0 #define ORDERING_TABLE_LENGTH 12 #define MAX_NO_PACKETS 128000 #define DCACHE 0x1f800000 #define TRUE 1 #define FALSE 0 // *********************************************************************************************************** Ordering table // // These are the main globals for the library. They are transparent from the programmer so you // don't have to worry about them. long CurrentBuffer; GsOT TableHeader [2]; GsOT_TAG TableArray [2][1<u=_w*_xf, \ (_s)->v=_h*_yf, \ (_s)->w=_w, \ (_s)->h=_h, \ (_s)->m=_w>>1, \ (_s)->my=_h>>1 #define SetLinePos(_l,_x0,_y0,_x1,_y1) \ (_l)->x0=_x0, \ (_l)->y0=_y0, \ (_l)->x1=_x1, \ (_l)->y1=_y1 #define SetRect(_r,_x,_y,_w,_h) \ (_r)->x=_x, \ (_r)->y=_y, \ (_r)->w=_w, \ (_r)->h=_h #define SetRGB(_x,_r,_g,_b) \ (_x)->r=_r, \ (_x)->g=_g, \ (_x)->b=_b #define SetRGB2(_x,_r0,_g0,_b0,_r1,_g1,_b1) \ (_x)->r0=_r0, \ (_x)->g0=_g0, \ (_x)->b0=_b0, \ (_x)->r1=_r1, \ (_x)->g1=_g1, \ (_x)->b1=_b1 // ********************************************************************************************************************* Math // // A large collection of math related functions and macros. Emphasis is on performance. // // BitSet() Set specific bit(s) to 1. E.g. 16 would set bit 4 to 1. // BitClear() Set specific bit(s) to 0. // BitCheck() Check to see if specific bit(s) are set to 1. // RGB2long() Convert RGB components into one value. // BoundsLimit() Limits a value remains within low and high limits. E.g. if value is 101 and bounds are 0-100, value becomes 100. // BoundsWrap() Wraps a value remains within low and high limits. E.g. if value is 100 and bounds are 0-100, value becomes 0. // Sign() Checks the sign on a value. Returns -1 for negative or 1 for positive. // Min() Returns the smallest of two values. // Max() Returns the highest of two values. // Bearing() Returns the angle (0-4095) from one point to another. // AngleDifference() Compares one angle to another. Result is always between 0-2048. // FCos() Returns the cosine of 0-360 fast. // FSin() Returns the sine of 0-360 fast. // MoveVectorX() Moves a point which faces a given direction (0-360), either left(-) or right(+). Useful for strafing. // MoveVectorY() Moves a point which faces a given direction (0-360), backwards(-) or forwards(+). // MoveVectorXY() Moves a point which faces a given direction (0-360), either up or down and left or right. // MoveSVectorX() Same as other except x,y or 16-bit values instead of 32-bit. // MoveSVectorY() Same as other except x,y or 16-bit values instead of 32-bit. // MoveSVectorXY() Same as other except x,y or 16-bit values instead of 32-bit. // IntergetSqrt() Calculate the integer square root of a value fast. // ATanFast() Calculate the tangent (angle between 0-4095) between 0,0 and x,y. // Distance() Accurately calculate the distance between two points. // DistanceFast() Calculate distance faster using approximation. Less accurate though with 3.5% error. // AdjustAngle() Adjust one angle (0-4095) at a specific position to face another position. Step (0-2048) is the amount to adjust the angle by. #define BitSet(_x,_b) (*(_x)=(*(_x))|(_b)) #define BitClear(_x,_b) (*(_x)-=(*(_x))&(_b)) #define BitCheck(_x,_b) (*(_x)&(_b)) #define RGB2long(_r,_g,_b) (_r+(_g<<8)+(_b<<16)) #define BoundsLimit(_x,_l,_h) ((_x)<(_l)?(_l):(_x)>(_h)?(_h):(_x)) #define BoundsWrap(_x,_l,_h) ((_x)<(_l)?(_x)+(_h)-(_l):(_x)>(_h)?(_x)-((_h)-(_l)):(_x)) #define Sign(_x) ((_x)<0?-1:1) #define Min(_x,_y) ((_x)<(_y)?(_x):(_y)) #define Max(_x,_y) ((_x)>(_y)?(_x):(_y)) #define Bearing(_x1,_y1,_x2,_y2) ATanFast(_x2-_x1,_y2-_y1) #define AngleDifference(_angle1,_angle2) (abs(_angle1-_angle2)>2048?abs(abs(_angle1-_angle2)-2048):abs(_angle1-_angle2)) short FCos (register short x); short FSin (register short x); void MoveVectorX (long *x,long *y,register short angle,register long dx); void MoveVectorY (long *x,long *y,register short angle,register long dy); void MoveVectorXY (long *x,long *y,register short angle,register long dx,register long dy); void MoveSVectorX (short *x,short *y,register short angle,register short dx); void MoveSVectorY (short *x,short *y,register short angle,register short dy); void MoveSVectorXY (short *x,short *y,register short angle,register short dx,register short dy); u_long IntegerSqrt (u_long x); short ATanFast (long x,long y); u_long Distance (long x1,long y1,long x2,long y2); u_long DistanceFast (long x,long y); void AdjustAngle (long *angle1,long step,long x1,long y1,long x2,long y2); // ****************************************************************************************************** Collision detection // // Here is a collection of very fast collision detection algorithms which should cover all of your needs. // I may add pixel perfect collision detection at a later date. // // Collision() Tests two rectanglar regions for overlap (x,y being the centre point and w,h being width & height). // PointCollision() Tests to see if x1,y1 lies within a rectanglar region (x2,y2 being the centre point and w2,h2 being width & height). // CircularCollision() Tests two circles for overlap (x,y being the centre point and r being the radius). // ClipSprite() Tests whether a sprite should be drawn or not (x,y being the centre point and w,h being width & height). // ClipSpriteFast() Tests whether a sprite should be drawn or not, but ignores width and height (x,y being the centre point). // ClipRelative() Clips an one point relative to another in a rectangular region (x,y being the positions with d being the distance). // PolygonCollision() Tests to see if a point lies within a polygon (you need to pass an array of coordinates to this). // LineIntersection() Checks to see if two seperate lines overlap. #define Collision(_x1,_y1,_w1,_h1,_x2,_y2,_w2,_h2) (((_w1+_w2)>>1)>abs(_x1-_x2) && ((_h1+_h2)>>1)>abs(_y1-_y2)) #define PointCollision(_x1,_y1,_x2,_y2,_w2,_h2) (abs(_x1-_x2)<(_w2>>1) && abs(_y1-_y2)<(_h2>>1)) #define CircularCollision(_x1,_y1,_r1,_x2,_y2,_r1) (_r1+_r2)>1)+HALF_WIDTH>abs(HALF_WIDTH-_x) && (_h>>1)+HALF_HEIGHT>abs(HALF_HEIGHT-_y)) #define ClipSpriteFast(_x,_y) (abs(HALF_WIDTH-_x)