Objectified cars and smoke.
This commit is contained in:
parent
f7519ad939
commit
60cb1dbbc9
|
@ -32,10 +32,8 @@ typedef s32 FIXED; // 32bit FIXED in 24.8 format
|
||||||
|
|
||||||
#define NUMSMOKES 30
|
#define NUMSMOKES 30
|
||||||
|
|
||||||
u16 PaletteBuffer[256];
|
|
||||||
OBJATTR oe_buffer[2+NUMSMOKES+10];
|
OBJATTR oe_buffer[2+NUMSMOKES+10];
|
||||||
OBJAFFINE *const oa_buffer = (OBJAFFINE*)oe_buffer;
|
OBJAFFINE *const oa_buffer = (OBJAFFINE*)oe_buffer;
|
||||||
s8 smoke_frame[NUMSMOKES];
|
|
||||||
|
|
||||||
unsigned int frame;
|
unsigned int frame;
|
||||||
|
|
||||||
|
@ -45,21 +43,122 @@ void VblankInterrupt()
|
||||||
ScanKeys();
|
ScanKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
class Smoke {
|
||||||
|
OBJATTR* oam;
|
||||||
|
int num_entries;
|
||||||
|
public:
|
||||||
|
s8* smoke_frame;
|
||||||
|
u8 next_smoke;
|
||||||
|
Smoke(int num_entries, OBJATTR* start) {
|
||||||
|
oam = start;
|
||||||
|
smoke_frame = new s8[num_entries];
|
||||||
|
next_smoke = 0;
|
||||||
|
this->num_entries = num_entries;
|
||||||
|
for (u16 i=0; i<num_entries; i++) {
|
||||||
|
oam[i].attr1 = OBJ_X(20+(i*10));
|
||||||
|
oam[i].attr0 = OBJ_256_COLOR | OBJ_Y(40);
|
||||||
|
// 6 == off
|
||||||
|
smoke_frame[i] = 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void increase_frame_counts() {
|
||||||
|
for (u8 i=0; i<num_entries; i++) {
|
||||||
|
if (smoke_frame[i] < 6) {
|
||||||
|
smoke_frame[i] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_at(int x, int y) {
|
||||||
|
smoke_frame[next_smoke] = 0;
|
||||||
|
oam[next_smoke].attr1 = OBJ_X(x);
|
||||||
|
oam[next_smoke].attr0 = OBJ_256_COLOR | OBJ_Y(y);
|
||||||
|
next_smoke += 1;
|
||||||
|
if (next_smoke>=num_entries) {
|
||||||
|
next_smoke = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_sprites() {
|
||||||
|
for (u8 i=0; i<num_entries; i++)
|
||||||
|
oam[i].attr2 = OBJ_CHAR(528 + 2*smoke_frame[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Smoke() {
|
||||||
|
delete smoke_frame;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Car {
|
||||||
|
OBJAFFINE* aff_matrix;
|
||||||
|
OBJATTR* oam;
|
||||||
|
int index;
|
||||||
|
public:
|
||||||
|
Car(int x, int y, OBJAFFINE* aff, OBJATTR* entry, int aff_index,
|
||||||
|
int sprite_index) {
|
||||||
|
this->x = INT2FIX(x);
|
||||||
|
this->y = INT2FIX(y);
|
||||||
|
speed = 0;
|
||||||
|
angle = 0;
|
||||||
|
aff_matrix = aff;
|
||||||
|
oam = entry;
|
||||||
|
index = aff_index;
|
||||||
|
oam->attr2 = OBJ_CHAR(sprite_index);
|
||||||
|
}
|
||||||
|
void rotate(int alpha) {
|
||||||
|
angle += alpha;
|
||||||
|
if (angle < 0) {
|
||||||
|
angle += 512;
|
||||||
|
} else if (angle >= 512) {
|
||||||
|
angle -= 512;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void speedup() {
|
||||||
|
if (speed<30) {
|
||||||
|
speed += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void slowdown() {
|
||||||
|
if (speed>0) {
|
||||||
|
speed -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_position() {
|
||||||
|
x -= (speed >> 3)*lut_sin(angle);
|
||||||
|
y -= (speed >> 3)*lut_cos(angle);
|
||||||
|
|
||||||
|
if (x>=INT2FIX(232)) {
|
||||||
|
x -= INT2FIX(256);
|
||||||
|
} else if (x<INT2FIX(-24)) {
|
||||||
|
x += INT2FIX(256);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y>=INT2FIX(152)) {
|
||||||
|
y -= INT2FIX(176);
|
||||||
|
} else if (y<INT2FIX(-24)) {
|
||||||
|
y += INT2FIX(176);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_matrix() {
|
||||||
|
aff_matrix->pa = lut_cos(angle);
|
||||||
|
aff_matrix->pb = -lut_sin(angle);
|
||||||
|
aff_matrix->pc = lut_sin(angle);
|
||||||
|
aff_matrix->pd = lut_cos(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_oam() {
|
||||||
|
oam->attr1 = OBJ_SIZE(1) | OBJ_ROT_SCALE(index) | OBJ_X(FIX2INT(x));
|
||||||
|
oam->attr0 = OBJ_256_COLOR | OBJ_DOUBLE | OBJ_ROT_SCALE_ON | OBJ_Y(FIX2INT(y));
|
||||||
|
}
|
||||||
|
|
||||||
FIXED x, y;
|
FIXED x, y;
|
||||||
int speed, angle;
|
int speed, angle;
|
||||||
} Car;
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
OBJATTR*red_car = &oe_buffer[0];
|
|
||||||
OBJATTR*blue_car = &oe_buffer[1];
|
|
||||||
OBJAFFINE*red_car_aff = &oa_buffer[0];
|
|
||||||
OBJAFFINE*blue_car_aff = &oa_buffer[1];
|
|
||||||
// We'll make a few smoke clouds
|
|
||||||
OBJATTR*smokes = &oe_buffer[2];
|
|
||||||
|
|
||||||
// Set up the interrupt handlers
|
// Set up the interrupt handlers
|
||||||
InitInterrupt();
|
InitInterrupt();
|
||||||
|
|
||||||
|
@ -90,177 +189,59 @@ int main(void)
|
||||||
CpuFastSet(smoke_bin, (void*)free_space, COPY32 | smoke_bin_size/4);
|
CpuFastSet(smoke_bin, (void*)free_space, COPY32 | smoke_bin_size/4);
|
||||||
free_space += smoke_bin_size;
|
free_space += smoke_bin_size;
|
||||||
|
|
||||||
red_car->attr2 = OBJ_CHAR(512);
|
Car red(102, 72, &oa_buffer[0], &oe_buffer[0], 0, 512);
|
||||||
blue_car->attr2 = OBJ_CHAR(520);
|
Car blue(122, 72, &oa_buffer[1], &oe_buffer[1], 1, 520);
|
||||||
|
Smoke smoke(NUMSMOKES, &oe_buffer[2]);
|
||||||
u8 next_smoke = 0;
|
|
||||||
|
|
||||||
u8 i;
|
|
||||||
for (i=0; i<NUMSMOKES; i++) {
|
|
||||||
smokes[i].attr1 = OBJ_X(20+(i*10));
|
|
||||||
smokes[i].attr0 = OBJ_256_COLOR | OBJ_Y(40);
|
|
||||||
// 6 == off
|
|
||||||
smoke_frame[i] = 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
Car red, blue;
|
|
||||||
|
|
||||||
red.x = INT2FIX(102);
|
|
||||||
red.y = INT2FIX(72);
|
|
||||||
blue.x = INT2FIX(122);
|
|
||||||
blue.y = INT2FIX(72);
|
|
||||||
red.speed = 0;
|
|
||||||
red.angle = 0;
|
|
||||||
blue.speed = 0;
|
|
||||||
blue.angle = 0;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (KeysHeld() & KEY_RIGHT) {
|
if (KeysHeld() & KEY_RIGHT) {
|
||||||
red.angle -= 8;
|
red.rotate(-8);
|
||||||
} else if (KeysHeld() & KEY_LEFT) {
|
} else if (KeysHeld() & KEY_LEFT) {
|
||||||
red.angle += 8;
|
red.rotate(8);
|
||||||
}
|
}
|
||||||
if (red.angle < 0) {
|
|
||||||
red.angle += 512;
|
|
||||||
} else if (red.angle >= 512) {
|
|
||||||
red.angle -= 512;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (KeysHeld() & KEY_A) {
|
if (KeysHeld() & KEY_A) {
|
||||||
blue.angle -= 8;
|
blue.rotate(-8);
|
||||||
} else if (KeysHeld() & KEY_B) {
|
} else if (KeysHeld() & KEY_B) {
|
||||||
blue.angle += 8;
|
blue.rotate(8);
|
||||||
}
|
|
||||||
if (blue.angle < 0) {
|
|
||||||
blue.angle += 512;
|
|
||||||
} else if (blue.angle >= 512) {
|
|
||||||
blue.angle -= 512;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeysHeld() & KEY_L) {
|
if (KeysHeld() & KEY_L) {
|
||||||
if ((red.speed<30) && (red.speed>=0)) {
|
red.speedup();
|
||||||
// slow speedup
|
|
||||||
red.speed += 1;
|
|
||||||
} else if (red.speed<0) {
|
|
||||||
// break if we're going backward
|
|
||||||
red.speed += 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeysHeld() & KEY_R) {
|
if (KeysHeld() & KEY_R) {
|
||||||
if ((blue.speed<30) && (blue.speed>=0)) {
|
blue.speedup();
|
||||||
// slow speedup
|
|
||||||
blue.speed += 1;
|
|
||||||
} else if (blue.speed<0) {
|
|
||||||
// break if we're going backward
|
|
||||||
blue.speed += 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Disabled */
|
|
||||||
/* if (KeysHeld() & KEY_B) { */
|
|
||||||
/* if ((red.speed>=-5) && (red.speed<=0)) { */
|
|
||||||
/* // slow speedup */
|
|
||||||
/* red.speed -= 1; */
|
|
||||||
/* } else if (red.speed>0) { */
|
|
||||||
/* // break if we're going forward */
|
|
||||||
/* red.speed -= 2; */
|
|
||||||
/* } */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
// slow down if we're not doing anything
|
|
||||||
if (!(KeysHeld() & KEY_L)) {
|
if (!(KeysHeld() & KEY_L)) {
|
||||||
if (red.speed>0) {
|
red.slowdown();
|
||||||
red.speed -= 1;
|
|
||||||
} else if (red.speed<0) {
|
|
||||||
red.speed += 1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!(KeysHeld() & KEY_R)) {
|
if (!(KeysHeld() & KEY_R)) {
|
||||||
if (blue.speed>0) {
|
blue.slowdown();
|
||||||
blue.speed -= 1;
|
|
||||||
} else if (blue.speed<0) {
|
|
||||||
blue.speed += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
red.x -= (red.speed >> 3)*lut_sin(red.angle);
|
red.update_position();
|
||||||
red.y -= (red.speed >> 3)*lut_cos(red.angle);
|
red.update_matrix();
|
||||||
|
red.update_oam();
|
||||||
|
|
||||||
if (red.x>=INT2FIX(232)) {
|
blue.update_position();
|
||||||
red.x -= INT2FIX(256);
|
blue.update_matrix();
|
||||||
} else if (red.x<INT2FIX(-24)) {
|
blue.update_oam();
|
||||||
red.x += INT2FIX(256);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (red.y>=INT2FIX(152)) {
|
|
||||||
red.y -= INT2FIX(176);
|
|
||||||
} else if (red.y<INT2FIX(-24)) {
|
|
||||||
red.y += INT2FIX(176);
|
|
||||||
}
|
|
||||||
|
|
||||||
red_car_aff->pa = lut_cos(red.angle);
|
|
||||||
red_car_aff->pb = -lut_sin(red.angle);
|
|
||||||
red_car_aff->pc = lut_sin(red.angle);
|
|
||||||
red_car_aff->pd = lut_cos(red.angle);
|
|
||||||
|
|
||||||
red_car->attr1 = OBJ_SIZE(1) | OBJ_X(FIX2INT(red.x));
|
|
||||||
red_car->attr0 = OBJ_256_COLOR | OBJ_DOUBLE | OBJ_ROT_SCALE_ON | OBJ_Y(FIX2INT(red.y));
|
|
||||||
|
|
||||||
blue.x -= (blue.speed >> 3)*lut_sin(blue.angle);
|
|
||||||
blue.y -= (blue.speed >> 3)*lut_cos(blue.angle);
|
|
||||||
|
|
||||||
if (blue.x>=INT2FIX(232)) {
|
|
||||||
blue.x -= INT2FIX(256);
|
|
||||||
} else if (blue.x<INT2FIX(-24)) {
|
|
||||||
blue.x += INT2FIX(256);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blue.y>=INT2FIX(152)) {
|
|
||||||
blue.y -= INT2FIX(176);
|
|
||||||
} else if (blue.y<INT2FIX(-24)) {
|
|
||||||
blue.y += INT2FIX(176);
|
|
||||||
}
|
|
||||||
|
|
||||||
blue_car_aff->pa = lut_cos(blue.angle);
|
|
||||||
blue_car_aff->pb = -lut_sin(blue.angle);
|
|
||||||
blue_car_aff->pc = lut_sin(blue.angle);
|
|
||||||
blue_car_aff->pd = lut_cos(blue.angle);
|
|
||||||
|
|
||||||
blue_car->attr1 = OBJ_SIZE(1) | OBJ_ROT_SCALE(1) | OBJ_X(FIX2INT(blue.x));
|
|
||||||
blue_car->attr0 = OBJ_256_COLOR | OBJ_DOUBLE | OBJ_ROT_SCALE_ON | OBJ_Y(FIX2INT(blue.y));
|
|
||||||
|
|
||||||
// Update smoke cloud frames
|
|
||||||
if ((frame & 3) == 3) {
|
if ((frame & 3) == 3) {
|
||||||
for (i=0; i<NUMSMOKES; i++) {
|
smoke.increase_frame_counts();
|
||||||
if (smoke_frame[i] < 6) {
|
|
||||||
smoke_frame[i] += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// place a new smoke cloud after car if driving
|
// place a new smoke cloud after car if driving
|
||||||
// forwards
|
// forwards
|
||||||
if ((red.speed!=0) && ((frame & 1) == 1)) {
|
if ((red.speed!=0) && ((frame & 1) == 1)) {
|
||||||
smoke_frame[next_smoke] = 0;
|
smoke.dump_at(FIX2INT(red.x)+12, FIX2INT(red.y)+12);
|
||||||
smokes[next_smoke].attr1 = OBJ_X(FIX2INT(red.x)+12);
|
|
||||||
smokes[next_smoke].attr0 = OBJ_256_COLOR | OBJ_Y(FIX2INT(red.y)+12);
|
|
||||||
}
|
}
|
||||||
next_smoke += 1;
|
|
||||||
if ((blue.speed!=0) && ((frame & 1) == 1)) {
|
if ((blue.speed!=0) && ((frame & 1) == 1)) {
|
||||||
smoke_frame[next_smoke] = 0;
|
smoke.dump_at(FIX2INT(blue.x)+12, FIX2INT(blue.y)+12);
|
||||||
smokes[next_smoke].attr1 = OBJ_X(FIX2INT(blue.x)+12);
|
|
||||||
smokes[next_smoke].attr0 = OBJ_256_COLOR | OBJ_Y(FIX2INT(blue.y)+12);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next_smoke += 1;
|
smoke.update_sprites();
|
||||||
if (next_smoke>=NUMSMOKES) {
|
|
||||||
next_smoke = 0;
|
|
||||||
}
|
|
||||||
for (i=0; i<NUMSMOKES; i++)
|
|
||||||
smokes[i].attr2 = OBJ_CHAR(528 + 2*smoke_frame[i]);
|
|
||||||
|
|
||||||
VBlankIntrWait();
|
VBlankIntrWait();
|
||||||
CpuFastSet(oe_buffer, OAM, COPY32 | sizeof(oe_buffer)/4);
|
CpuFastSet(oe_buffer, OAM, COPY32 | sizeof(oe_buffer)/4);
|
||||||
|
|
Reference in New Issue