From 7040fff6e70b7d590461a7e3479b9fd871cf9042 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Sun, 21 Apr 2024 18:10:31 -0500 Subject: [PATCH] Reorganized code. --- pc/CMakeLists.txt | 3 + pc/include/a23d2.h | 2 +- pc/include/bitmap.h | 69 +++++++ pc/include/util.h | 8 + pc/src/a23d2.c | 371 ++++++++++++++++++++++++++++++++++++++ pc/src/bitmap.c | 116 ++++++++++++ pc/src/flight.c | 22 ++- pc/src/main.c | 426 ++------------------------------------------ 8 files changed, 594 insertions(+), 423 deletions(-) create mode 100644 pc/include/bitmap.h create mode 100644 pc/src/a23d2.c create mode 100644 pc/src/bitmap.c diff --git a/pc/CMakeLists.txt b/pc/CMakeLists.txt index af646af..da97601 100644 --- a/pc/CMakeLists.txt +++ b/pc/CMakeLists.txt @@ -30,6 +30,9 @@ list(TRANSFORM SOURCE PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/src/") add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCE} + src/a23d2.c + include/bitmap.h + src/bitmap.c ) diff --git a/pc/include/a23d2.h b/pc/include/a23d2.h index bb59b86..ad4c3f2 100644 --- a/pc/include/a23d2.h +++ b/pc/include/a23d2.h @@ -26,7 +26,7 @@ #else #include #include -typedef uint8_t byte; +#include "util.h" #endif diff --git a/pc/include/bitmap.h b/pc/include/bitmap.h new file mode 100644 index 0000000..1138dc7 --- /dev/null +++ b/pc/include/bitmap.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef BITMAP_H +#define BITMAP_H + + +#include + +#include "util.h" + + +#define HEIGHT 240 +#define WIDTH 320 +#define SCALE 1.25 // Scale factor for 256->320 + + +// ***FIX*** Somehow we're getting invalid drawing coordinates from A2-3D2. +#define bitmapPutPixelIOSet(x,y) \ +({ \ + if ((x < WIDTH) && (y < HEIGHT)) { \ + byte *p = _pixels + ((x) * 4 + ((y) * WIDTH * 4)); \ + *p++ = _color.r; \ + *p++ = _color.g; \ + *p++ = _color.b; \ + *p++ = 255; \ + } else { \ + printf("CLIPPED!\n"); \ + fflush(0); \ + } \ +}) + + +typedef struct ColorS { + byte r; + byte g; + byte b; +} ColorT; + + +extern byte *_pixels; +extern ColorT _color; + + +void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +void colorSet(byte ega); + + +#endif // BITMAP_H diff --git a/pc/include/util.h b/pc/include/util.h index 9f635bf..584257f 100644 --- a/pc/include/util.h +++ b/pc/include/util.h @@ -26,6 +26,14 @@ #include +#include + + +#define LOW_BYTE(x) ((uint8_t)(x)) +#define HIGH_BYTE(x) ((uint8_t)(((uint16_t)(x)) >> 8)) + + +typedef uint8_t byte; char *utilCreateString(char *format, ...); diff --git a/pc/src/a23d2.c b/pc/src/a23d2.c new file mode 100644 index 0000000..54c284b --- /dev/null +++ b/pc/src/a23d2.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2024 Scott Duensing, scott@kangaroopunch.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include + +#include "vrEmu6502.h" +#include "a23d2bin.h" +#include "bitmap.h" +#include "flight.h" + +#include "a23d2.h" + + +// Emulator Stuff. +byte _RAM[0x10000]; // 6502 memory. +VrEmu6502 *_v6502 = NULL; + +uint16_t _drawlistInDatabase; +float _trig; +uint8_t _x1; + + +void jsr(uint16_t addr); +void landscape(void); +byte memoryRead(uint16_t addr, bool isDebug); +void memoryWrite(uint16_t addr, byte value); + + +void a23d2Cos(void) { + // Map 0-359 into 0-255. + _tdata = _tdata % 359; + _x1 = (360/256) * _tdata; + + // Call COSEX. + _RAM[A23D2_TDATA] = _x1; + jsr(A23D2_COSEX); + + // Convert to float. + _trig = (float)(_RAM[A23D2_TDATA] + _RAM[A23D2_TDATA + 1] * 256) / 32768; +} + + +void a23d2Draw(void) { + uint16_t pointer = DRAWLIST_P0; + int16_t x1; + int16_t y1; + int16_t x2; + int16_t y2; + + while (true) { + switch (_RAM[pointer++]) { + + // Line. + case LIN2D: + x1 = (int8_t)_RAM[pointer++] + 128; + y1 = 255 - ((int8_t)_RAM[pointer++] + 128); + x2 = (int8_t)_RAM[pointer++] + 128; + y2 = 255 - ((int8_t)_RAM[pointer++] + 128); + bitmapLine(x1 * SCALE, y1 / SCALE, x2 * SCALE, y2 / SCALE); + continue; + + // Point. + case PNT2D: + x1 = (int8_t)_RAM[pointer++] + 128; + y1 = 255 - ((int8_t)_RAM[pointer++] + 128); + x1 *= SCALE; + y1 /= SCALE; + bitmapPutPixelIOSet(x1, y1); + continue; + + // Set Color. + case STCOL: + x1 = _RAM[pointer++]; + colorSet(x1); + continue; + + // Set Resolution. + case SRES: + // Eat this byte. We don't need it. + pointer++; + continue; + + // End. + case END: + break; + + } + break; + } +} + + +void a23d2Init(void) { + uint16_t bytes; + + // Clear VM RAM. + memset(_RAM, 0, 0x10000); + + // Create our VM. + _v6502 = vrEmu6502New(CPU_W65C02, memoryRead, memoryWrite); + + // Copy A2-3D2 into 6502 RAM. + memcpy(&_RAM[0x6000], a23d2bin, a23d2bin_len); + + // Initialize A2-3D2 so we can use the "fast entry point" (NXTPT) when rendering. + bytes = A23D2_TEST_DATABASE; + _RAM[bytes++] = SCRSZ; // Screen size. 256x240. Center is 0,0. We're going to scale this up. + _RAM[bytes++] = 255; // Scales up to 320. + _RAM[bytes++] = 233; // Scales up to 193 (leaves 46 pixels for a control panel). + _RAM[bytes++] = 0; + _RAM[bytes++] = 0; + _RAM[bytes++] = END; // Setup complete! + jsr(A23D2_ENTRYN); + + // Generate scene database. + landscape(); + + // Set up drawlist. + _drawlistInDatabase = DATABASE + 1; + _RAM[DRAWLIST_P0] = END; + + // Set up camera. + _camera = (cameraT *)&_RAM[DATABASE + 4]; + _camera->x = 10600; + _camera->y = PLANE_HEIGHT; + _camera->z = 10500; + _camera->p = 0; + _camera->h = 0; +} + + +void a23d2Render(void) { + // Update drawlist. + _RAM[_drawlistInDatabase + 0] = LOW_BYTE(DRAWLIST_P0); + _RAM[_drawlistInDatabase + 1] = HIGH_BYTE(DRAWLIST_P0); + + // Set IBP. + _RAM[A23D2_IBP + 0] = LOW_BYTE(DATABASE); + _RAM[A23D2_IBP + 1] = HIGH_BYTE(DATABASE); + + // Render. + jsr(A23D2_NXTPT); +} + + +void a23d2Shutdown(void) { + vrEmu6502Destroy(_v6502); + _v6502 = NULL; +} + + +void a23d2Sin(void) { + // Map 0-359 into 0-255. + _tdata = _tdata % 359; + _x1 = (360/256) * _tdata; + + // Call COSEX. + _RAM[A23D2_TDATA] = _x1; + jsr(A23D2_SINEX); + + // Convert to float. + _trig = (float)(_RAM[A23D2_TDATA] + _RAM[A23D2_TDATA + 1] * 256) / 32768; +} + + +void jsr(uint16_t addr) { + int32_t depth = 0; + //int32_t instructions = 0; + uint16_t PC = addr; + + vrEmu6502SetPC(_v6502, PC); + + while (true) { + // Did we execute an instruction? + if (PC != vrEmu6502GetPC(_v6502)) { + PC = vrEmu6502GetPC(_v6502); + //instructions++; + // Track JSRs & RTSs. + if (vrEmu6502GetCurrentOpcode(_v6502) == 0x20) depth++; + if (vrEmu6502GetCurrentOpcode(_v6502) == 0x60) { + depth--; + if (depth < 0) break; + } + } + // Step. + vrEmu6502Tick(_v6502); + } + + //printf("%x = %d instructions\n", addr, instructions); +} + + +void landscape(void) { + int32_t i; + int32_t x; + int32_t z; + int32_t w; + int32_t l; + int32_t min = 0; + int32_t max = 30000; // A mile is 5280. + int32_t lines = 10; + int32_t skip = (abs(min) + abs(max)) / lines; + byte *db = _RAM; + uint16_t bytes = DATABASE; + + + // All scene databases need to begin with the ARRAY and EYE records. + // The CLPSW clipping setting is up to you. :-) + + db[bytes++] = ARRAY; // Will be filled in by the program. + db[bytes++] = 0; + db[bytes++] = 0; + + db[bytes++] = EYE; // Will be filled in by the program. + db[bytes++] = 0x00; // X + db[bytes++] = 0x00; + db[bytes++] = 0x00; // Y + db[bytes++] = 0x00; + db[bytes++] = 0x00; // Z + db[bytes++] = 0x00; + db[bytes++] = 0x00; // P + db[bytes++] = 0x00; // B + db[bytes++] = 0x00; // H + + db[bytes++] = CLPSW; + db[bytes++] = 0x00; + + // Landscape + + db[bytes++] = STCOL; + db[bytes++] = 2; // Green + + for (i=min; i<=max; i+=skip) { + db[bytes++] = SPNT; + db[bytes++] = LOW_BYTE(i); // X + db[bytes++] = HIGH_BYTE(i); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(min); // Z + db[bytes++] = HIGH_BYTE(min); + + db[bytes++] = CPNT; + db[bytes++] = LOW_BYTE(i); // X + db[bytes++] = HIGH_BYTE(i); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(max); // Z + db[bytes++] = HIGH_BYTE(max); + + db[bytes++] = SPNT; + db[bytes++] = LOW_BYTE(min); // X + db[bytes++] = HIGH_BYTE(min); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(i); // Z + db[bytes++] = HIGH_BYTE(i); + + db[bytes++] = CPNT; + db[bytes++] = LOW_BYTE(max); // X + db[bytes++] = HIGH_BYTE(max); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(i); // Z + db[bytes++] = HIGH_BYTE(i); + } + + // Runway - 3000' x 200' + w = 200; + l = 3000; + x = skip * 3.5; + z = skip * 3.5; + printf("%dx%d\n", x, z); + + db[bytes++] = STCOL; + db[bytes++] = 7; // Light Grey + + db[bytes++] = SPNT; + db[bytes++] = LOW_BYTE(x); // X + db[bytes++] = HIGH_BYTE(x); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(z); // Z + db[bytes++] = HIGH_BYTE(z); + + db[bytes++] = CPNT; + db[bytes++] = LOW_BYTE(x+w); // X + db[bytes++] = HIGH_BYTE(x+w); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(z); // Z + db[bytes++] = HIGH_BYTE(z); + + db[bytes++] = CPNT; + db[bytes++] = LOW_BYTE(x+w); // X + db[bytes++] = HIGH_BYTE(x+w); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(z+l); // Z + db[bytes++] = HIGH_BYTE(z+l); + + db[bytes++] = CPNT; + db[bytes++] = LOW_BYTE(x); // X + db[bytes++] = HIGH_BYTE(x); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(z+l); // Z + db[bytes++] = HIGH_BYTE(z+l); + + db[bytes++] = CPNT; + db[bytes++] = LOW_BYTE(x); // X + db[bytes++] = HIGH_BYTE(x); + db[bytes++] = 0; // Y + db[bytes++] = 0; + db[bytes++] = LOW_BYTE(z); // Z + db[bytes++] = HIGH_BYTE(z); + + db[bytes++] = STCOL; + db[bytes++] = 15; // White + + skip = l / (lines * 2); + x += (w / 2); + for (i=z + skip; i +#include + +#include "bitmap.h" + + +byte _ega[16][3] = { + { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0xaa }, + { 0x00, 0xaa, 0x00 }, + { 0x00, 0xaa, 0xaa }, + { 0xaa, 0x00, 0x00 }, + { 0xaa, 0x00, 0xaa }, + { 0xaa, 0x55, 0x00 }, + { 0xaa, 0xaa, 0xaa }, + { 0x55, 0x55, 0x55 }, + { 0x55, 0x55, 0xff }, + { 0x55, 0xff, 0x55 }, + { 0x55, 0xff, 0xff }, + { 0xff, 0x55, 0x55 }, + { 0xff, 0x55, 0xff }, + { 0xff, 0xff, 0x55 }, + { 0xff, 0xff, 0xff } +}; +byte *_pixels = NULL; +ColorT _color; + + +void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { + uint16_t x; + uint16_t y; + int16_t dx; + int16_t dy; + int16_t incX; + int16_t incY; + int16_t balance; + + if (x2 >= x1) { + dx = x2 - x1; + incX = 1; + } else { + dx = x1 - x2; + incX = -1; + } + + if (y2 >= y1) { + dy = y2 - y1; + incY = 1; + } else { + dy = y1 - y2; + incY = -1; + } + + x = x1; + y = y1; + + if (dx >= dy) { + dy <<= 1; + balance = dy - dx; + dx <<= 1; + while (x != x2) { + bitmapPutPixelIOSet(x, y); + if (balance >= 0) { + y += incY; + balance -= dx; + } + balance += dy; + x += incX; + } + bitmapPutPixelIOSet(x, y); + } else { + dx <<= 1; + balance = dx - dy; + dy <<= 1; + while (y != y2) { + bitmapPutPixelIOSet(x, y); + if (balance >= 0) { + x += incX; + balance -= dy; + } + balance += dx; + y += incY; + } + bitmapPutPixelIOSet(x, y); + } +} + + +void colorSet(byte ega) { + _color.r = _ega[ega][0]; + _color.g = _ega[ega][1]; + _color.b = _ega[ega][2]; +} diff --git a/pc/src/flight.c b/pc/src/flight.c index da027b7..c607472 100644 --- a/pc/src/flight.c +++ b/pc/src/flight.c @@ -22,6 +22,7 @@ #include "flight.h" +#include "a23d2.h" airplaneT _plane; @@ -35,12 +36,10 @@ airplaneT _plane; #define Rads(d) (((d) < 0 ? (d) + 360 : (d)) * (PI / 180)) #define Degs(r) ((r) * (180 / PI)) -// https://www.reddit.com/r/programming/comments/3e7ghi/discrete_arctan_in_6502/ -#define ATAN_SPLINE_C0 (double)(-0.14380550980765507115) /* 3pi/4 - 5/2 */ -#define ATAN_SPLINE_C1 (double)(-0.07079632679489661923) /* 3/2 - pi/2 */ +// https://www.reddit.com/r/programming/comments/3e7ghi/discrete_arctan_in_6502 +#define ATAN_SPLINE_C0 (double)(-0.14380550980765507115) // 3pi/4 - 5/2 +#define ATAN_SPLINE_C1 (double)(-0.07079632679489661923) // 3/2 - pi/2 double ourAtan(double x){ - return atan(x); -/* if (x >= 0) { if ( x<= 1) { return x + (ATAN_SPLINE_C0 + ATAN_SPLINE_C1 * x) * x * x; @@ -56,17 +55,28 @@ double ourAtan(double x){ return (x + (ATAN_SPLINE_C0 + ATAN_SPLINE_C1 * x) * x * x) - PI / 2; } } -*/ } float cosD(float d) { return cos(Rads(d)); + /* + // Map 0-359 into 0-255. + _tdata = (int)d % 359; + a23d2Cos(); + return _trig; + */ } float sinD(float d) { return sin(Rads(d)); + /* + // Map 0-359 into 0-255. + _tdata = (int)d % 359; + a23d2Sin(); + return _trig; + */ } diff --git a/pc/src/main.c b/pc/src/main.c index deb47c8..8d492e4 100644 --- a/pc/src/main.c +++ b/pc/src/main.c @@ -21,11 +21,10 @@ */ -#include "vrEmu6502.h" -#include "a23d2bin.h" #include "a23d2.h" #include "flight.h" #include "util.h" +#include "bitmap.h" #define APP_IMPLEMENTATION @@ -42,9 +41,6 @@ #include "sysfont.h" -#define HEIGHT 240 -#define WIDTH 320 -#define SCALE 1.25 // Scale factor for 256->320 #define DEG2CAM 0.711111111 #define CAM2DEG 1.40625 @@ -58,381 +54,20 @@ #define JOY_BUTTON_3 64 -typedef struct ColorS { - byte r; - byte g; - byte b; -} ColorT; - // Foenix Stuff. byte _gamepad; -// Graphics Stuff. -byte _ega[16][3] = { - { 0x00, 0x00, 0x00 }, - { 0x00, 0x00, 0xaa }, - { 0x00, 0xaa, 0x00 }, - { 0x00, 0xaa, 0xaa }, - { 0xaa, 0x00, 0x00 }, - { 0xaa, 0x00, 0xaa }, - { 0xaa, 0x55, 0x00 }, - { 0xaa, 0xaa, 0xaa }, - { 0x55, 0x55, 0x55 }, - { 0x55, 0x55, 0xff }, - { 0x55, 0xff, 0x55 }, - { 0x55, 0xff, 0xff }, - { 0xff, 0x55, 0x55 }, - { 0xff, 0x55, 0xff }, - { 0xff, 0xff, 0x55 }, - { 0xff, 0xff, 0xff } -}; -byte *_pixels = NULL; -ColorT _color; - -// Emulator Stuff. -byte _RAM[0x10000]; // 6502 memory. -VrEmu6502 *_v6502 = NULL; - // A2-3D2 Stuff. volatile cameraT *_camera; -uint16_t _drawlistInDatabase; + +// External. +void a23d2Shutdown(void); -#define LOW_BYTE(x) ((uint8_t)(x)) -#define HIGH_BYTE(x) ((uint8_t)(((uint16_t)(x)) >> 8)) - -// ***FIX*** Somehow we're getting invalid drawing coordinates from A2-3D2. -#define bitmapPutPixelIOSet(x,y) \ - ({ \ - if ((x < WIDTH) && (y < HEIGHT)) { \ - byte *p = _pixels + ((x) * 4 + ((y) * WIDTH * 4)); \ - *p++ = _color.r; \ - *p++ = _color.g; \ - *p++ = _color.b; \ - *p++ = 255; \ - } else { \ - printf("CLIPPED!\n"); \ - fflush(0); \ - } \ - }) - - -void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); -void colorSet(byte ega); -void draw(void); -void jsr(uint16_t addr); -void landscape(void); -byte memoryRead(uint16_t addr, bool isDebug); -void memoryWrite(uint16_t addr, byte value); void printAt(uint8_t x, uint8_t y, char *format, ...); int appMain(app_t *app, void *userData); -void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { - uint16_t x; - uint16_t y; - int16_t dx; - int16_t dy; - int16_t incX; - int16_t incY; - int16_t balance; - - if (x2 >= x1) { - dx = x2 - x1; - incX = 1; - } else { - dx = x1 - x2; - incX = -1; - } - - if (y2 >= y1) { - dy = y2 - y1; - incY = 1; - } else { - dy = y1 - y2; - incY = -1; - } - - x = x1; - y = y1; - - if (dx >= dy) { - dy <<= 1; - balance = dy - dx; - dx <<= 1; - while (x != x2) { - bitmapPutPixelIOSet(x, y); - if (balance >= 0) { - y += incY; - balance -= dx; - } - balance += dy; - x += incX; - } - bitmapPutPixelIOSet(x, y); - } else { - dx <<= 1; - balance = dx - dy; - dy <<= 1; - while (y != y2) { - bitmapPutPixelIOSet(x, y); - if (balance >= 0) { - x += incX; - balance -= dy; - } - balance += dx; - y += incY; - } - bitmapPutPixelIOSet(x, y); - } -} - - -void colorSet(byte ega) { - _color.r = _ega[ega][0]; - _color.g = _ega[ega][1]; - _color.b = _ega[ega][2]; -} - - -void draw(void) { - uint16_t pointer = DRAWLIST_P0; - int16_t x1; - int16_t y1; - int16_t x2; - int16_t y2; - - while (true) { - switch (_RAM[pointer++]) { - - // Line. - case LIN2D: - x1 = (int8_t)_RAM[pointer++] + 128; - y1 = 255 - ((int8_t)_RAM[pointer++] + 128); - x2 = (int8_t)_RAM[pointer++] + 128; - y2 = 255 - ((int8_t)_RAM[pointer++] + 128); - bitmapLine(x1 * SCALE, y1 / SCALE, x2 * SCALE, y2 / SCALE); - continue; - - // Point. - case PNT2D: - x1 = (int8_t)_RAM[pointer++] + 128; - y1 = 255 - ((int8_t)_RAM[pointer++] + 128); - x1 *= SCALE; - y1 /= SCALE; - bitmapPutPixelIOSet(x1, y1); - continue; - - // Set Color. - case STCOL: - x1 = _RAM[pointer++]; - colorSet(x1); - continue; - - // Set Resolution. - case SRES: - // Eat this byte. We don't need it. - pointer++; - continue; - - // End. - case END: - break; - - } - break; - } -} - - -void jsr(uint16_t addr) { - int32_t depth = 0; -// int32_t instructions = 0; - uint16_t PC = addr; - - vrEmu6502SetPC(_v6502, PC); - - while (true) { - // Did we execute an instruction? - if (PC != vrEmu6502GetPC(_v6502)) { - PC = vrEmu6502GetPC(_v6502); -// instructions++; - // Track JSRs & RTSs. - if (vrEmu6502GetCurrentOpcode(_v6502) == 0x20) depth++; - if (vrEmu6502GetCurrentOpcode(_v6502) == 0x60) { - depth--; - if (depth < 0) break; - } - } - // Step. - vrEmu6502Tick(_v6502); - } - - //printf("%x = %d instructions\n", addr, instructions); -} - - -void landscape(void) { - int32_t i; - int32_t x; - int32_t z; - int32_t w; - int32_t l; - int32_t min = 0; - int32_t max = 30000; // A mile is 5280. - int32_t lines = 10; - int32_t skip = (abs(min) + abs(max)) / lines; - byte *db = _RAM; - uint16_t bytes = DATABASE; - - - // All scene databases need to begin with the ARRAY and EYE records. - // The CLPSW clipping setting is up to you. :-) - - db[bytes++] = ARRAY; // Will be filled in by the program. - db[bytes++] = 0; - db[bytes++] = 0; - - db[bytes++] = EYE; // Will be filled in by the program. - db[bytes++] = 0x00; // X - db[bytes++] = 0x00; - db[bytes++] = 0x00; // Y - db[bytes++] = 0x00; - db[bytes++] = 0x00; // Z - db[bytes++] = 0x00; - db[bytes++] = 0x00; // P - db[bytes++] = 0x00; // B - db[bytes++] = 0x00; // H - - db[bytes++] = CLPSW; - db[bytes++] = 0x00; - - // Landscape - - db[bytes++] = STCOL; - db[bytes++] = 2; // Green - - for (i=min; i<=max; i+=skip) { - db[bytes++] = SPNT; - db[bytes++] = LOW_BYTE(i); // X - db[bytes++] = HIGH_BYTE(i); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(min); // Z - db[bytes++] = HIGH_BYTE(min); - - db[bytes++] = CPNT; - db[bytes++] = LOW_BYTE(i); // X - db[bytes++] = HIGH_BYTE(i); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(max); // Z - db[bytes++] = HIGH_BYTE(max); - - db[bytes++] = SPNT; - db[bytes++] = LOW_BYTE(min); // X - db[bytes++] = HIGH_BYTE(min); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(i); // Z - db[bytes++] = HIGH_BYTE(i); - - db[bytes++] = CPNT; - db[bytes++] = LOW_BYTE(max); // X - db[bytes++] = HIGH_BYTE(max); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(i); // Z - db[bytes++] = HIGH_BYTE(i); - } - - // Runway - 3000' x 200' - w = 200; - l = 3000; - x = skip * 3.5; - z = skip * 3.5; - printf("%dx%d\n", x, z); - - db[bytes++] = STCOL; - db[bytes++] = 7; // Light Grey - - db[bytes++] = SPNT; - db[bytes++] = LOW_BYTE(x); // X - db[bytes++] = HIGH_BYTE(x); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(z); // Z - db[bytes++] = HIGH_BYTE(z); - - db[bytes++] = CPNT; - db[bytes++] = LOW_BYTE(x+w); // X - db[bytes++] = HIGH_BYTE(x+w); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(z); // Z - db[bytes++] = HIGH_BYTE(z); - - db[bytes++] = CPNT; - db[bytes++] = LOW_BYTE(x+w); // X - db[bytes++] = HIGH_BYTE(x+w); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(z+l); // Z - db[bytes++] = HIGH_BYTE(z+l); - - db[bytes++] = CPNT; - db[bytes++] = LOW_BYTE(x); // X - db[bytes++] = HIGH_BYTE(x); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(z+l); // Z - db[bytes++] = HIGH_BYTE(z+l); - - db[bytes++] = CPNT; - db[bytes++] = LOW_BYTE(x); // X - db[bytes++] = HIGH_BYTE(x); - db[bytes++] = 0; // Y - db[bytes++] = 0; - db[bytes++] = LOW_BYTE(z); // Z - db[bytes++] = HIGH_BYTE(z); - - db[bytes++] = STCOL; - db[bytes++] = 15; // White - - skip = l / (lines * 2); - x += (w / 2); - for (i=z + skip; ix = 10600; - _camera->y = PLANE_HEIGHT; - _camera->z = 10500; - _camera->p = 0; - _camera->h = 0; - // Set up render surface. _pixels = (byte *)malloc(HEIGHT * WIDTH * 4); + // Start up 3D engine. + a23d2Init(); + // Build a plane! resetAircraft(); _plane.x = _camera->x; @@ -523,17 +127,8 @@ int appMain(app_t *app, void *userData) { // Clear screen. memset(_pixels, 0, HEIGHT * WIDTH * 4); - // Update drawlist. - _RAM[_drawlistInDatabase + 1] = HIGH_BYTE(DRAWLIST_P0); - _RAM[_drawlistInDatabase + 0] = LOW_BYTE(DRAWLIST_P0); - - // Set IBP. - _RAM[A23D2_IBP + 1] = HIGH_BYTE(DATABASE); - _RAM[A23D2_IBP + 0] = LOW_BYTE(DATABASE); - - // Render. - jsr(A23D2_NXTPT); - draw(); + a23d2Render(); + a23d2Draw(); fps++; // Control Panel. @@ -679,8 +274,7 @@ int appMain(app_t *app, void *userData) { } // Destroy VM. - vrEmu6502Destroy(_v6502); - _v6502 = NULL; + a23d2Shutdown(); // Free render surface. free(_pixels);