diff --git a/source/main.c b/source/main.c index 76472d9..c561d8b 100644 --- a/source/main.c +++ b/source/main.c @@ -67,13 +67,6 @@ flipBuffers() } } -void -putPx(uint16_t x, uint16_t y, uint8_t c) -{ - uint16_t pos = (GBA_SCREEN_W * y + x); - buffer[pos] = c; -} - /////////////////////////////////////////////////////////// #include @@ -82,8 +75,6 @@ putPx(uint16_t x, uint16_t y, uint8_t c) #include #include -#define VWIDTH 25 -#define VHEIGHT 25 #define CUBE_WIDTH 10 #define CUBE_WIDTH_FP ((1 << FP) * CUBE_WIDTH) @@ -103,21 +94,16 @@ enum faces { #define ACTION_STEP 0.1 #define ACTION_STEP_FP ((1 << FP) * ACTION_STEP) -#define SCALE 3 // how much is our initial render scaled +#define SCALE 5 // how much is our initial render scaled -volatile FIXED_POINT K1 = 20; -volatile FIXED_POINT K2 = (2 * CUBE_WIDTH) + 10; +#define K1 (20) +#define K2 (2 * CUBE_WIDTH + 10) -#define MULT_FP(a,b) ((a * b) >> FP) +#define MULT_FP(a, b) ((a * b) >> FP) #define SQ(n) (n * n) #define SQ_FP(n) (MULT_FP(n, n)) -#define PLOT_COORD(x, y, c) \ - for (uint8_t i = 0 ; i < SCALE ; ++i) \ - for (uint8_t j = 0 ; j < SCALE ; ++j) \ - putPx(x * SCALE + i, j + (SCALE * y), chooseColor(c)); - #define GET_ROTATE_X_Q(a) ({ float _a = (a) ; \ struct Quaternions q = {}; q.w = FLOAT2FIXED(cos(_a * .5)); \ q.x = FLOAT2FIXED(sin(_a * .5)); q; }) @@ -149,6 +135,25 @@ init_colors() PALETTE[lastPaletteIndex] = color_order[lastPaletteIndex]; } +uint8_t +chooseColor(uint8_t c) +{ + if (c >= 0 && c < NUM_FACES) + return c + 1; // palette 0 is bg + else + return 0; +} + +void +putPx(uint16_t x, uint16_t y, uint8_t c) +{ + for (uint8_t i = 0 ; i < SCALE ; ++i) + for (uint8_t j = 0 ; j < SCALE ; ++j) { + uint16_t pos = GBA_SCREEN_W * (y * SCALE + j) + x * SCALE + i; + buffer[pos] = chooseColor(c); + } +} + struct { uint8_t x; uint8_t y; @@ -177,7 +182,7 @@ normalize(struct Quaternions *q) { float n = sqrt(FIXED2FLOAT(SQ_FP(q->w) + SQ_FP(q->x) + SQ_FP(q->y) + SQ_FP(q->z))); - if (n == 0 || n == 1) + if (n == 0.|| n == 1.) return; q->w = FLOAT2FIXED(FIXED2FLOAT(q->w) / n); @@ -192,17 +197,18 @@ mult(struct Quaternions *q, FIXED_POINT x, FIXED_POINT y, FIXED_POINT z) //p = q * p * qbar struct Quaternions res; + // << 1 <=> * 2 res.w = 0; res.x = MULT_FP(x, (SQ_FP(q->w) + SQ_FP(q->x) - SQ_FP(q->y) - SQ_FP(q->z))) - + (MULT_FP(y, (MULT_FP(q->x, q->y) - MULT_FP(q->w, q->z))) * 2) - + (MULT_FP(z, (MULT_FP(q->x, q->z) + MULT_FP(q->w, q->y))) * 2); + + (MULT_FP(y, (MULT_FP(q->x, q->y) - MULT_FP(q->w, q->z))) << 1) + + (MULT_FP(z, (MULT_FP(q->x, q->z) + MULT_FP(q->w, q->y))) << 1); - res.y = (MULT_FP(x, (MULT_FP(q->x, q->y) + MULT_FP(q->w,q->z))) * 2) + res.y = (MULT_FP(x, (MULT_FP(q->x, q->y) + MULT_FP(q->w,q->z))) << 1) + (MULT_FP(y, (SQ_FP(q->w) - SQ_FP(q->x) + SQ_FP(q->y) - SQ_FP(q->z)))) - + (MULT_FP(z, (MULT_FP(q->y, q->z) - MULT_FP(q->w, q->x))) << 2); + + (MULT_FP(z, (MULT_FP(q->y, q->z) - MULT_FP(q->w, q->x))) << 1); - res.z = (MULT_FP(x, (MULT_FP(q->x, q->z) - MULT_FP(q->w, q->y)))* 2) - + (MULT_FP(y, (MULT_FP(q->y, q->z) + MULT_FP(q->w, q->x))) * 2) + res.z = (MULT_FP(x, (MULT_FP(q->x, q->z) - MULT_FP(q->w, q->y))) << 1) + + (MULT_FP(y, (MULT_FP(q->y, q->z) + MULT_FP(q->w, q->x))) << 1) + MULT_FP(z, (SQ_FP(q->w) - SQ_FP(q->x) - SQ_FP(q->y) + SQ_FP(q->z))); return res; @@ -239,52 +245,17 @@ multQ(struct Quaternions *p, struct Quaternions *q) } -uint16_t -chooseColor(uint8_t c) -{ - if (c >= 0 && c < NUM_FACES) - return c + 1; // palette 0 is bg - else - return 0; -} - uint8_t chooseMainFace() { - int total = 0; - int faces[NUM_FACES] = {0}; - - for (int k = 0; k < VWIDTH * VHEIGHT; ++k) - if (vertices[k] >= 0 && vertices[k] < NUM_FACES) { - faces[vertices[k]]++; - ++total; - } - - int max = 0, idx = 0; - for (int k = 0; k < NUM_FACES; ++k) - if (faces[k] > max) { - max = faces[k]; - idx = k; - } - - frontFacingFace = max > total * 0.9 ? idx : -1; - return frontFacingFace; + // TODO + return 0; } -// ISSUE the 4 vertices rendered do not make a convex quad -// we have to switch 2 vertices for that -#pragma GCC uint8_t isInQuad(const uint16_t x, const uint16_t y, uint8_t current_face) { uint16_t *points = (uint16_t *)&vertices[current_face * 8]; - // little hack - - uint16_t tmpX = points[6], tmpY = points[7]; - points[6] = points[4]; - points[7] = points[5]; - points[4] = tmpX; - points[5] = tmpY; uint8_t pos = 0, neg = 0; int32_t d; @@ -294,15 +265,14 @@ isInQuad(const uint16_t x, const uint16_t y, uint8_t current_face) return 1; //Form a segment between the i'th point - int32_t x1 = points[2 * i]; - int32_t y1 = points[2 * i + 1]; + uint16_t x1 = points[2 * i]; + uint16_t y1 = points[2 * i + 1]; //And the i+1'th, or if i is the last, with the first point uint8_t i2 = (i + 1) % 4; - int32_t x2 = points[2 * i2]; - int32_t y2 = points[2 * i2 + 1]; - + uint16_t x2 = points[2 * i2]; + uint16_t y2 = points[2 * i2 + 1]; //Compute the cross product d = (x - x1) * (y2 - y1) - (y - y1) * (x2 - x1); @@ -318,9 +288,27 @@ isInQuad(const uint16_t x, const uint16_t y, uint8_t current_face) return 1; } +// the 4 vertices rendered do not make a convex quad +// we have to switch 2 vertices for that +// only works because we render 4 points left to right +void +makeConvex(uint16_t *points) +{ + // little hack + + uint16_t tmpX = points[6], tmpY = points[7]; + points[6] = points[4]; + points[7] = points[5]; + points[4] = tmpX; + points[5] = tmpY; + +} + void fillQuads(uint8_t current_face) { + makeConvex((uint16_t *)&vertices[current_face * 8]); + uint16_t top = UINT16_MAX, bot = 0, left = UINT16_MAX, right = 0; for (uint8_t k = 0 ; k < 8 ; ++k) { const uint16_t item = vertices[current_face * 8 + k]; @@ -338,10 +326,10 @@ fillQuads(uint8_t current_face) } } - for (uint16_t y = top ; y <= bot ; ++y) { + for (uint16_t y = top ; y <= bot; ++y) { for (uint16_t x = left ; x <= right ; ++x) { if (isInQuad(x, y, current_face)) - PLOT_COORD(x, y, current_face); + putPx(x, y, current_face); } } } @@ -517,7 +505,7 @@ uint8_t getInput() { // TODO - uint8_t c = 'd'; + uint8_t c = 's'; handleAngle(c); return c; } @@ -533,7 +521,7 @@ main() memset(MEM_VRAM_MODE4, 0, GBA_SCREEN_H * GBA_SCREEN_W); memset((uint16_t *)vertices, UINT16_MAX, sizeof(uint16_t) * NUM_FACES * 4 * 2); //zBuff is not correct data struct, need a map or smth - memset((uint16_t *)zBuffer, 0, NUM_FACES * 2 * sizeof(FIXED_POINT)); + memset((FIXED_POINT *)zBuffer, 0, NUM_FACES * 2 * sizeof(FIXED_POINT)); for (FIXED_POINT cubeX = -CUBE_WIDTH_FP + 1 * (1 << FP); cubeX <= CUBE_WIDTH_FP - 1 * (1 << FP); cubeX += STEP_FP - 2 * (1 << FP)) {