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:
#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?
Workaround to allow screenshots: http://www.cemetech.net/forum/viewtopic.php?t=8825

That should work Smile

How large is the file?


EDIT:
woops, for some reason i thought this was lua.

I think you need to use blocking getkey somewhere in the program, which will pause it and give screenreceiver a capture of the screen. Smile
flyingfisch wrote:
Workaround to allow screenshots: http://www.cemetech.net/forum/viewtopic.php?t=8825

That should work Smile

How large is the file?


This isn't LuaZM. It's in C. Razz

flyingfisch wrote:

EDIT:
woops, for some reason i thought this was lua.

I think you need to use blocking getkey somewhere in the program, which will pause it and give screenreceiver a capture of the screen. Smile


Blocking Getkey? How would I do that?
Spenceboy98 wrote:

Blocking Getkey? How would I do that?

http://prizm.cemetech.net/index.php/GetKey
flyingfisch wrote:
Spenceboy98 wrote:

Blocking Getkey? How would I do that?

http://prizm.cemetech.net/index.php/GetKey


So, what exactly do I put where it says "int *key"? Do I put a KEY_PRGM_ or something else?
Yes, I *think* KEY_PRGM vals work... but its been a while since i have written C code for the PRIZM...

EDIT:

also, you should probably make it only executed when a certain key is pressed... because it will stop the program until a key is pressed
flyingfisch wrote:
Yes, I *think* KEY_PRGM vals work... but its been a while since i have written C code for the PRIZM...

EDIT:

also, you should probably make it only executed when a certain key is pressed... because it will stop the program until a key is pressed


Yeah. I did. It doesn't work for getting a screenshot because all it displays is a white screen. Any other ideas?
Spenceboy98 wrote:
flyingfisch wrote:
Yes, I *think* KEY_PRGM vals work... but its been a while since i have written C code for the PRIZM...

EDIT:

also, you should probably make it only executed when a certain key is pressed... because it will stop the program until a key is pressed


Yeah. I did. It doesn't work for getting a screenshot because all it displays is a white screen. Any other ideas?


Hmm... i don't have any, but I'm not very well-versed in C either...

Hope someone can help you with this! Smile
Woohoo! I did it! I had to put the Getkey after the render code and also add the Bdisp_EnableColor(1);. Here they are:



I'm gonna add them to the file in the archive.
*BUMP*

Can someone see how to do more colors than just blue? I've been trying to figure it out all day.
From a cursory glance it looks like the color is selected from the tilemap. Try altering the code where you fill the tilemap (tilemap[i] = random() % 20 ...).
souvik1997 wrote:
From a cursory glance it looks like the color is selected from the tilemap. Try altering the code where you fill the tilemap (tilemap[i] = random() % 20 ...).


I just tried it and it doesn't really change the color. Any other suggestions?
*BUMP*

I can't figure out how to do color, but if I wanted to do a racing game, would I just place a sprite in front and make it so it continually goes forward?
That would work considering that the map would turn around the sprite, but wouldn't change to map color any. I'll look into seeing about changing color values (I'm not very good with code though) Do I smell an f-zero style plan here?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement