0 Members and 2 Guests are viewing this topic.
#include <os.h>// Useful structurestypedef struct{ int x; int y;} ScreenPoint;// Functions// Miscellaneous defines#define abs(x) (x < 0 ? -x : x)#define map(x, in_min, in_max, out_min, out_max) ((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)#define nRC_248mul(a,b) ((a*b) >> 8)#define nRC_248div(a,b) ((a << 8) / b)// Trigonometry#define nRC_Sin(angle) nRC_Cos(angle + 64)int nRC_Cos(int angle){ // Beware ! All trigonometry is done in base 256 ! int table[256]={128,128,128,128,127,127,127,126,126,125,124,123,122,122,121,119,118,117,116,114,113,111,110,108,106,105,103,101,99,97,95,93,91,248,86,84,81,79,76,74,71,68,66,63,60,58,55,52,49,46,43,40,37,34,31,28,25,22,19,16,13,9,6,3,0,-3,-6,-9,-13,-16,-19,-22,-25,-28,-31,-34,-37,-40,-43,-46,-49,-52,-55,-58,-60,-63,-66,-68,-71,-74,-76,-79,-81,-84,-86,-248,-91,-93,-95,-97,-99,-101,-103,-105,-106,-108,-110,-111,-113,-114,-116,-117,-118,-119,-121,-122,-122,-123,-124,-125,-126,-126,-127,-127,-127,-128,-128,-128,-128,-128,-128,-128,-127,-127,-127,-126,-126,-125,-124,-123,-122,-122,-121,-119,-118,-117,-116,-114,-113,-111,-110,-108,-106,-105,-103,-101,-99,-97,-95,-93,-91,-248,-86,-84,-81,-79,-76,-74,-71,-68,-66,-63,-60,-58,-55,-52,-49,-46,-43,-40,-37,-34,-31,-28,-25,-22,-19,-16,-13,-9,-6,-3,0,3,6,9,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,60,63,66,68,71,74,76,79,81,84,86,248,91,93,95,97,99,101,103,105,106,108,110,111,113,114,116,117,118,119,121,122,122,123,124,125,126,126,127,127,127,128,128,128}; return table[angle & 0xff];}#define nRC_Tan(angle) nRC_248div(nRC_Sin(angle), nRC_Cos(angle))// Drawing functionsvoid nRC_setPixel(ScreenPoint pixel, int color, char* buffer){ int temp; if(pixel.x < 319 && pixel.x > 0 && pixel.y < 239 && pixel.y > 0) { if(is_cx) // color LCD, 16 bpp { buffer[temp = ((pixel.y * 320 + pixel.x) * 2)] = color & 0xff; buffer[temp + 1] = color >> 8 & 0xff; } else // monochrome LCD, 4 bpp { temp = (pixel.y * 160 + pixel.x/2); if(pixel.x & 1) { buffer[temp] = (buffer[temp] & 0xf0) | (color & 0x0f); } else { buffer[temp] = (buffer[temp] & 0x0f) | (color << 4 & 0xf0); } } }}#define nRC_drawHorizontalLine(origin, end, constant, color, buffer) nRC_drawLineShared(origin, end, constant, color, buffer, 0)#define nRC_drawVerticalLine(origin, end, constant, color, buffer) nRC_drawLineShared(origin, end, constant, color, buffer, 1)void nRC_drawLineShared(int origin, int end, int constant, int color, char *buffer, int side){ ScreenPoint pixel; int i,j; if(constant > 0 && constant < (side ? 319 : 239)) { i = min(origin, end); j = max(origin, end); if(!side) { pixel.y = constant; for(pixel.x = i; pixel.x < j; pixel.x++) nRC_setPixel(pixel, color, buffer); } else { pixel.x = constant; for(pixel.y = i; pixel.y < j; pixel.y++) nRC_setPixel(pixel, color, buffer); } }}void nRC_drawLine(ScreenPoint pt1, ScreenPoint pt2, int color, char* buffer){ int dx, dy, inx, iny, e; dx = pt2.x - pt1.x; dy = pt2.y - pt1.y; inx = dx > 0 ? 1 : -1; iny = dy > 0 ? 1 : -1; dx = abs(dx); dy = abs(dy); if(dx >= dy) { dy <<= 1; e = dy - dx; dx <<= 1; while (pt1.x != pt2.x) { nRC_setPixel(pt1, color, buffer); if(e >= 0) { pt1.y += iny; e-= dx; } e += dy; pt1.x += inx; } } else { dx <<= 1; e = dx - dy; dy <<= 1; while (pt1.y != pt2.y) { nRC_setPixel(pt1, color, buffer); if(e >= 0) { pt1.x += inx; e -= dy; } e += dx; pt1.y += iny; } } nRC_setPixel(pt1, color, buffer);}void nRC_fillTriangle(ScreenPoint pt1, ScreenPoint pt2, ScreenPoint pt3, int color, char *buffer){ int dx1, dx2, x1, x2, y, i; ScreenPoint intermediate; // Sort points from lowest to highest Y if(pt1.y > pt2.y) { intermediate = pt1; pt1 = pt2; pt2 = intermediate; } if(pt2.y > pt3.y) { intermediate = pt2; pt2 = pt3; pt3 = intermediate; } if(pt1.y > pt2.y) { intermediate = pt1; pt1 = pt2; pt2 = intermediate; } // dx1 = (x2 - x1) / (y2 - y1) dx1 = ((pt2.x - pt1.x) << 8) / ((pt2.y != pt1.y) ? pt2.y - pt1.y : 1); // dx2 = (x3 - x1) / (y3 - y1) dx2 = ((pt3.x - pt1.x) << 8) / ((pt3.y != pt1.y) ? pt3.y - pt1.y : 1); x1 = x2 = pt1.x << 8; y = pt1.y; // X values are multiplied by 256 to handle a sort of a decimal part to make calculations, and thus slopes, // more accurate. It's called a fixed .8 part, since it's only 8 bits. for(i = 0; i < 2; i++) { do { nRC_drawHorizontalLine(x1 >> 8, x2 >> 8, y, color, buffer); x1 += dx1; x2 += dx2; y++; } while(y < pt2.y); // dx1 = (x3 - x2) / (y3 - y2) dx1 = ((pt3.x - pt2.x) << 8) / ((pt3.y != pt2.y) ? pt3.y - pt2.y : 1); pt2.y = pt3.y; }}inline void nRC_clearBuf(char *buffer){ memset(buffer, 0, SCREEN_BYTES_SIZE);}inline void nRC_dispBuf(char *buffer){ memcpy(SCREEN_BASE_ADDRESS, buffer, SCREEN_BYTES_SIZE);}// Ray castingvoid nRC_rayCasting(int *map, ScreenPoint player, ScreenPoint mapDimensions, int fov, int angle, char *buffer){ int rayX, rayY, dx, dy, d1, d2, currentAngle, distFromProjPlane; int deltaAngle, midFov; int constantTan, flag, i = 0; unsigned char currentUsableAngle; deltaAngle = nRC_248div(fov, 320); midFov = fov / 2; currentAngle = ((angle - midFov) << 8) & 0xffff; distFromProjPlane = 64*277; for(i = 0; i < 320; i++) { currentAngle += deltaAngle; currentAngle &= 0xffff; currentUsableAngle = currentAngle >> 8; constantTan = nRC_Tan(currentUsableAngle); // Calculate distance from closest horizontal edge if(currentUsableAngle & 127) { rayY = (currentUsableAngle < 128 ? ((player.y >> 6) + 1) << 6 : ((player.y >> 6) << 6) - 1); rayX = (unsigned char)(currentUsableAngle + 64) & 127 ? nRC_248div(abs(rayY - player.y), constantTan) + player.x : player.x; dy = currentUsableAngle < 128 ? 64 : -64; dx = (unsigned char)(currentUsableAngle + 64) & 127 ? nRC_248div(64, constantTan) : 0; //printf("rayX = %d ; rayY = %d ; dx = %d ; dy = %d\n", rayX, rayY, dx, dy); //printf("currentUsableAngle = %d\n", currentUsableAngle); if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)]) { d1 = nRC_248div(abs(player.y - rayY), (nRC_Sin(currentUsableAngle) ? nRC_Sin(currentUsableAngle) << 1 : 1)); goto skip1; } flag = 0; while(1) { rayX += dx; rayY += dy; flag = rayX > 64 * mapDimensions.x || rayY > 64 * mapDimensions.y; if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)] || flag) break; } d1 = flag ? 50000000 : nRC_248div(abs(player.y - rayY), (nRC_Sin(currentUsableAngle) ? nRC_Sin(currentUsableAngle) << 1 : 1)); } else d1 = 50000000; skip1: d1 = nRC_248mul(d1, nRC_Cos(angle - currentUsableAngle)); // At this point we have the distance from the closest horizontal edge in d1 // Now calculate distance from the closest vertical edge if((unsigned char)(currentUsableAngle + 64) & 127) { rayX = (unsigned char)(currentUsableAngle - 64) < 128 ? ((player.x >> 6) << 6) - 1 : ((player.x >> 6) + 1) << 6; rayY = nRC_248mul(abs(player.x - rayX), constantTan) + player.y; dx = (unsigned char)(currentUsableAngle - 64) < 128 ? -64 : 64; dy = nRC_248mul(64, constantTan); if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)]) { d2 = nRC_248div(abs(player.x - rayX), (nRC_Cos(currentUsableAngle) ? nRC_Cos(currentUsableAngle) << 1 : 1)); goto skip2; } flag = 0; while(1) { rayX += dx; rayY += dy; flag = rayX > 64 * mapDimensions.x || rayY > 64 * mapDimensions.y; if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)] || flag) break; } d2 = flag ? 50000000 : nRC_248div(abs(player.x - rayX), (nRC_Cos(currentUsableAngle) ? nRC_Cos(currentUsableAngle) << 1 : 1)); } else d2 = 50000000; skip2: d2 = nRC_248mul(d2, nRC_Cos(angle - currentUsableAngle)); // Calculate the height of the current wall slice d1 = distFromProjPlane / min(d1, d2); nRC_drawVerticalLine((240 - d1) >> 1, (240 + d1) >> 1, i, 0xf800, buffer); }}
typedef struct{ int x; int y;} ScreenPoint;#define abs(x) (x < 0 ? -x : x)#define map(x, in_min, in_max, out_min, out_max) ((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)#define nRC_248mul(a,b) ((a*b) >> 8)#define nRC_248div(a,b) ((a << 8) / b)#define nRC_Sin(angle) nRC_Cos(angle + 64)extern int nRC_Cos(unsigned char angle);extern void nRC_rayCasting(int *map, ScreenPoint player, ScreenPoint mapDimensions, int fov, int angle, char *buffer);#define nRC_drawHorizontalLine(origin, end, constant, color, buffer) nRC_drawLineShared(origin, end, constant, color, buffer, 0)#define nRC_drawVerticalLine(origin, end, constant, color, buffer) nRC_drawLineShared(origin, end, constant, color, buffer, 1)void nRC_drawLineShared(int origin, int end, int constant, int color, char *buffer, int side);extern void nRC_setPixel(ScreenPoint pixel, int color, char* buffer);extern void nRC_drawLine(ScreenPoint pt1, ScreenPoint pt2, int color, char *buffer);extern void nRC_fillTriangle(ScreenPoint pt1, ScreenPoint pt2, ScreenPoint pt3, int color, char *buffer);extern inline void nRC_clearBuf(char *buffer);extern inline void nRC_dispBuf(char *buffer);
#include <os.h>#include "nRayC.h"int main(void){ int map[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; ScreenPoint player = { 448, 448 }, mapDim = { 16, 16 }; unsigned char angle, *buffer; buffer = malloc(SCREEN_BYTES_SIZE); if(!buffer) exit(0); nRC_clearBuf(buffer); angle = 64; while(!isKeyPressed(KEY_NSPIRE_ESC)) { nRC_rayCasting(map, player, mapDim, 60, angle, buffer); nRC_dispBuf(buffer); nRC_clearBuf(buffer); angle += isKeyPressed(KEY_NSPIRE_RIGHT) - isKeyPressed(KEY_NSPIRE_LEFT); if(isKeyPressed(KEY_NSPIRE_UP)) { player.x = ((player.x << 6) + nRC_Cos(angle)) >> 6; player.y = ((player.y << 6) + nRC_Sin(angle)) >> 6; } else if(isKeyPressed(KEY_NSPIRE_DOWN)) { player.x = ((player.x << 6) - nRC_Cos(angle)) >> 6; player.y = ((player.y << 6) - nRC_Sin(angle)) >> 6; } if(isKeyPressed(KEY_NSPIRE_PLUS)) printf("%d", angle); } free(buffer); return 0;}
int nRC_Cos(int angle){ // Beware ! All trigonometry is done in base 256 ! int table[256]={128,128,128,128,127,127,127,126,126,125,124,123,122,122,121,119,118,117,116,114,113,111,110,108,106,105,103,101,99,97,95,93,91,248,86,84,81,79,76,74,71,68,66,63,60,58,55,52,49,46,43,40,37,34,31,28,25,22,19\,16,13,9,6,3,0,-3,-6,-9,-13,-16,-19,-22,-25,-28,-31,-34,-37,-40,-43,-46,-49,-52,-55,-58,-60,-63,-66,-68,-71,-74,-76,-79,-81,-84,-86,-248,-91,-93,-95,-97,-99,-101,-103,-105,-106,-108,-110,-111,-113,-114,-116,-117,-118,-119,-12\1,-122,-122,-123,-124,-125,-126,-126,-127,-127,-127,-128,-128,-128,-128,-128,-128,-128,-127,-127,-127,-126,-126,-125,-124,-123,-122,-122,-121,-119,-118,-117,-116,-114,-113,-111,-110,-108,-106,-105,-103,-101,-99,-97,-95,-93,-9\1,-248,-86,-84,-81,-79,-76,-74,-71,-68,-66,-63,-60,-58,-55,-52,-49,-46,-43,-40,-37,-34,-31,-28,-25,-22,-19,-16,-13,-9,-6,-3,0,3,6,9,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,60,63,66,68,71,74,76,79,81,84,86,248,91,93,95\,97,99,101,103,105,106,108,110,111,113,114,116,117,118,119,121,122,122,123,124,125,126,126,127,127,127,128,128,128}; return table[angle & 0xff];}
inline void nRC_dispBuf(char *buffer){ memcpy(SCREEN_BASE_ADDRESS, buffer, SCREEN_BYTES_SIZE);}
#include <os.h>// Useful structurestypedef struct{ int x; int y;} ScreenPoint;// Functions// Miscellaneous defines#define abs(x) (x < 0 ? -x : x)#define map(x, in_min, in_max, out_min, out_max) ((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min)#define nRC_248mul(a,b) ((a*b) >> 8)#define nRC_248div(a,b) ((a << 8) / b)// Trigonometry#define nRC_Sin(angle) nRC_Cos(angle + 64)int nRC_Cos(int angle){ // Beware ! All trigonometry is done in base 256 ! static int table[256]={128,128,128,128,127,127,127,126,126,125,124,123,122,122,121,119,118,117,116,114,113,111,110,108,106,105,103,101,99,97,95,93,91,248,86,84,81,79,76,74,71,68,66,63,60,58,55,52,49,46,43,40,37,34,31,28,25,22,19,16,13,9,6,3,0,-3,-6,-9,-13,-16,-19,-22,-25,-28,-31,-34,-37,-40,-43,-46,-49,-52,-55,-58,-60,-63,-66,-68,-71,-74,-76,-79,-81,-84,-86,-248,-91,-93,-95,-97,-99,-101,-103,-105,-106,-108,-110,-111,-113,-114,-116,-117,-118,-119,-121,-122,-122,-123,-124,-125,-126,-126,-127,-127,-127,-128,-128,-128,-128,-128,-128,-128,-127,-127,-127,-126,-126,-125,-124,-123,-122,-122,-121,-119,-118,-117,-116,-114,-113,-111,-110,-108,-106,-105,-103,-101,-99,-97,-95,-93,-91,-248,-86,-84,-81,-79,-76,-74,-71,-68,-66,-63,-60,-58,-55,-52,-49,-46,-43,-40,-37,-34,-31,-28,-25,-22,-19,-16,-13,-9,-6,-3,0,3,6,9,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58,60,63,66,68,71,74,76,79,81,84,86,248,91,93,95,97,99,101,103,105,106,108,110,111,113,114,116,117,118,119,121,122,122,123,124,125,126,126,127,127,127,128,128,128}; return table[angle & 0xff];}#define nRC_Tan(angle) nRC_248div(nRC_Sin(angle), nRC_Cos(angle))// Drawing functionsvoid nRC_setPixel(ScreenPoint pixel, int color, char* buffer){ int temp; if(pixel.x < 319 && pixel.x > 0 && pixel.y < 239 && pixel.y > 0) { if(is_cx) // color LCD, 16 bpp { buffer[temp = ((pixel.y * 320 + pixel.x) * 2)] = color & 0xff; buffer[temp + 1] = color >> 8 & 0xff; } else // monochrome LCD, 4 bpp { temp = (pixel.y * 160 + pixel.x/2); if(pixel.x & 1) { buffer[temp] = (buffer[temp] & 0xf0) | (color & 0x0f); } else { buffer[temp] = (buffer[temp] & 0x0f) | (color << 4 & 0xf0); } } }}#define nRC_drawHorizontalLine(origin, end, constant, color, buffer) nRC_drawLineShared(origin, end, constant, color, buffer, 0)#define nRC_drawVerticalLine(origin, end, constant, color, buffer) nRC_drawLineShared(origin, end, constant, color, buffer, 1)void nRC_drawLineShared(int origin, int end, int constant, int color, char *buffer, int side){ ScreenPoint pixel; int i,j; if(constant > 0 && constant < (side ? 319 : 239)) { i = min(origin, end); j = max(origin, end); if(!side) { pixel.y = constant; for(pixel.x = i; pixel.x < j; pixel.x++) nRC_setPixel(pixel, color, buffer); } else { pixel.x = constant; for(pixel.y = i; pixel.y < j; pixel.y++) nRC_setPixel(pixel, color, buffer); } }}void nRC_drawLine(ScreenPoint pt1, ScreenPoint pt2, int color, char* buffer){ int dx, dy, inx, iny, e; dx = pt2.x - pt1.x; dy = pt2.y - pt1.y; inx = dx > 0 ? 1 : -1; iny = dy > 0 ? 1 : -1; dx = abs(dx); dy = abs(dy); if(dx >= dy) { dy <<= 1; e = dy - dx; dx <<= 1; while (pt1.x != pt2.x) { nRC_setPixel(pt1, color, buffer); if(e >= 0) { pt1.y += iny; e-= dx; } e += dy; pt1.x += inx; } } else { dx <<= 1; e = dx - dy; dy <<= 1; while (pt1.y != pt2.y) { nRC_setPixel(pt1, color, buffer); if(e >= 0) { pt1.x += inx; e -= dy; } e += dx; pt1.y += iny; } } nRC_setPixel(pt1, color, buffer);}void nRC_fillTriangle(ScreenPoint pt1, ScreenPoint pt2, ScreenPoint pt3, int color, char *buffer){ int dx1, dx2, x1, x2, y, i; ScreenPoint intermediate; // Sort points from lowest to highest Y if(pt1.y > pt2.y) { intermediate = pt1; pt1 = pt2; pt2 = intermediate; } if(pt2.y > pt3.y) { intermediate = pt2; pt2 = pt3; pt3 = intermediate; } if(pt1.y > pt2.y) { intermediate = pt1; pt1 = pt2; pt2 = intermediate; } // dx1 = (x2 - x1) / (y2 - y1) dx1 = ((pt2.x - pt1.x) << 8) / ((pt2.y != pt1.y) ? pt2.y - pt1.y : 1); // dx2 = (x3 - x1) / (y3 - y1) dx2 = ((pt3.x - pt1.x) << 8) / ((pt3.y != pt1.y) ? pt3.y - pt1.y : 1); x1 = x2 = pt1.x << 8; y = pt1.y; // X values are multiplied by 256 to handle a sort of a decimal part to make calculations, and thus slopes, // more accurate. It's called a fixed .8 part, since it's only 8 bits. for(i = 0; i < 2; i++) { do { nRC_drawHorizontalLine(x1 >> 8, x2 >> 8, y, color, buffer); x1 += dx1; x2 += dx2; y++; } while(y < pt2.y); // dx1 = (x3 - x2) / (y3 - y2) dx1 = ((pt3.x - pt2.x) << 8) / ((pt3.y != pt2.y) ? pt3.y - pt2.y : 1); pt2.y = pt3.y; }}inline void nRC_clearBuf(char *buffer){ memset(buffer, 0, SCREEN_BYTES_SIZE);}inline void nRC_dispBuf(char *buffer){ memcpy(SCREEN_BASE_ADDRESS, buffer, SCREEN_BYTES_SIZE);}// Ray castingvoid nRC_rayCasting(int *map, ScreenPoint player, ScreenPoint mapDimensions, int fov, int angle, char *buffer){ int rayX, rayY, dx, dy, d1, d2, currentAngle, distFromProjPlane; int deltaAngle, midFov; int constantTan, flag, i = 0; unsigned char currentUsableAngle; deltaAngle = nRC_248div(fov, 320); midFov = fov / 2; currentAngle = ((angle - midFov) << 8) & 0xffff; distFromProjPlane = 64*277; for(i = 0; i < 320; i++) { currentAngle += deltaAngle; currentAngle &= 0xffff; currentUsableAngle = currentAngle >> 8; constantTan = nRC_Tan(currentUsableAngle); // Calculate distance from closest horizontal edge if(currentUsableAngle & 127) { rayY = (currentUsableAngle < 128 ? ((player.y >> 6) + 1) << 6 : ((player.y >> 6) << 6) - 1); rayX = (unsigned char)(currentUsableAngle + 64) & 127 ? nRC_248div(abs(rayY - player.y), constantTan) + player.x : player.x; dy = currentUsableAngle < 128 ? 64 : -64; dx = (unsigned char)(currentUsableAngle + 64) & 127 ? nRC_248div(64, constantTan) : 0; //printf("rayX = %d ; rayY = %d ; dx = %d ; dy = %d\n", rayX, rayY, dx, dy); //printf("currentUsableAngle = %d\n", currentUsableAngle); flag = rayX > 64 * mapDimensions.x || rayY > 64 * mapDimensions.y || rayX < 0 || rayY < 0; if(!flag) { if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)]) { d1 = nRC_248div(abs(player.y - rayY), (nRC_Sin(currentUsableAngle) ? nRC_Sin(currentUsableAngle) << 1 : 1)); flag = 1; } while(!flag) { rayX += dx; rayY += dy; if(flag = (rayX > 64 * mapDimensions.x || rayY > 64 * mapDimensions.y || rayX < 0 || rayY < 0)) break; if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)]) break; } } d1 = flag ? 50000000 : nRC_248div(abs(player.y - rayY), (nRC_Sin(currentUsableAngle) ? nRC_Sin(currentUsableAngle) << 1 : 1)); } else d1 = 50000000; skip1: d1 = nRC_248mul(d1, nRC_Cos(angle - currentUsableAngle)); // At this point we have the distance from the closest horizontal edge in d1 // Now calculate distance from the closest vertical edge if((unsigned char)(currentUsableAngle + 64) & 127) { rayX = (unsigned char)(currentUsableAngle - 64) < 128 ? ((player.x >> 6) << 6) - 1 : ((player.x >> 6) + 1) << 6; rayY = nRC_248mul(abs(player.x - rayX), constantTan) + player.y; dx = (unsigned char)(currentUsableAngle - 64) < 128 ? -64 : 64; dy = nRC_248mul(64, constantTan); flag = rayX > 64 * mapDimensions.x || rayY > 64 * mapDimensions.y || rayX < 0 || rayY < 0; if(!flag) { if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)]) { d2 = nRC_248div(abs(player.x - rayX), (nRC_Cos(currentUsableAngle) ? nRC_Cos(currentUsableAngle) << 1 : 1)); flag = 1; } while(!flag) { rayX += dx; rayY += dy; rayY += dy; if(flag = (rayX > 64 * mapDimensions.x || rayY > 64 * mapDimensions.y || rayX < 0 || rayY < 0)) break; if (map[(rayY >> 6) * mapDimensions.x + (rayX >> 6)]) break; } } d2 = flag ? 50000000 : nRC_248div(abs(player.x - rayX), (nRC_Cos(currentUsableAngle) ? nRC_Cos(currentUsableAngle) << 1 : 1)); } else d2 = 50000000; skip2: d2 = nRC_248mul(d2, nRC_Cos(angle - currentUsableAngle)); // Calculate the height of the current wall slice d1 = distFromProjPlane / min(d1, d2); nRC_drawVerticalLine((240 - d1) >> 1, (240 + d1) >> 1, i, 0xf800, buffer); }}
#include <os.h>#include "nRayC.h"int main(void){ static int map[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; ScreenPoint player = { 448, 448 }, mapDim = { 16, 16 }; unsigned char angle, *buffer; buffer = malloc(SCREEN_BYTES_SIZE); if(!buffer) exit(0); nRC_clearBuf(buffer); angle = 64; while(!isKeyPressed(KEY_NSPIRE_ESC)) { nRC_rayCasting(map, player, mapDim, 60, angle, buffer); nRC_dispBuf(buffer); nRC_clearBuf(buffer); angle += isKeyPressed(KEY_NSPIRE_RIGHT) - isKeyPressed(KEY_NSPIRE_LEFT); if(isKeyPressed(KEY_NSPIRE_UP)) { player.x = ((player.x << 6) + nRC_Cos(angle)) >> 6; player.y = ((player.y << 6) + nRC_Sin(angle)) >> 6; } else if(isKeyPressed(KEY_NSPIRE_DOWN)) { player.x = ((player.x << 6) - nRC_Cos(angle)) >> 6; player.y = ((player.y << 6) - nRC_Sin(angle)) >> 6; } if(isKeyPressed(KEY_NSPIRE_PLUS)) printf("%d", angle); } free(buffer); return 0;}
Jacobly helped me on IRC so I was able to get rid of the crash,