/arm9/source/engine.itcm.c
#include <nds.h>
#include <stdlib.h>
#include <string.h>
#include "engine.h"
DTCM_DATA pixel pixels[NPIXELS];
void pixel_init(pixel *p) {
p->x = rand() % (SCREEN_WIDTH << FRACBITS);
p->y = rand() % (SCREEN_WIDTH << FRACBITS);
p->vx = (rand() % 10 - 5) << FRACBITS;
p->vy = (rand() % 10 - 5) << FRACBITS;
}
void pixel_accel(pixel *p, s16 x, s16 y) {
p->vx += x;
if (p->vx > VELOCITY_THRESHOLD)
p->vx = VELOCITY_THRESHOLD;
else if (p->vx < -VELOCITY_THRESHOLD)
p->vx = -VELOCITY_THRESHOLD;
p->vy += y;
if (p->vy > VELOCITY_THRESHOLD)
p->vy = VELOCITY_THRESHOLD;
else if (p->vy < -VELOCITY_THRESHOLD)
p->vy = -VELOCITY_THRESHOLD;
}
void pixel_update(pixel *p) {
p->x += p->vx;
p->y += p->vy;
}
void pixel_draw(pixel *p) {
if (p->x < 0 || p->x > SCREEN_WIDTH << FRACBITS ||
p->y < 0 || p->y > SCREEN_HEIGHT << FRACBITS)
return;
glVertex3v16((p->x - p->vx) >> FRACBITS, (p->y - p->vy) >> FRACBITS, 0);
glVertex3v16(p->x >> FRACBITS, p->y >> FRACBITS, 0);
glVertex3v16(p->x >> FRACBITS, p->y >> FRACBITS, 0);
}
DTCM_DATA u16 mx = 128;
DTCM_DATA u16 my = 96;
void engine() {
touchPosition touch;
int i;
while(1) {
// Input handling
scanKeys();
if (keysHeld() & KEY_TOUCH) {
touch = touchReadXY();
mx = touch.px;
my = touch.py;
if (keysDown() & KEY_TOUCH) { // just pressed
for (i = 0; i < NPIXELS; i++) {
s32 dx = pixels[i].x - (mx << FRACBITS);
s32 dy = pixels[i].y - (my << FRACBITS);
u16 mag = swiSqrt(dx*dx + dy*dy);
// Shift for the following division,
// and keep the sign!
dx = (dx & BIT(31)) | ((dx << FRACBITS) & ~BIT(31));
dy = (dy & BIT(31)) | ((dy << FRACBITS) & ~BIT(31));
dx = (dx / mag) * 10;
dy = (dy / mag) * 10;
pixel_accel(&pixels[i], dx, dy);
}
}
}
for (i = 0; i < NPIXELS; i++) {
// Get distance
s16 dx = (mx << FRACBITS) - pixels[i].x;
s16 dy = (my << FRACBITS) - pixels[i].y;
// This works because the multiplication shifts
// the decimal place outwards, then the sqrt shifts it
// back inwards. It's bizarre, but it all works out
// somehow.
u16 d = swiSqrt((u32)dx*(u32)dx + (u32)dy*(u32)dy);
// Apply acceleration to pixels towards the cursor
s16 ax = dx / 50;
s16 ay = dy / 50;
// Apply a drag proportional to the distance from the
// cursor
if (d > 25 << FRACBITS) {
ax += -pixels[i].vx * (d - (25 << FRACBITS)) / 5000;
ay += -pixels[i].vy * (d - (25 << FRACBITS)) / 5000;
}
// And a "chaotic" acceleration inversely proportional
// to the distance from the cursor
ax += (rand() % (20 << (FRACBITS*2)) - (10 << (FRACBITS*2))) / d;
ay += (rand() % (20 << (FRACBITS*2)) - (10 << (FRACBITS*2))) / d;
pixel_accel(&pixels[i], ax, ay);
pixel_update(&pixels[i]);
}
glBegin(GL_TRIANGLES);
for (i = 0; i < NPIXELS; i++) {
pixel_draw(&pixels[i]);
}
//glEnd();
glBegin(GL_QUADS);
// Draw rect around the cursor
glVertex3v16(mx - 5, my - 5, 0);
glVertex3v16(mx + 5, my - 5, 0);
glVertex3v16(mx + 5, my + 5, 0);
glVertex3v16(mx - 5, my + 5, 0);
//glEnd();
swiWaitForVBlank();
glFlush(0);
}
}