dsgmLib/source/DSGM_misc.c
2016-01-09 10:13:14 +00:00

165 lines
4.8 KiB
C

#include "DSGM.h"
#define DSGM_LegacySin(angle) (sinLerp(angle << 6) >> 4)
#define DSGM_LegacyCos(angle) (cosLerp(angle << 6) >> 4)
inline int DSGM_GetBrightness(u8 screen) {
int v = (screen == DSGM_TOP ? REG_MASTER_BRIGHT : REG_MASTER_BRIGHT_SUB);
return (v - (v & 1 << 14)) < 16 ? (v - (v & 1 << 14)) : -(v - (v & 2 << 14));
}
void DSGM_FadeIn(u8 screen, u8 delay) {
int brightness = DSGM_GetBrightness(screen);
if(brightness == -15) {
// Fade in from black
while(brightness < 0) {
brightness += 1;
DSGM_SetBrightness(screen, brightness);
int i; for(i = 0; i < delay; i++) swiWaitForVBlank();
}
}
else if(brightness == 15) {
// Fade in from white
while(brightness > 0) {
brightness -= 1;
DSGM_SetBrightness(screen, brightness);
int i; for(i = 0; i < delay; i++) swiWaitForVBlank();
}
}
}
void DSGM_FadeOutToBlack(u8 screen, u8 delay) {
int brightness = DSGM_GetBrightness(screen);
while(brightness > -15) {
brightness -= 1;
DSGM_SetBrightness(screen, brightness);
int i; for(i = 0; i < delay; i++) swiWaitForVBlank();
}
}
void DSGM_FadeOutToWhite(u8 screen, u8 delay) {
int brightness = DSGM_GetBrightness(screen);
while(brightness < 15) {
brightness += 1;
DSGM_SetBrightness(screen, brightness);
int i; for(i = 0; i < delay; i++) swiWaitForVBlank();
}
}
inline u64 DSGM_SquareDistance(s32 x1, s32 y1, s32 x2, s32 y2) {
s64 h = x1 - x2;
s64 v = y1 - y2;
return h * h + v * v;
}
inline u64 DSGM_Distance(s32 x1, s32 y1, s32 x2, s32 y2) {
s64 h = x1 - x2;
s64 v = y1 - y2;
return sqrt32(h * h + v * v);
}
static u16 DSGM_AdjustAngle(u16 angle, s16 anglerot, s32 startx, s32 starty, s32 targetx, s32 targety) {
u64 distances[3];
startx = startx << 10; // 8
starty = starty << 10; // 8
targetx = targetx << 10; // 8
targety = targety << 10; // 8
u16 tempangle = (angle - anglerot) & (511 << 6);
distances[0] = DSGM_SquareDistance(startx + cosLerp(tempangle), starty - sinLerp(tempangle), targetx, targety);
tempangle += anglerot;
tempangle &= 511 << 6;
distances[1] = DSGM_SquareDistance(startx + cosLerp(tempangle), starty - sinLerp(tempangle), targetx, targety);
tempangle += anglerot;
tempangle &= 511 << 6;
distances[2] = DSGM_SquareDistance(startx + cosLerp(tempangle), starty - sinLerp(tempangle), targetx, targety);
if(distances[0] < distances[1]) angle -= anglerot;
else if(distances[2] < distances[1]) angle += anglerot;
return angle & (511 << 6);
}
inline u16 DSGM_GetAngle(s32 startx, s32 starty, s32 targetx, s32 targety) {
u16 angle = 0;
u16 anglerot = 180 << 6;
while(anglerot > 5 << 6) {
angle = DSGM_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
anglerot = (anglerot - ((3 * anglerot) >> 3));
}
anglerot = 4 << 6;
angle = DSGM_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
anglerot = 2 << 6;
angle = DSGM_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
anglerot = 1 << 6;
angle = DSGM_AdjustAngle(angle, anglerot, startx, starty, targetx, targety);
return angle;
}
inline int DSGM_Random(int min, int max) {
return (rand() % (max - min + 1)) + min;
}
void DSGM_Delay(unsigned int time) {
int i;
for(i = 0; i < time; i++) {
swiWaitForVBlank();
}
}
unsigned int DSGM_GetWordLength(char *text) {
int i;
int len = strlen(text);
for(i = 0; i < len; i++) {
if(text[i] == ' ' || text[i] == '\n') break;
}
return i;
}
// Taken from: http://alienryderflex.com/intersect/
bool DSGM_Intersection(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy) {
double distAB, theCos, theSin, newX, ABpos;
// Fail if either line segment is zero-length
if((Ax == Bx && Ay == By) || (Cx == Dx && Cy == Dy)) return false;
// Fail if the segments share an end-point
if((Ax == Cx && Ay == Cy) || (Bx == Cx && By == Cy) || (Ax == Dx && Ay == Dy) || (Bx == Dx && By == Dy)) return false;
// Translate the system so that point A is on the origin
Bx -= Ax; By -= Ay;
Cx -= Ax; Cy -= Ay;
Dx -= Ax; Dy -= Ay;
// Discover the length of segment A-B
distAB = sqrt32(Bx * Bx + By * By);
// Rotate the system so that point B is on the positive X axis
theCos = Bx / distAB;
theSin = By / distAB;
newX = Cx * theCos + Cy * theSin;
Cy = Cy * theCos - Cx * theSin; Cx = newX;
newX = Dx * theCos + Dy * theSin;
Dy = Dy * theCos - Dx * theSin; Dx = newX;
// Fail if segment C-D doesn't cross line A-B
if((Cy < 0. && Dy < 0.) || (Cy >= 0. && Dy >= 0.)) return false;
// Discover the position of the intersection point along line A-B
ABpos = Dx + (Cx - Dx) * Dy / (Dy - Cy);
// Fail if segment C-D crosses line A-B outside of segment A-B
if(ABpos < 0. || ABpos > distAB) return false;
// Apply the discovered position to line A-B in the original coordinate system
// *X = Ax + ABpos * theCos;
// *Y = Ay + ABpos * theSin;
return true;
}