123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529 |
- /*
- * Raycaster, based on lodev engine tutorial
- */
- #define word char
- #include "LIB/MATH.C"
- #include "LIB/STDLIB.C"
- #include "LIB/SYS.C"
- #include "LIB/GFX.C"
- #include "LIB/FP.C"
- #define screenWidth 320
- #define screenHeight 240
- #define mapWidth 24
- #define mapHeight 24
- #define BTN_LEFT 256
- #define BTN_RIGHT 257
- #define BTN_UP 258
- #define BTN_DOWN 259
- // Colors
- #define COLOR_RED 224
- #define COLOR_DARK_RED 96
- #define COLOR_GREEN 28
- #define COLOR_DARK_GREEN 12
- #define COLOR_BLUE 3
- #define COLOR_DARK_BLUE 2
- #define COLOR_WHITE 0xFF
- #define COLOR_GREY 0xB6
- #define COLOR_YELLOW 0xFC
- #define COLOR_DARK_YELLOW 0x90
- #define FB_ADDR 0xD00000
- // Framebuffer. fb[Y][X] (bottom right is [239][319])
- char (*fb)[screenWidth] = (char (*)[screenWidth]) FB_ADDR;
- word quitGame = 0;
- word LUTdirX[360] = {
- -65526, -65496, -65446, -65376, -65287, -65177, -65048, -64898, -64729, -64540, -64332, -64104,
- -63856, -63589, -63303, -62997, -62672, -62328, -61966, -61584, -61183, -60764, -60326, -59870,
- -59396, -58903, -58393, -57865, -57319, -56756, -56175, -55578, -54963, -54332, -53684, -53020,
- -52339, -51643, -50931, -50203, -49461, -48703, -47930, -47143, -46341, -45525, -44695, -43852,
- -42995, -42126, -41243, -40348, -39441, -38521, -37590, -36647, -35693, -34729, -33754, -32768,
- -31772, -30767, -29753, -28729, -27697, -26656, -25607, -24550, -23486, -22415, -21336, -20252,
- -19161, -18064, -16962, -15855, -14742, -13626, -12505, -11380, -10252, -9121, -7987, -6850,
- -5712, -4572, -3430, -2287, -1144, 0, 1144, 2287, 3430, 4572, 5712, 6850,
- 7987, 9121, 10252, 11380, 12505, 13626, 14742, 15855, 16962, 18064, 19161, 20252,
- 21336, 22415, 23486, 24550, 25607, 26656, 27697, 28729, 29753, 30767, 31772, 32768,
- 33754, 34729, 35693, 36647, 37590, 38521, 39441, 40348, 41243, 42126, 42995, 43852,
- 44695, 45525, 46341, 47143, 47930, 48703, 49461, 50203, 50931, 51643, 52339, 53020,
- 53684, 54332, 54963, 55578, 56175, 56756, 57319, 57865, 58393, 58903, 59396, 59870,
- 60326, 60764, 61183, 61584, 61966, 62328, 62672, 62997, 63303, 63589, 63856, 64104,
- 64332, 64540, 64729, 64898, 65048, 65177, 65287, 65376, 65446, 65496, 65526, 65536,
- 65526, 65496, 65446, 65376, 65287, 65177, 65048, 64898, 64729, 64540, 64332, 64104,
- 63856, 63589, 63303, 62997, 62672, 62328, 61966, 61584, 61183, 60764, 60326, 59870,
- 59396, 58903, 58393, 57865, 57319, 56756, 56175, 55578, 54963, 54332, 53684, 53020,
- 52339, 51643, 50931, 50203, 49461, 48703, 47930, 47143, 46341, 45525, 44695, 43852,
- 42995, 42126, 41243, 40348, 39441, 38521, 37590, 36647, 35693, 34729, 33754, 32768,
- 31772, 30767, 29753, 28729, 27697, 26656, 25607, 24550, 23486, 22415, 21336, 20252,
- 19161, 18064, 16962, 15855, 14742, 13626, 12505, 11380, 10252, 9121, 7987, 6850,
- 5712, 4572, 3430, 2287, 1144, 0, -1144, -2287, -3430, -4572, -5712, -6850,
- -7987, -9121, -10252, -11380, -12505, -13626, -14742, -15855, -16962, -18064, -19161, -20252,
- -21336, -22415, -23486, -24550, -25607, -26656, -27697, -28729, -29753, -30767, -31772, -32768,
- -33754, -34729, -35693, -36647, -37590, -38521, -39441, -40348, -41243, -42126, -42995, -43852,
- -44695, -45525, -46341, -47143, -47930, -48703, -49461, -50203, -50931, -51643, -52339, -53020,
- -53684, -54332, -54963, -55578, -56175, -56756, -57319, -57865, -58393, -58903, -59396, -59870,
- -60326, -60764, -61183, -61584, -61966, -62328, -62672, -62997, -63303, -63589, -63856, -64104,
- -64332, -64540, -64729, -64898, -65048, -65177, -65287, -65376, -65446, -65496, -65526, -65536
- };
- word LUTdirY[360] = {
- 1144, 2287, 3430, 4572, 5712, 6850, 7987, 9121, 10252, 11380, 12505, 13626,
- 14742, 15855, 16962, 18064, 19161, 20252, 21336, 22415, 23486, 24550, 25607, 26656,
- 27697, 28729, 29753, 30767, 31772, 32768, 33754, 34729, 35693, 36647, 37590, 38521,
- 39441, 40348, 41243, 42126, 42995, 43852, 44695, 45525, 46341, 47143, 47930, 48703,
- 49461, 50203, 50931, 51643, 52339, 53020, 53684, 54332, 54963, 55578, 56175, 56756,
- 57319, 57865, 58393, 58903, 59396, 59870, 60326, 60764, 61183, 61584, 61966, 62328,
- 62672, 62997, 63303, 63589, 63856, 64104, 64332, 64540, 64729, 64898, 65048, 65177,
- 65287, 65376, 65446, 65496, 65526, 65536, 65526, 65496, 65446, 65376, 65287, 65177,
- 65048, 64898, 64729, 64540, 64332, 64104, 63856, 63589, 63303, 62997, 62672, 62328,
- 61966, 61584, 61183, 60764, 60326, 59870, 59396, 58903, 58393, 57865, 57319, 56756,
- 56175, 55578, 54963, 54332, 53684, 53020, 52339, 51643, 50931, 50203, 49461, 48703,
- 47930, 47143, 46341, 45525, 44695, 43852, 42995, 42126, 41243, 40348, 39441, 38521,
- 37590, 36647, 35693, 34729, 33754, 32768, 31772, 30767, 29753, 28729, 27697, 26656,
- 25607, 24550, 23486, 22415, 21336, 20252, 19161, 18064, 16962, 15855, 14742, 13626,
- 12505, 11380, 10252, 9121, 7987, 6850, 5712, 4572, 3430, 2287, 1144, 0,
- -1144, -2287, -3430, -4572, -5712, -6850, -7987, -9121, -10252, -11380, -12505, -13626,
- -14742, -15855, -16962, -18064, -19161, -20252, -21336, -22415, -23486, -24550, -25607, -26656,
- -27697, -28729, -29753, -30767, -31772, -32768, -33754, -34729, -35693, -36647, -37590, -38521,
- -39441, -40348, -41243, -42126, -42995, -43852, -44695, -45525, -46341, -47143, -47930, -48703,
- -49461, -50203, -50931, -51643, -52339, -53020, -53684, -54332, -54963, -55578, -56175, -56756,
- -57319, -57865, -58393, -58903, -59396, -59870, -60326, -60764, -61183, -61584, -61966, -62328,
- -62672, -62997, -63303, -63589, -63856, -64104, -64332, -64540, -64729, -64898, -65048, -65177,
- -65287, -65376, -65446, -65496, -65526, -65536, -65526, -65496, -65446, -65376, -65287, -65177,
- -65048, -64898, -64729, -64540, -64332, -64104, -63856, -63589, -63303, -62997, -62672, -62328,
- -61966, -61584, -61183, -60764, -60326, -59870, -59396, -58903, -58393, -57865, -57319, -56756,
- -56175, -55578, -54963, -54332, -53684, -53020, -52339, -51643, -50931, -50203, -49461, -48703,
- -47930, -47143, -46341, -45525, -44695, -43852, -42995, -42126, -41243, -40348, -39441, -38521,
- -37590, -36647, -35693, -34729, -33754, -32768, -31772, -30767, -29753, -28729, -27697, -26656,
- -25607, -24550, -23486, -22415, -21336, -20252, -19161, -18064, -16962, -15855, -14742, -13626,
- -12505, -11380, -10252, -9121, -7987, -6850, -5712, -4572, -3430, -2287, -1144, 0
- };
- word LUTplaneX[360] = {
- 755, 1510, 2264, 3017, 3770, 4521, 5271, 6020, 6766, 7511, 8253, 8993,
- 9730, 10464, 11195, 11922, 12646, 13366, 14082, 14794, 15501, 16203, 16901, 17593,
- 18280, 18961, 19637, 20306, 20970, 21627, 22277, 22921, 23558, 24187, 24809, 25424,
- 26031, 26630, 27220, 27803, 28377, 28942, 29499, 30047, 30585, 31114, 31634, 32144,
- 32644, 33134, 33614, 34084, 34544, 34993, 35431, 35859, 36276, 36681, 37076, 37459,
- 37831, 38191, 38539, 38876, 39201, 39514, 39815, 40104, 40381, 40645, 40897, 41137,
- 41364, 41578, 41780, 41969, 42145, 42309, 42459, 42597, 42721, 42833, 42931, 43017,
- 43089, 43148, 43194, 43227, 43247, 43254, 43247, 43227, 43194, 43148, 43089, 43017,
- 42931, 42833, 42721, 42597, 42459, 42309, 42145, 41969, 41780, 41578, 41364, 41137,
- 40897, 40645, 40381, 40104, 39815, 39514, 39201, 38876, 38539, 38191, 37831, 37459,
- 37076, 36681, 36276, 35859, 35431, 34993, 34544, 34084, 33614, 33134, 32644, 32144,
- 31634, 31114, 30585, 30047, 29499, 28942, 28377, 27803, 27220, 26630, 26031, 25424,
- 24809, 24187, 23558, 22921, 22277, 21627, 20970, 20306, 19637, 18961, 18280, 17593,
- 16901, 16203, 15501, 14794, 14082, 13366, 12646, 11922, 11195, 10464, 9730, 8993,
- 8253, 7511, 6766, 6020, 5271, 4521, 3770, 3017, 2264, 1510, 755, 0,
- -755, -1510, -2264, -3017, -3770, -4521, -5271, -6020, -6766, -7511, -8253, -8993,
- -9730, -10464, -11195, -11922, -12646, -13366, -14082, -14794, -15501, -16203, -16901, -17593,
- -18280, -18961, -19637, -20306, -20970, -21627, -22277, -22921, -23558, -24187, -24809, -25424,
- -26031, -26630, -27220, -27803, -28377, -28942, -29499, -30047, -30585, -31114, -31634, -32144,
- -32644, -33134, -33614, -34084, -34544, -34993, -35431, -35859, -36276, -36681, -37076, -37459,
- -37831, -38191, -38539, -38876, -39201, -39514, -39815, -40104, -40381, -40645, -40897, -41137,
- -41364, -41578, -41780, -41969, -42145, -42309, -42459, -42597, -42721, -42833, -42931, -43017,
- -43089, -43148, -43194, -43227, -43247, -43254, -43247, -43227, -43194, -43148, -43089, -43017,
- -42931, -42833, -42721, -42597, -42459, -42309, -42145, -41969, -41780, -41578, -41364, -41137,
- -40897, -40645, -40381, -40104, -39815, -39514, -39201, -38876, -38539, -38191, -37831, -37459,
- -37076, -36681, -36276, -35859, -35431, -34993, -34544, -34084, -33614, -33134, -32644, -32144,
- -31634, -31114, -30585, -30047, -29499, -28942, -28377, -27803, -27220, -26630, -26031, -25424,
- -24809, -24187, -23558, -22921, -22277, -21627, -20970, -20306, -19637, -18961, -18280, -17593,
- -16901, -16203, -15501, -14794, -14082, -13366, -12646, -11922, -11195, -10464, -9730, -8993,
- -8253, -7511, -6766, -6020, -5271, -4521, -3770, -3017, -2264, -1510, -755, 0
- };
- word LUTplaneY[360] = {
- 43247, 43227, 43194, 43148, 43089, 43017, 42931, 42833, 42721, 42597, 42459, 42309,
- 42145, 41969, 41780, 41578, 41364, 41137, 40897, 40645, 40381, 40104, 39815, 39514,
- 39201, 38876, 38539, 38191, 37831, 37459, 37076, 36681, 36276, 35859, 35431, 34993,
- 34544, 34084, 33614, 33134, 32644, 32144, 31634, 31114, 30585, 30047, 29499, 28942,
- 28377, 27803, 27220, 26630, 26031, 25424, 24809, 24187, 23558, 22921, 22277, 21627,
- 20970, 20306, 19637, 18961, 18280, 17593, 16901, 16203, 15501, 14794, 14082, 13366,
- 12646, 11922, 11195, 10464, 9730, 8993, 8253, 7511, 6766, 6020, 5271, 4521,
- 3770, 3017, 2264, 1510, 755, 0, -755, -1510, -2264, -3017, -3770, -4521,
- -5271, -6020, -6766, -7511, -8253, -8993, -9730, -10464, -11195, -11922, -12646, -13366,
- -14082, -14794, -15501, -16203, -16901, -17593, -18280, -18961, -19637, -20306, -20970, -21627,
- -22277, -22921, -23558, -24187, -24809, -25424, -26031, -26630, -27220, -27803, -28377, -28942,
- -29499, -30047, -30585, -31114, -31634, -32144, -32644, -33134, -33614, -34084, -34544, -34993,
- -35431, -35859, -36276, -36681, -37076, -37459, -37831, -38191, -38539, -38876, -39201, -39514,
- -39815, -40104, -40381, -40645, -40897, -41137, -41364, -41578, -41780, -41969, -42145, -42309,
- -42459, -42597, -42721, -42833, -42931, -43017, -43089, -43148, -43194, -43227, -43247, -43254,
- -43247, -43227, -43194, -43148, -43089, -43017, -42931, -42833, -42721, -42597, -42459, -42309,
- -42145, -41969, -41780, -41578, -41364, -41137, -40897, -40645, -40381, -40104, -39815, -39514,
- -39201, -38876, -38539, -38191, -37831, -37459, -37076, -36681, -36276, -35859, -35431, -34993,
- -34544, -34084, -33614, -33134, -32644, -32144, -31634, -31114, -30585, -30047, -29499, -28942,
- -28377, -27803, -27220, -26630, -26031, -25424, -24809, -24187, -23558, -22921, -22277, -21627,
- -20970, -20306, -19637, -18961, -18280, -17593, -16901, -16203, -15501, -14794, -14082, -13366,
- -12646, -11922, -11195, -10464, -9730, -8993, -8253, -7511, -6766, -6020, -5271, -4521,
- -3770, -3017, -2264, -1510, -755, 0, 755, 1510, 2264, 3017, 3770, 4521,
- 5271, 6020, 6766, 7511, 8253, 8993, 9730, 10464, 11195, 11922, 12646, 13366,
- 14082, 14794, 15501, 16203, 16901, 17593, 18280, 18961, 19637, 20306, 20970, 21627,
- 22277, 22921, 23558, 24187, 24809, 25424, 26031, 26630, 27220, 27803, 28377, 28942,
- 29499, 30047, 30585, 31114, 31634, 32144, 32644, 33134, 33614, 34084, 34544, 34993,
- 35431, 35859, 36276, 36681, 37076, 37459, 37831, 38191, 38539, 38876, 39201, 39514,
- 39815, 40104, 40381, 40645, 40897, 41137, 41364, 41578, 41780, 41969, 42145, 42309,
- 42459, 42597, 42721, 42833, 42931, 43017, 43089, 43148, 43194, 43227, 43247, 43254
- };
- word worldMap[mapWidth][mapHeight]=
- {
- {1,1,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0,1},
- {1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
- {1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
- {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1},
- {1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
- {1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
- {1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
- {1,0,0,0,0,0,0,0,0,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,0,0,0,0,0,0,0,0,1},
- {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,5,0,0,0,0,0,0,1},
- {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
- {1,4,4,4,4,4,4,4,4,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,1,1,1,1,1,1,1,1}
- };
- // Render vertical line in pixel plane
- // INPUT:
- // r4 = x (which vertical line)
- // r5 = y when to start drawing line
- // r6 = y when to stop drawing line
- // r7 = color of line
- void RAYFX_drawVertLine(word x, word start, word end, char color)
- {
- // reg 4 5 6 7 and 2 (retval) are safe
- asm(
- "; backup registers\n"
- "push r9\n"
- );
- asm(
- "load32 0xD00000 r9 ; r9 = framebuffer addr\n"
- "add r9 r4 r4 ; r4 = first pixel in line\n"
- "multu r5 320 r9 ; r9 = start with line offset\n"
- "add r9 r4 r5 ; r5 = fb addr of start\n"
-
- "multu r6 320 r9 ; r9 = end with line offset\n"
- "add r9 r4 r6 ; r6 = fb addr of start\n"
- "load 239 r2 ; r2 = y endloop\n"
- "multu r2 320 r9 ; r9 = start line offset\n"
- "add r9 r4 r2 ; r2 = fb addr of final pixel\n"
- "; draw until start\n"
- "RAYFX_drawVlineLoopCeiling:\n"
- " write 0 r4 r0 ; write black pixel\n"
- " add r4 320 r4 ; go to next line pixel\n"
- " bge r4 r5 2 ; keep looping until reached start\n"
- " jump RAYFX_drawVlineLoopCeiling\n"
- "; draw until end\n"
- "RAYFX_drawVlineLoopWall:\n"
- " write 0 r4 r7 ; write color pixel\n"
- " add r4 320 r4 ; go to next line pixel\n"
- " bge r4 r6 2 ; keep looping until reached end\n"
- " jump RAYFX_drawVlineLoopWall\n"
- "; draw until final pixel\n"
- "RAYFX_drawVlineLoopFloor:\n"
- " write 0 r4 r0 ; write black pixel\n"
- " add r4 320 r4 ; go to next line pixel\n"
- " bge r4 r2 2 ; keep looping until reached end of screen\n"
- " jump RAYFX_drawVlineLoopFloor\n"
- );
- asm(
- "; restore registers\n"
- "pop r9\n"
- );
- }
- int main()
- {
- // clear screen from text
- GFX_clearWindowtileTable();
- GFX_clearWindowpaletteTable();
- GFX_clearBGtileTable();
- GFX_clearBGpaletteTable();
- //x and y start position
- fixed_point_t posX = FP_intToFP(12);
- fixed_point_t posY = FP_intToFP(12);
- //initial direction vector
- fixed_point_t dirX = LUTdirX[0];
- fixed_point_t dirY = LUTdirY[0];
- //the 2d raycaster version of camera plane
- fixed_point_t planeX = LUTplaneX[0];
- fixed_point_t planeY = LUTplaneY[0];
- // rotation angle (loops at 360)
- word rotationAngle = 0;
- word rotationSpeed = 3; // degrees per frame
- fixed_point_t moveSpeed = FP_StringToFP("0.15");
- while(!quitGame)
- {
- word x;
- for(x = 0; x < screenWidth; x++)
- {
- //calculate ray position and direction
- fixed_point_t cameraX = FP_Div(FP_intToFP(x<<1), FP_intToFP(screenWidth)) - FP_intToFP(1); //x-coordinate in camera space
- fixed_point_t rayDirX = dirX + FP_Mult(planeX, cameraX);
- fixed_point_t rayDirY = dirY + FP_Mult(planeY, cameraX);
- //which box of the map we are in
- word mapX = FP_FPtoInt(posX);
- word mapY = FP_FPtoInt(posY);
- //length of ray from current position to next x or y-side
- fixed_point_t sideDistX;
- fixed_point_t sideDistY;
- //length of ray from one x or y-side to next x or y-side
- //these are derived as:
- //deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
- //deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
- //which can be simplified to abs(|rayDir| / rayDirX) and abs(|rayDir| / rayDirY)
- //where |rayDir| is the length of the vector (rayDirX, rayDirY). Its length,
- //unlike (dirX, dirY) is not 1, however this does not matter, only the
- //ratio between deltaDistX and deltaDistY matters, due to the way the DDA
- //stepping further below works. So the values can be computed as below.
- // Division through zero is prevented by setting the result to a very high value
- fixed_point_t deltaDistX = (rayDirX == 0) ? 1<<30 : MATH_abs( FP_Div(FP_intToFP(1), rayDirX));
- fixed_point_t deltaDistY = (rayDirY == 0) ? 1<<30 : MATH_abs( FP_Div(FP_intToFP(1), rayDirY));
- fixed_point_t perpWallDist;
- //what direction to step in x or y-direction (either +1 or -1)
- word stepX;
- word stepY;
- word hit = 0; //was there a wall hit?
- word side; //was a NS or a EW wall hit?
- //calculate step and initial sideDist
- if(rayDirX < 0)
- {
- stepX = -1;
- sideDistX = FP_Mult((posX - FP_intToFP(mapX)), deltaDistX);
- }
- else
- {
- stepX = 1;
- sideDistX = FP_Mult((FP_intToFP(mapX + 1) - posX), deltaDistX);
- }
- if(rayDirY < 0)
- {
- stepY = -1;
- sideDistY = FP_Mult((posY - FP_intToFP(mapY)), deltaDistY);
- }
- else
- {
- stepY = 1;
- sideDistY = FP_Mult((FP_intToFP(mapY + 1) - posY), deltaDistY);
- }
- //perform DDA
- while(hit == 0)
- {
- //jump to next map square, either in x-direction, or in y-direction
- if(sideDistX < sideDistY)
- {
- sideDistX += deltaDistX;
- mapX += stepX;
- side = 0;
- }
- else
- {
- sideDistY += deltaDistY;
- mapY += stepY;
- side = 1;
- }
- //Check if ray has hit a wall
- if(worldMap[mapX][mapY] > 0) hit = 1;
- }
- //Calculate distance projected on camera direction. This is the shortest distance from the point where the wall is
- //hit to the camera plane. Euclidean to center camera point would give fisheye effect!
- //This can be computed as (mapX - posX + (1 - stepX) / 2) / rayDirX for side == 0, or same formula with Y
- //for size == 1, but can be simplified to the code below thanks to how sideDist and deltaDist are computed:
- //because they were left scaled to |rayDir|. sideDist is the entire length of the ray above after the multiple
- //steps, but we subtract deltaDist once because one step more into the wall was taken above.
- if(side == 0) perpWallDist = (sideDistX - deltaDistX);
- else perpWallDist = (sideDistY - deltaDistY);
- //Calculate height of line to draw on screen
- word lineHeight = FP_FPtoInt(FP_Div(FP_intToFP(screenHeight), perpWallDist));
- //calculate lowest and highest pixel to fill in current stripe
- word drawStart = - (lineHeight >> 1) + (screenHeight >> 1);
- if(drawStart < 0) drawStart = 0;
- word drawEnd = (lineHeight >> 1) + (screenHeight >> 1);
- if(drawEnd >= screenHeight) drawEnd = screenHeight - 1;
- //choose wall color
- //give x and y sides different brightness
- char color;
- switch(worldMap[mapX][mapY])
- {
- case 1: color = (side == 1) ? COLOR_DARK_RED : COLOR_RED; break;
- case 2: color = (side == 1) ? COLOR_DARK_GREEN : COLOR_GREEN; break;
- case 3: color = (side == 1) ? COLOR_DARK_BLUE : COLOR_BLUE; break;
- case 4: color = (side == 1) ? COLOR_GREY : COLOR_WHITE; break;
- default: color = (side == 1) ? COLOR_DARK_YELLOW : COLOR_YELLOW; break;
- }
- //draw the pixels of the stripe as a vertical line
- // Safity checks beforehand
- // Currently skips first line of frame as it does not render properly
- if (x != 0 && drawStart >= 0 && drawEnd >= drawStart && drawEnd < screenHeight)
- {
- RAYFX_drawVertLine(x, drawStart, drawEnd, color);
- }
- }
- // check which button is held
- if (BDOS_USBkeyHeld(BTN_LEFT))
- {
- //both camera direction and camera plane must be rotated
- rotationAngle -= rotationSpeed;
- if (rotationAngle < 0)
- {
- rotationAngle += 360;
- }
- dirX = LUTdirX[rotationAngle];
- dirY = LUTdirY[rotationAngle];
- planeX = LUTplaneX[rotationAngle];
- planeY = LUTplaneY[rotationAngle];
- }
- else if (BDOS_USBkeyHeld(BTN_RIGHT))
- {
- //both camera direction and camera plane must be rotated
- rotationAngle += rotationSpeed;
- if (rotationAngle >= 360)
- {
- rotationAngle -= 360;
- }
- dirX = LUTdirX[rotationAngle];
- dirY = LUTdirY[rotationAngle];
- planeX = LUTplaneX[rotationAngle];
- planeY = LUTplaneY[rotationAngle];
- }
- if (BDOS_USBkeyHeld(BTN_UP))
- {
- word worldMapX = FP_FPtoInt(posX + FP_Mult(dirX, moveSpeed));
- word worldMapY = FP_FPtoInt(posY);
- if(worldMap[worldMapX][worldMapY] == 0)
- {
- posX += FP_Mult(dirX, moveSpeed);
- }
- worldMapX = FP_FPtoInt(posX);
- worldMapY = FP_FPtoInt(posY + FP_Mult(dirY, moveSpeed));
- if(worldMap[worldMapX][worldMapY] == 0)
- {
- posY += FP_Mult(dirY, moveSpeed);
- }
- }
- else if (BDOS_USBkeyHeld(BTN_DOWN))
- {
- word worldMapX = FP_FPtoInt(posX - FP_Mult(dirX, moveSpeed));
- word worldMapY = FP_FPtoInt(posY);
- if(worldMap[worldMapX][worldMapY] == 0)
- {
- posX -= FP_Mult(dirX, moveSpeed);
- }
- worldMapX = FP_FPtoInt(posX);
- worldMapY = FP_FPtoInt(posY - FP_Mult(dirY, moveSpeed));
- if(worldMap[worldMapX][worldMapY] == 0)
- {
- posY -= FP_Mult(dirY, moveSpeed);
- }
- }
- if (HID_FifoAvailable())
- {
- word c = HID_FifoRead();
- if (c == 27) // escape
- {
- GFX_clearPXframebuffer();
- return 'q';
- }
- }
-
- }
- return 'q';
- }
- void interrupt()
- {
- // handle all interrupts
- word i = getIntID();
- switch(i)
- {
- case INTID_TIMER1:
- timer1Value = 1; // notify ending of timer1
- break;
- case INTID_TIMER2:
- break;
- case INTID_UART0:
- break;
- case INTID_GPU:
- break;
- case INTID_TIMER3:
- break;
- case INTID_PS2:
- break;
- case INTID_UART1:
- break;
- case INTID_UART2:
- break;
- }
- }
|