fix: [WIP] IT "WORKS"
This commit is contained in:
parent
28295eb8d6
commit
f2bb638c0b
1 changed files with 298 additions and 316 deletions
188
source/main.c
188
source/main.c
|
@ -68,17 +68,12 @@ flipBuffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
putPx(uint8_t x, uint8_t y, uint16_t c)
|
putPx(uint16_t x, uint16_t y, uint8_t c)
|
||||||
{
|
{
|
||||||
uint16_t pos = (GBA_SCREEN_W * y + x) >> 1;
|
uint16_t pos = (GBA_SCREEN_W * y + x);
|
||||||
uint8_t px = buffer[pos];
|
buffer[pos] = c;
|
||||||
if (y & 1) {
|
|
||||||
buffer[pos] = c << 8;
|
|
||||||
buffer[pos] = (c << 8) | (px & 0x00ff);
|
|
||||||
} else {
|
|
||||||
buffer[pos] = (px & 0xff00) | c;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -108,7 +103,7 @@ enum faces {
|
||||||
#define ACTION_STEP 0.1
|
#define ACTION_STEP 0.1
|
||||||
#define ACTION_STEP_FP ((1 << FP) * ACTION_STEP)
|
#define ACTION_STEP_FP ((1 << FP) * ACTION_STEP)
|
||||||
|
|
||||||
#define SCALE 10 // how much is our initial render scaled
|
#define SCALE 3 // how much is our initial render scaled
|
||||||
|
|
||||||
volatile FIXED_POINT K1 = 20;
|
volatile FIXED_POINT K1 = 20;
|
||||||
volatile FIXED_POINT K2 = (2 * CUBE_WIDTH) + 10;
|
volatile FIXED_POINT K2 = (2 * CUBE_WIDTH) + 10;
|
||||||
|
@ -118,8 +113,6 @@ volatile FIXED_POINT K2 = (2 * CUBE_WIDTH) + 10;
|
||||||
#define SQ(n) (n * n)
|
#define SQ(n) (n * n)
|
||||||
#define SQ_FP(n) (MULT_FP(n, n))
|
#define SQ_FP(n) (MULT_FP(n, n))
|
||||||
|
|
||||||
#define COORD2INDEX(x, y) (y * VWIDTH + x)
|
|
||||||
#define COUPLE2INDEX(x) (COORD2INDEX(x[0], x[1]))
|
|
||||||
#define PLOT_COORD(x, y, c) \
|
#define PLOT_COORD(x, y, c) \
|
||||||
for (uint8_t i = 0 ; i < SCALE ; ++i) \
|
for (uint8_t i = 0 ; i < SCALE ; ++i) \
|
||||||
for (uint8_t j = 0 ; j < SCALE ; ++j) \
|
for (uint8_t j = 0 ; j < SCALE ; ++j) \
|
||||||
|
@ -152,9 +145,8 @@ init_colors()
|
||||||
RGB15(31, 0, 31),
|
RGB15(31, 0, 31),
|
||||||
};
|
};
|
||||||
|
|
||||||
for ( ; lastPaletteIndex <= NUM_FACES ; ++lastPaletteIndex) {
|
for ( ; lastPaletteIndex <= NUM_FACES ; ++lastPaletteIndex)
|
||||||
PALETTE[lastPaletteIndex] = color_order[lastPaletteIndex];
|
PALETTE[lastPaletteIndex] = color_order[lastPaletteIndex];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -172,9 +164,8 @@ struct Quaternions {
|
||||||
} Target, Current;
|
} Target, Current;
|
||||||
|
|
||||||
static FIXED_POINT interpolationStep = 0;
|
static FIXED_POINT interpolationStep = 0;
|
||||||
static FIXED_POINT zBuffer[VHEIGHT * VWIDTH];
|
static volatile uint16_t vertices[NUM_FACES * 2 * 4];
|
||||||
static FIXED_POINT maxZbufByColor[NUM_FACES * 2];
|
static volatile FIXED_POINT zBuffer[NUM_FACES * 2];
|
||||||
static uint8_t output[VHEIGHT * VWIDTH];
|
|
||||||
|
|
||||||
static volatile uint8_t shouldBreak = 1;
|
static volatile uint8_t shouldBreak = 1;
|
||||||
static volatile uint8_t currentlyMoving = 0;
|
static volatile uint8_t currentlyMoving = 0;
|
||||||
|
@ -251,8 +242,8 @@ multQ(struct Quaternions *p, struct Quaternions *q)
|
||||||
uint16_t
|
uint16_t
|
||||||
chooseColor(uint8_t c)
|
chooseColor(uint8_t c)
|
||||||
{
|
{
|
||||||
if (c >= 1 && c <= NUM_FACES)
|
if (c >= 0 && c < NUM_FACES)
|
||||||
return c;
|
return c + 1; // palette 0 is bg
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -264,8 +255,8 @@ chooseMainFace()
|
||||||
int faces[NUM_FACES] = {0};
|
int faces[NUM_FACES] = {0};
|
||||||
|
|
||||||
for (int k = 0; k < VWIDTH * VHEIGHT; ++k)
|
for (int k = 0; k < VWIDTH * VHEIGHT; ++k)
|
||||||
if (output[k] >= 0 && output[k] < NUM_FACES) {
|
if (vertices[k] >= 0 && vertices[k] < NUM_FACES) {
|
||||||
faces[output[k]]++;
|
faces[vertices[k]]++;
|
||||||
++total;
|
++total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,27 +271,37 @@ chooseMainFace()
|
||||||
return frontFacingFace;
|
return frontFacingFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ISSUE the 4 vertices rendered do not make a convex quad
|
||||||
|
// we have to switch 2 vertices for that
|
||||||
|
#pragma GCC
|
||||||
uint8_t
|
uint8_t
|
||||||
isInQuad(uint8_t curr[2], uint8_t points[8])
|
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;
|
uint8_t pos = 0, neg = 0;
|
||||||
uint8_t x = curr[0];
|
int32_t d;
|
||||||
uint8_t y = curr[1];;
|
|
||||||
int d;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 4; ++i) {
|
for (uint8_t i = 0; i < 4; ++i) {
|
||||||
if (points[2 * i] == curr[0] && points[2 * i + 1] == curr[1])
|
if (points[2 * i] == x && points[2 * i + 1] == y)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
//Form a segment between the i'th point
|
//Form a segment between the i'th point
|
||||||
uint8_t x1 = points[2 * i];
|
int32_t x1 = points[2 * i];
|
||||||
uint8_t y1 = points[2 * i + 1];
|
int32_t y1 = points[2 * i + 1];
|
||||||
|
|
||||||
//And the i+1'th, or if i is the last, with the first point
|
//And the i+1'th, or if i is the last, with the first point
|
||||||
uint8_t i2 = (i + 1) % 4;
|
uint8_t i2 = (i + 1) % 4;
|
||||||
|
|
||||||
uint8_t x2 = points[2 * i2];
|
int32_t x2 = points[2 * i2];
|
||||||
uint8_t y2 = points[2 * i2 + 1];
|
int32_t y2 = points[2 * i2 + 1];
|
||||||
|
|
||||||
|
|
||||||
//Compute the cross product
|
//Compute the cross product
|
||||||
|
@ -318,48 +319,40 @@ isInQuad(uint8_t curr[2], uint8_t points[8])
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fill_quads(uint8_t *points, uint8_t current_face)
|
fillQuads(uint8_t current_face)
|
||||||
{
|
{
|
||||||
uint8_t top = 0, bot = 0, left = 0, right = 0;
|
uint16_t top = UINT16_MAX, bot = 0, left = UINT16_MAX, right = 0;
|
||||||
for (uint8_t x = 0 ; x < 8 ; ++x) {
|
for (uint8_t k = 0 ; k < 8 ; ++k) {
|
||||||
if (x % 2 == 0) {
|
const uint16_t item = vertices[current_face * 8 + k];
|
||||||
if (points[x] > right)
|
|
||||||
right = points[x];
|
if (k & 1) {
|
||||||
if (points[x] < left)
|
if (item > bot)
|
||||||
left = points[x];
|
bot = item;
|
||||||
|
if (item < top)
|
||||||
|
top = item;
|
||||||
} else {
|
} else {
|
||||||
if (points[x] > bot)
|
if (item > right)
|
||||||
bot = points[x];
|
right = item;
|
||||||
if (points[x] < top)
|
if (item < left)
|
||||||
top = points[x];
|
left = item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int y = top ; y < bot ; ++y) {
|
|
||||||
for (int x = left ; x < right ; ++x) {
|
for (uint16_t y = top ; y <= bot ; ++y) {
|
||||||
uint8_t curr[2] = {x, y};
|
for (uint16_t x = left ; x <= right ; ++x) {
|
||||||
if (isInQuad(curr, points))
|
if (isInQuad(x, y, current_face))
|
||||||
PLOT_COORD(x, y, current_face + 1);
|
PLOT_COORD(x, y, current_face);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
detect(uint8_t *points, uint8_t current_face) {
|
detect(uint8_t current_face)
|
||||||
uint8_t i = 0;
|
{
|
||||||
for (uint8_t y = 0; y < VHEIGHT; ++y) {
|
for (uint8_t k = current_face * 8; k < current_face * 8 + 8; ++k)
|
||||||
for (uint8_t x = 0; x < VWIDTH; ++x) {
|
if (vertices[k] == UINT16_MAX)
|
||||||
if (output[COORD2INDEX(x, y)] != current_face)
|
|
||||||
continue;
|
|
||||||
// only 4 points are ploted
|
|
||||||
points[i] = x;
|
|
||||||
points[i + 1] = y;
|
|
||||||
i += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t x = 0 ; x < 8 ; ++x)
|
|
||||||
if (points[x] == 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,31 +365,21 @@ comp(const void *p1, const void *p2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
detect_and_fill_quads()
|
detectAndFillQuads()
|
||||||
{
|
{
|
||||||
qsort(maxZbufByColor, NUM_FACES, 2 * sizeof(FIXED_POINT), comp);
|
qsort((FIXED_POINT *)zBuffer, NUM_FACES, 2 * sizeof(FIXED_POINT), comp);
|
||||||
for (uint8_t idx = 0 ; idx < NUM_FACES ; ++idx) {
|
for (uint8_t idx = 0 ; idx < NUM_FACES ; ++idx) {
|
||||||
uint8_t current_face = maxZbufByColor[2 * idx + 1];
|
char ch = zBuffer[2 * idx + 1];
|
||||||
uint8_t points[8] = { 0 };
|
if (detect(ch))
|
||||||
if (detect(points, current_face))
|
fillQuads(ch);
|
||||||
fill_quads(points, current_face);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
printAscii()
|
printAscii()
|
||||||
{
|
{
|
||||||
detect_and_fill_quads();
|
detectAndFillQuads();
|
||||||
flipBuffers();
|
flipBuffers();
|
||||||
|
|
||||||
// DISPLAY POINTS
|
|
||||||
//for (int i = 0; i < VHEIGHT; ++i) {
|
|
||||||
// for (int j = 0; j < VWIDTH; ++j) {
|
|
||||||
// uint8_t prevc = 0;
|
|
||||||
// uint8_t c = output[i * VWIDTH + j];
|
|
||||||
// MEM_VRAM_MODE4[i * GBA_SCREEN_W + j] = chooseColor(c);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -404,29 +387,30 @@ rotateCube(FIXED_POINT cubeX, FIXED_POINT cubeY, FIXED_POINT cubeZ, uint8_t ch)
|
||||||
{
|
{
|
||||||
struct Quaternions q = mult(&Current, cubeX, cubeY, cubeZ);
|
struct Quaternions q = mult(&Current, cubeX, cubeY, cubeZ);
|
||||||
|
|
||||||
int x = q.x >> FP;
|
uint32_t x = q.x >> FP;
|
||||||
int y = q.y >> FP;
|
uint32_t y = q.y >> FP;
|
||||||
|
|
||||||
// not fixed point yet!!
|
// not fixed point yet!!
|
||||||
float invZ = (1 << FP) / (float)(q.z + K2 * (1 << FP));
|
float invZ = (1 << FP) / (float)(q.z + K2 * (1 << FP));
|
||||||
|
|
||||||
int screenX = (int)(VWIDTH * 0.5) + (int)((x) * K1) * invZ;
|
int32_t screenX = CUBE_WIDTH * 2 + (int32_t)((x) * K1) * invZ;
|
||||||
int screenY = (int)(VHEIGHT * 0.5) + (int)((y) * K1) * invZ;
|
int32_t screenY = CUBE_WIDTH * 2 + (int32_t)((y) * K1) * invZ;
|
||||||
//TODO luminescence
|
//TODO luminescence
|
||||||
|
|
||||||
if (screenX > VWIDTH || screenX < 0) return;
|
if (screenX > GBA_SCREEN_W || screenX < 0
|
||||||
|
|| screenY > GBA_SCREEN_H || screenY < 0) return;
|
||||||
|
|
||||||
int idx = screenY * VWIDTH + screenX;
|
FIXED_POINT invZFixed = FLOAT2FIXED(invZ);
|
||||||
if (idx >= 0 && idx < VWIDTH * VHEIGHT) {
|
uint8_t firstEmptyVertex = ch * 8;
|
||||||
invZ = FLOAT2FIXED(invZ);
|
for ( ; vertices[firstEmptyVertex] != UINT16_MAX
|
||||||
if (zBuffer[idx] < invZ) {
|
&& firstEmptyVertex - ch * 8 < 8 ; firstEmptyVertex+=2);
|
||||||
zBuffer[idx] = invZ;
|
|
||||||
output[idx] = ch;
|
vertices[firstEmptyVertex] = screenX;
|
||||||
if (invZ > maxZbufByColor[ch]) {
|
vertices[firstEmptyVertex + 1] = screenY;
|
||||||
maxZbufByColor[2 * ch] = invZ;
|
|
||||||
maxZbufByColor[2 * ch + 1] = ch; //palette[0] is bg
|
if (zBuffer[2 * ch] < invZFixed) {
|
||||||
}
|
zBuffer[2 * ch] = invZFixed;
|
||||||
}
|
zBuffer[2 * ch + 1] = ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,21 +526,19 @@ int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
REG_DISPCNT = DISPCNT_BG_MODE(4) | DISPCNT_BG2_ENABLE;
|
REG_DISPCNT = DISPCNT_BG_MODE(4) | DISPCNT_BG2_ENABLE;
|
||||||
|
|
||||||
Current = GET_ROTATE_Z_Q(0);
|
Current = GET_ROTATE_Z_Q(0);
|
||||||
|
|
||||||
init_colors();
|
init_colors();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
memset(MEM_VRAM_MODE4, 0, GBA_SCREEN_H * GBA_SCREEN_W);
|
memset(MEM_VRAM_MODE4, 0, GBA_SCREEN_H * GBA_SCREEN_W);
|
||||||
memset(output, NUM_FACES, VWIDTH * VHEIGHT);
|
memset((uint16_t *)vertices, UINT16_MAX, sizeof(uint16_t) * NUM_FACES * 4 * 2);
|
||||||
memset(maxZbufByColor, 0, 2 * sizeof(FIXED_POINT) * NUM_FACES);
|
//zBuff is not correct data struct, need a map or smth
|
||||||
memset(zBuffer, 0xffffffff, VWIDTH * VHEIGHT * sizeof(FIXED_POINT));
|
memset((uint16_t *)zBuffer, 0, NUM_FACES * 2 * sizeof(FIXED_POINT));
|
||||||
|
|
||||||
for (FIXED_POINT cubeX = -CUBE_WIDTH_FP + 2 * (1 << FP);
|
for (FIXED_POINT cubeX = -CUBE_WIDTH_FP + 1 * (1 << FP);
|
||||||
cubeX <= CUBE_WIDTH_FP - 2 * (1 << FP); cubeX += STEP_FP - 4 * (1 << FP)) {
|
cubeX <= CUBE_WIDTH_FP - 1 * (1 << FP); cubeX += STEP_FP - 2 * (1 << FP)) {
|
||||||
for (FIXED_POINT cubeY = -CUBE_WIDTH_FP + 2 * (1 << FP);
|
for (FIXED_POINT cubeY = -CUBE_WIDTH_FP + 1 * (1 << FP);
|
||||||
cubeY <= CUBE_WIDTH_FP - 2 * (1 << FP); cubeY += STEP_FP - 4 * (1 << FP)) {
|
cubeY <= CUBE_WIDTH_FP - 1 * (1 << FP); cubeY += STEP_FP - 2 * (1 << FP)) {
|
||||||
switch (frontFacingFace) {
|
switch (frontFacingFace) {
|
||||||
case FACE_FRONT:
|
case FACE_FRONT:
|
||||||
rotateCube(cubeX, cubeY, -CUBE_WIDTH_FP, FACE_FRONT);
|
rotateCube(cubeX, cubeY, -CUBE_WIDTH_FP, FACE_FRONT);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue