Fix division by zero
[raycastlib.git] / programs / helloWorld.c
blob8a3edf3666da558830a5a57c06aefe81222e385f
1 /*
2 Simple hello world for raycastlib. Renders a single raycasted frame into
3 terminal as ASCII.
5 author: Miloslav Ciz
6 license: CC0 1.0, public domain
7 */
9 #define RCL_PIXEL_FUNCTION pixelFunc /* tell the library the name of our
10 function with which we write pixels to
11 the screen */
12 #define RCL_COMPUTE_FLOOR_DEPTH 0 /* turn off what we don't need, to help
13 performance */
14 #define RCL_COMPUTE_CEILING_DEPTH 0
16 #include "../raycastlib.h" // now include raycastlib itself
18 #include <stdio.h> // for IO
20 #define SCREEN_W 80
21 #define SCREEN_H 40
23 #define PIXELS_TOTAL ((SCREEN_W + 1) * SCREEN_H + 1)
25 char screen[(SCREEN_W + 1) * SCREEN_H + 1]; /* our ASCII screen, with extra
26 space for newlines and
27 terminating 0 */
29 /* Function that will tell the library height of square at each coordinates.
30 We may implement it however we like, it may e.g. read the height out of a
31 level array. Here we simply compute the height procedurally, without needing
32 extra data. */
33 RCL_Unit heightAt(int16_t x, int16_t y)
35 return (x < 0 || x > 10 || y < 0 || y > 10) ?
36 2 * RCL_UNITS_PER_SQUARE : // two library units, imagine e.g. 2 meters
40 /* This is the function we write pixels to our ASCII screen with. Above we have
41 told the library it should call this function during rendering. */
42 void pixelFunc(RCL_PixelInfo *p)
44 char c = ' ';
46 if (p->isWall)
48 switch (p->hit.direction)
50 case 1:
51 case 2: c = '#'; break;
52 case 0:
53 case 3: c = '/'; break;
54 default: break;
57 else // floor/ceiling
58 c = p->isFloor ? '.' : ':';
60 screen[p->position.y * (SCREEN_W + 1) + p->position.x] = c;
63 int main()
65 for (int i = 0; i < PIXELS_TOTAL; ++i) // prefill screen with newlines
66 screen[i] = '\n';
68 screen[PIXELS_TOTAL - 1] = 0; // terminate the string
70 RCL_Camera camera; // camera to specify our view
71 RCL_initCamera(&camera);
73 // set up the camera:
74 camera.position.x = 5 * RCL_UNITS_PER_SQUARE;
75 camera.position.y = 6 * RCL_UNITS_PER_SQUARE;
76 camera.direction = 5 * RCL_UNITS_PER_SQUARE / 6; // 4/5 of full angle
77 camera.resolution.x = SCREEN_W;
78 camera.resolution.y = SCREEN_H;
80 RCL_RayConstraints constraints; /* this struct tell the library more
81 details about how it should cast
82 rays */
83 RCL_initRayConstraints(&constraints);
84 constraints.maxHits = 1; // we don't need more than 1 hit here
85 constraints.maxSteps = 40; // max squares a ray will travel
89 /* This will start the rendering itself. The library will start calling our
90 pixelFunc to render one frame. You can also try to use the complex
91 rendering function, the result should be practically the same:
93 RCL_renderComplex(camera,heightAt,0,0,constraints); */
94 RCL_renderSimple(camera,heightAt,0,0,constraints);
96 puts(screen); // print out the rendered frame
98 return 0; // done!