- [PRIZM] Mode 7 Port
- 26 Feb 2013 06:32:35 pm
- Last edited by Spenceboy98 on 26 Feb 2013 08:49:55 pm; edited 2 times in total
This is a port of a Mode 7 engine by t0xic_kitt3n on Omnimaga.
The original:
http://ourl.ca/18123/336651
Download: http://www.cemetech.net/programs/index.php?mode=file&id=861
It works quite well.
Controls:
[8] = Forward
[5] = Backward
[4] = Left
[6] = Right
[7] = Rotate Left
[9] = Rotate Right
Source:
Code:
Also, do any of you know how to make it so that I can take a screenshot?
The original:
http://ourl.ca/18123/336651
Download: http://www.cemetech.net/programs/index.php?mode=file&id=861
It works quite well.
Controls:
[8] = Forward
[5] = Backward
[4] = Left
[6] = Right
[7] = Rotate Left
[9] = Rotate Right
Source:
Code:
#include "keyboard.hpp"
#include "keyboard_syscalls.h"
#include "display.h"
#include "color.h"
#include "stdlib.h"
#include "math.c"
#define MAP_SIZE_X 64
#define MAP_SIZE_Y 64
#define TEX_SIZE 16
unsigned int random(void);
unsigned int srandom(int seed);
static unsigned int lastrandom=0x12345678;
unsigned int random(void) {
return srandom(0);
}
unsigned int srandom(int seed){
if (seed) lastrandom=seed;
lastrandom = ( 0x41C64E6D*lastrandom ) + 0x3039;
return ( lastrandom >> 16 );
}
int PRGM_GetKey(){
unsigned char buffer[12];
PRGM_GetKey_OS( buffer );
return ( buffer[1] & 0x0F ) * 10 + ( ( buffer[2] & 0xF0 ) >> 4 );
}
void fill_scr(color_t color) {
unsigned int temp_color = (unsigned int)(color<<16) | color;
for(int i = 0; i < LCD_WIDTH_PX*LCD_HEIGHT_PX/2; i++) {
*((int*)0xA8000000+i) = temp_color;
}
}
void plot(int x0, int y0, int color) {
char* VRAM = (char*)0xA8000000;
VRAM += 2*(y0*LCD_WIDTH_PX + x0);
*(VRAM++) = (color&0x0000FF00)>>8;
*(VRAM++) = (color&0x000000FF);
return;
}
void mode7BuildLut(vec2_t* lutPtr, int screenHeight, int screenWidth, float planeH, float planeV, float height) {
int screenRow;
for (screenRow = 0; screenRow < screenHeight; screenRow++) {
float cameraV = (((float)screenRow / (float)screenHeight) * 2.0 - 1.0);
float rayX = planeH;
float rayY = 1.0;
float rayZ = planeV * cameraV;
float intersectY = (height / rayZ) * rayY;
float intersectX = -(height / rayZ) * rayX;
lutPtr[screenRow].x = (signed long int)(intersectX * 65536);
lutPtr[screenRow].y = (signed long int)(intersectY * 65536);
}
}
void mode7Render(vec2_t* lutPtr, int screenHeight, int screenWidth, char* tilemap, int mapSizeX, int mapSizeY, char** texIdx, int texSize, vec2_t pos, signed long int heading) {
int screenX, screenY;
for (screenY = screenHeight / 2; screenY < screenHeight; screenY++) {
vec2_t map = lutPtr[screenY];
vec2_t mapXStep = {-map.x / (screenWidth / 2), 0};
signed long int sinHeading = sin1(heading);
signed long int cosHeading = cos1(heading);
map = rotateVec2(map, sinHeading, cosHeading);
mapXStep = rotateVec2(mapXStep, sinHeading, cosHeading);
map.x += pos.x;
map.y += pos.y;
for (screenX = 0; screenX < 384; screenX++) {
int color = 0;
//map.x = map.x && numToFix(mapSizeX) - 1;
//map.y = map.y && numToFix(mapSizeY) - 1;
if (map.x >= 0 && map.x < numToFix(mapSizeX) && map.y >= 0 && map.y < numToFix(mapSizeY)) {
//if (map.x == map.x & (numToFix(MAP_SIZE_X) - 1) && map.y == map.y & (numToFix(MAP_SIZE_Y) - 1)) {
signed long int mapIdx = (map.y >> 16) * 64 + (map.x >> 16);
color = tilemap[mapIdx];
if (color > 0xF) {
color = texIdx[color - 16][((map.y & 0xFFFF) >> 12) * texSize + ((map.x & 0xFFFF) >> 12)];
}
}
//if (map.x >= 0 && map.x < numToFix(MAP_SIZE_X) && map.y >= 0 && map.y < numToFix(MAP_SIZE_Y)) color >>= 2;
map.x += mapXStep.x;
map.y += mapXStep.y;
plot(screenX, screenY, color);
}
}
}
int main() {
signed long int i, j, k; //for loop counters
//nio_console csl;
//lcd_ingray();
//clrscr();
//53 columns, 29 rows. 0px offset for x/y.
//Background color 0 (black), foreground color 15 (white)
//nio_InitConsole(&csl, 53, 29, 0, 0, 0, 15);
fill_scr(0x0000);
char* tilemap = (char*) malloc(MAP_SIZE_X * MAP_SIZE_Y);
srandom(42);
for (i = 0; i < MAP_SIZE_X * MAP_SIZE_Y; i++) tilemap[i] = random() % 20;
char* xorTex = (char*) malloc(16 * 16);
for (i = 0; i < 16; i++) for (j = 0; j < 16; j++) xorTex[j * 16 + i] = i ^ j;
char gradient1Tex[16][16];
for (i = 0; i < 16; i++) for (j = 0; j < 16; j++) gradient1Tex[i][j] = i;
char gradient2Tex[16][16];
for (k = 0; k < 8; k++) {
for (i = k; i < 16 - k; i++) for (j = k; j < 16 - k; j++) gradient2Tex[i][j] = k << 1;
}
char concentricTex[16][16];
for (k = 0; k < 8; k++) {
for (i = k; i < 16 - k; i++) for (j = k; j < 16 - k; j++) concentricTex[i][j] = (k & 1) * 8 + 4;
}
char* textureIdx[4] = {xorTex, gradient1Tex, gradient2Tex, concentricTex};
vec2_t* mode7lut = (vec2_t*) malloc(sizeof(vec2_t) * 216);
float planeH = 1.0;
float planeV = 0.75;
float height = 1;
mode7BuildLut(mode7lut, 216, 384, planeH, planeV, height);
vec2_t pos = {numToFix(4), numToFix(4)};
signed long int heading = 0;
while(1) {
int key = PRGM_GetKey();
if(key == KEY_PRGM_MENU) { GetKey(&key); }
signed long int sinA = sin1(heading);
signed long int cosA = cos1(heading);
vec2_t moveDist = rotateVec2((vec2_t){numToFix(0), floatToFix(0.25)}, sinA, cosA);
if (key == (KEY_PRGM_8)) pos = addVec2(pos, moveDist);
if (key == (KEY_PRGM_5)) pos = subVec2(pos, moveDist);
if (key == (KEY_PRGM_6)) pos = subVec2(pos, rotateVec2(moveDist, numToFix(1), 0));
if (key == (KEY_PRGM_4)) pos = addVec2(pos, rotateVec2(moveDist, numToFix(1), 0));
if (key == (KEY_PRGM_9)) heading += 0x400;
if (key == (KEY_PRGM_7)) heading -= 0x400;
mode7Render(mode7lut, 216, 384,
tilemap, MAP_SIZE_X, MAP_SIZE_Y,
textureIdx, TEX_SIZE,
pos, heading);
Bdisp_PutDisp_DD();
Bdisp_AllCr_VRAM();
}
//nio_CleanUp(&csl);
free(mode7lut);
free(tilemap);
return 0;
}
Also, do any of you know how to make it so that I can take a screenshot?