From 94efcaeca6150fc2bf3875d946fc8e4f6183d8c2 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Mon, 31 Jan 2022 08:08:18 +0100 Subject: [PATCH] Circle drawing in multicolor bitmap --- include/fixmath.c | 80 ++++- include/fixmath.h | 12 + include/gfx/bitmap.c | 56 ++-- include/gfx/bitmap.h | 56 ++-- include/gfx/mcbitmap.c | 171 +++++++++-- include/gfx/mcbitmap.h | 38 +-- include/gfx/vector3d.c | 82 +++++ include/gfx/vector3d.h | 30 ++ oscar64/InterCode.cpp | 19 +- oscar64/NativeCodeGenerator.cpp | 60 ++-- samples/games/make.bat | 1 + samples/games/missile.c | 435 +++++++++++++++++++++++++++ samples/hires/cube3d.c | 111 +------ samples/resources/missilechars.bin | Bin 0 -> 768 bytes samples/resources/missilesprites.bin | Bin 0 -> 1024 bytes 15 files changed, 935 insertions(+), 216 deletions(-) create mode 100644 samples/games/missile.c create mode 100644 samples/resources/missilechars.bin create mode 100644 samples/resources/missilesprites.bin diff --git a/include/fixmath.c b/include/fixmath.c index 651e197..edaaac6 100644 --- a/include/fixmath.c +++ b/include/fixmath.c @@ -349,10 +349,80 @@ int lmuldiv16s(int a, int b, int c) sign = !sign; } - long v = lmuldiv16u(a, b, c); + __asm + { + lda #0 + sta __tmp + 0 + sta __tmp + 1 + sta __tmp + 2 + sta __tmp + 3 - if (sign) - return -v; - else - return v; + ldx #16 + L1: lsr a + 1 + ror a + bcc W1 + clc + lda __tmp + 2 + adc b + sta __tmp + 2 + lda __tmp + 3 + adc b + 1 + sta __tmp + 3 + W1: + ror __tmp + 3 + ror __tmp + 2 + ror __tmp + 1 + ror __tmp + dex + bne L1 + + lda #0 + sta accu + sta accu + 1 + + ldx #17 + L2: + sec + lda __tmp + 2 + sbc c + tay + lda __tmp + 3 + sbc c + 1 + bcc W2 + sta __tmp + 3 + sty __tmp + 2 + W2: + rol accu + rol accu + 1 + + asl __tmp + rol __tmp + 1 + rol __tmp + 2 + rol __tmp + 3 + + dex + beq E2 + bcc L2 + + lda __tmp + 2 + sbc c + sta __tmp + 2 + lda __tmp + 3 + sbc c + 1 + sta __tmp + 3 + sec + bcs W2 + E2: + lda sign + beq E1 + + sec + lda #0 + sbc accu + sta accu + lda #0 + sbc accu + 1 + sta accu + 1 + E1: + } } diff --git a/include/fixmath.h b/include/fixmath.h index ba78710..e770547 100644 --- a/include/fixmath.h +++ b/include/fixmath.h @@ -1,28 +1,40 @@ #ifndef FIXMATH_H #define FIXMATH_H +// Multiply two unsinged 16bit numbers and return a 32bit result __native unsigned long lmul16u(unsigned x, unsigned y); +// Multiply two signed 16bit numbers and return a signed 32bit result __native long lmul16s(int x, int y) +// Multiply two 12.4 fixpoint numbers and return a 12.4 fixpoint result inline int lmul12f4s(int x, int y); +// Multiply two 8.8 fixpoint numbers and return an 8.8 fixpoint result inline int lmul8f8s(int x, int y); +// Multiply two 4.12 fixpoint numbers and return a 12.4 fixpoint result __native int lmul4f12s(int x, int y) +// Divide a 32bit unsigned number by a 16bit number and return a 16bit number __native unsigned ldiv16u(unsigned long x, unsigned y) +// Divide a signed 32bit number by a signed 16bit number and return a signed 16bit number __native int ldiv16s(long x, int y) +// Divide a 12.4 fixed point number by a 12.4 fixpoint number inline int ldiv12f4s(int x, int y) +// Divide a 8.8 fixed point number by an 8.8 fixpoint number inline int ldiv8f8s(int x, int y) +// Divide a 4.12 fixed point number by a 4.12 fixpoint number inline int ldiv4f12s(int x, int y) +// Multiply two unsigned 16bit numbers and divide the result by another 16bit number a * b / c __native unsigned lmuldiv16u(unsigned a, unsigned b, unsigned c) +// Multiply two signed 16bit numbers and divide the result by another signed 16bit number a * b / c __native int lmuldiv16s(int a, int b, int c) #pragma compile("fixmath.c") diff --git a/include/gfx/bitmap.c b/include/gfx/bitmap.c index c135e21..dffa565 100644 --- a/include/gfx/bitmap.c +++ b/include/gfx/bitmap.c @@ -28,34 +28,34 @@ void bm_free(Bitmap * bm) free(bm->rdata); } -void bm_fill(Bitmap * bm, char data) +void bm_fill(const Bitmap * bm, char data) { memset(bm->data, data, bm->cwidth * bm->cheight * 8); } -void bm_set(Bitmap * bm, int x, int y) +void bm_set(const Bitmap * bm, int x, int y) { bm->data[bm->cwidth * (y & ~7) + (x & ~7) + (y & 7)] |= 0x80 >> (x & 7); } #pragma native(bm_set) -void bm_clr(Bitmap * bm, int x, int y) +void bm_clr(const Bitmap * bm, int x, int y) { bm->data[bm->cwidth * (y & ~7) + (x & ~7) + (y & 7)] &= ~(0x80 >> (x & 7)); } #pragma native(bm_clr) -bool bm_get(Bitmap * bm, int x, int y) +bool bm_get(const Bitmap * bm, int x, int y) { return (bm->data[bm->cwidth * (y & ~7) + (x & ~7) + (y & 7)] & (0x80 >> (x & 7))) != 0; } #pragma native(bm_get) -void bm_put(Bitmap * bm, int x, int y, bool c) +void bm_put(const Bitmap * bm, int x, int y, bool c) { char * dp = bm->data + bm->cwidth * (y & ~7) + (x & ~7) + (y & 7); char m = 0x80 >> (x & 7); @@ -155,7 +155,7 @@ unsigned bm_usqrt(unsigned n) #pragma native(bm_usqrt) -void bm_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const char * pattern) +void bm_circle_fill(const Bitmap * bm, const ClipRect * clip, int x, int y, char r, const char * pattern) { int y0 = y - r, y1 = y + r + 1; if (y0 < clip->top) @@ -181,7 +181,7 @@ void bm_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const ch } } -void bm_trapezoid_fill(Bitmap * bm, ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pattern) +void bm_trapezoid_fill(const Bitmap * bm, const ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pattern) { if (y1 <= clip->top || y0 >= clip->bottom) return; @@ -213,7 +213,7 @@ void bm_trapezoid_fill(Bitmap * bm, ClipRect * clip, long x0, long x1, long dx0, } -void bm_triangle_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat) +void bm_triangle_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat) { int t; if (y1 < y0 && y1 < y2) @@ -264,13 +264,13 @@ void bm_triangle_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int } -void bm_quad_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat) +void bm_quad_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat) { bm_triangle_fill(bm, clip, x0, y0, x1, y1, x2, y2, pat); bm_triangle_fill(bm, clip, x0, y0, x2, y2, x3, y3, pat); } -void bm_polygon_fill(Bitmap * bm, ClipRect * clip, int * px, int * py, char num, const char * pat) +void bm_polygon_fill(const Bitmap * bm, const ClipRect * clip, int * px, int * py, char num, const char * pat) { char mi = 0; int my = py[0]; @@ -348,7 +348,7 @@ struct Edge Edge * next; }; -void bm_polygon_nc_fill(Bitmap * bm, ClipRect * clip, int * px, int * py, char num, const char * pattern) +void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int * py, char num, const char * pattern) { Edge * first = nullptr, * active = nullptr; Edge * e = (Edge *)BLIT_CODE; @@ -631,7 +631,7 @@ static inline void callline(byte * dst, byte bit, int m, char lh, char pattern) } } -void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op) +void bmu_line(const Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op) { if (pattern == 0x00) { @@ -688,7 +688,7 @@ void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp callline(dp, bit, m, l >> 8, pattern); } -void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op) +void bm_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op) { int dx = x1 - x0, dy = y1 - y0; @@ -991,7 +991,7 @@ static void builddop(char shift, char w, char lmask, char rmask, BlitOp op, bool #pragma native(builddop) -void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) +void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) { int rx = dx + w; char dxh0 = dx >> 3, dxh1 = rx >> 3; @@ -1077,7 +1077,7 @@ void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int #pragma native(bmu_bitblit) -void bm_bitblit(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) +void bm_bitblit(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) { if (dx >= clip->right || dy >= clip->bottom) return; @@ -1108,50 +1108,50 @@ void bm_bitblit(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int bmu_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, pattern, op); } -inline void bmu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h) +inline void bmu_rect_fill(const Bitmap * dbm, int dx, int dy, int w, int h) { bmu_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_SET); } -inline void bmu_rect_clear(Bitmap * dbm, int dx, int dy, int w, int h) +inline void bmu_rect_clear(const Bitmap * dbm, int dx, int dy, int w, int h) { bmu_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_RESET); } -inline void bmu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern) +inline void bmu_rect_pattern(const Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern) { bmu_bitblit(dbm, dx, dy, dbm, dx, dy, w, h, pattern, BLTOP_PATTERN); } -inline void bmu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) +inline void bmu_rect_copy(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h) { bmu_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, nullptr, BLTOP_COPY); } -inline void bm_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h) +inline void bm_rect_fill(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h) { bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_SET); } -inline void bm_rect_clear(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h) +inline void bm_rect_clear(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h) { bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, w, h, nullptr, BLTOP_RESET); } -inline void bm_rect_pattern(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern) +inline void bm_rect_pattern(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, const char * pattern) { bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, w, h, pattern, BLTOP_PATTERN); } -inline void bm_rect_copy(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) +inline void bm_rect_copy(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h) { bm_bitblit(dbm, clip, dx, dy, sbm, sx, sy, w, h, nullptr, BLTOP_COPY); } static char tworks[8]; -int bmu_text(Bitmap * bm, const char * str, char len) +int bmu_text(const Bitmap * bm, const char * str, char len) { char lx = 0; int tw = 0; @@ -1292,7 +1292,7 @@ static Bitmap tbitmap = { tbuffer, nullptr, 40, 1, 320 }; -int bmu_put_chars(Bitmap * bm, int x, int y, const char * str, char len, BlitOp op) +int bmu_put_chars(const Bitmap * bm, int x, int y, const char * str, char len, BlitOp op) { int tw = bmu_text(&tbitmap, str, len); @@ -1301,7 +1301,7 @@ int bmu_put_chars(Bitmap * bm, int x, int y, const char * str, char len, BlitOp return tw; } -int bm_put_chars(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, char len, BlitOp op) +int bm_put_chars(const Bitmap * bm, const ClipRect * clip, int x, int y, const char * str, char len, BlitOp op) { int tw = 0; @@ -1364,12 +1364,12 @@ int bm_put_chars(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, c return tw; } -int bm_put_string(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, BlitOp op) +int bm_put_string(const Bitmap * bm, const ClipRect * clip, int x, int y, const char * str, BlitOp op) { return bm_put_chars(bm, clip, x, y, str, strlen(str), op); } -int bm_transform(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, Bitmap * sbm, int sx, int sy, int dxx, int dxy, int dyx, int dyy) +int bm_transform(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, const Bitmap * sbm, int sx, int sy, int dxx, int dxy, int dyx, int dyy) { long lsx = (long)sx << 16, lsy = (long)sy << 16; diff --git a/include/gfx/bitmap.h b/include/gfx/bitmap.h index fe182bc..287178a 100644 --- a/include/gfx/bitmap.h +++ b/include/gfx/bitmap.h @@ -71,100 +71,100 @@ void bm_alloc(Bitmap * bm, char cw, char ch); void bm_free(Bitmap * bm); // Fill a bitmap with the data byte -void bm_fill(Bitmap * bm, char data); +void bm_fill(const Bitmap * bm, char data); void bm_scan_fill(int left, int right, char * lp, int x0, int x1, char pat); // Fill a circle with center x/y and radius r and the 8x8 pattern pat. -void bm_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const char * pat); +void bm_circle_fill(const Bitmap * bm, const ClipRect * clip, int x, int y, char r, const char * pat); // Fill a trapezoid with horizontal top and bottom, top left is in x0, top right in x1 // dx0 and dx1 are the horizontal delta for each line. Coordinates are in 16.16 fixed point // numbers. y0 and y1 are vertical coordinates in pixel. -void bm_trapezoid_fill(Bitmap * bm, ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pat) +void bm_trapezoid_fill(const Bitmap * bm, const ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pat) // Fill a triangle with a pattern, coordinate pairs x0/y0, x1/y1 and x2/y2 are in pixel -void bm_triangle_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat); +void bm_triangle_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat); // Fill a quad with a pattern, coordinate pairs are in pixel -void bm_quad_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat); +void bm_quad_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat); // Fill a convex polygon with a pattern, coordinate pairs x[]/y[] are in pixel -void bm_polygon_fill(Bitmap * bm, ClipRect * clip, int * x, int * y, char num, const char * pat); +void bm_polygon_fill(const Bitmap * bm, const ClipRect * clip, int * x, int * y, char num, const char * pat); // Fill an arbitrary polygon with a pattern, coordinate pairs x[]/y[] are in pixel, maximum size is // sixteen vertices -void bm_polygon_nc_fill(Bitmap * bm, ClipRect * clip, int * x, int * y, char num, const char * pat); +void bm_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * x, int * y, char num, const char * pat); // Set a single pixel -inline void bm_set(Bitmap * bm, int x, int y); +inline void bm_set(const Bitmap * bm, int x, int y); // Clear a single pixel -inline void bm_clr(Bitmap * bm, int x, int y); +inline void bm_clr(const Bitmap * bm, int x, int y); // Get the state of a single pixel -inline bool bm_get(Bitmap * bm, int x, int y); +inline bool bm_get(const Bitmap * bm, int x, int y); // Set or clear a single pixel -inline void bm_put(Bitmap * bm, int x, int y, bool c); +inline void bm_put(const Bitmap * bm, int x, int y, bool c); // Draw an unclipped line using an eight bit pattern -void bmu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op); +void bmu_line(const Bitmap * bm, int x0, int y0, int x1, int y1, char pattern, LineOp op); // Draw a clipped line using an eight bit pattern -void bm_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op); +void bm_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op); // Unclipped bit blit -void bmu_bitblit(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); +void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); // Unclipped rectangle fill -inline void bmu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h); +inline void bmu_rect_fill(const Bitmap * dbm, int dx, int dy, int w, int h); // Unclipped rectangle clear -inline void bmu_rect_clear(Bitmap * dbm, int dx, int dy, int w, int h); +inline void bmu_rect_clear(const Bitmap * dbm, int dx, int dy, int w, int h); // Unclipped rectangle pattern fill -inline void bmu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern); +inline void bmu_rect_pattern(const Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern); // Unclipped rectangle copy -inline void bmu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); +inline void bmu_rect_copy(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h); // Clipped bit blit -void bm_bitblit(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); +void bm_bitblit(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op); // Clipped rectangle fill -inline void bm_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h); +inline void bm_rect_fill(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h); // Clipped rectangle clear -inline void bm_rect_clear(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h); +inline void bm_rect_clear(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h); // Clipped rectangle pattern fill -inline void bm_rect_pattern(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern); +inline void bm_rect_pattern(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, const char * pattern); // Clipped rectangle copy -inline void bm_rect_copy(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); +inline void bm_rect_copy(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h); // Unclipped text rendering -int bmu_text(Bitmap * bm, const char * str, char len); +int bmu_text(const Bitmap * bm, const char * str, char len); // Calculate size of a char range int bmu_text_size(const char * str, char len); // Unclipped text output to an arbitrary location using a bit blit -int bmu_put_chars(Bitmap * bm, int x, int y, const char * str, char len, BlitOp op); +int bmu_put_chars(const Bitmap * bm, int x, int y, const char * str, char len, BlitOp op); // Clipped text output to an arbitrary location using a bit blit -int bm_put_chars(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, char len, BlitOp op); +int bm_put_chars(const Bitmap * bm, const ClipRect * clip, int x, int y, const char * str, char len, BlitOp op); // Clipped text output of a zero terminated string to an arbitrary location using a bit blit -inline int bm_put_string(Bitmap * bm, ClipRect * clip, int x, int y, const char * str, BlitOp op); +inline int bm_put_string(const Bitmap * bm, const ClipRect * clip, int x, int y, const char * str, BlitOp op); // Linear transformation of a source bitmap rectangle to a destination rectangle -int bm_transform(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, Bitmap * sbm, int sx, int sy, int dxx, int dxy, int dyx, int dyy); +int bm_transform(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, const Bitmap * sbm, int sx, int sy, int dxx, int dxy, int dyx, int dyy); #pragma compile("bitmap.c") diff --git a/include/gfx/mcbitmap.c b/include/gfx/mcbitmap.c index 4e90a2e..2d85eeb 100644 --- a/include/gfx/mcbitmap.c +++ b/include/gfx/mcbitmap.c @@ -32,14 +32,14 @@ char MixedColors[4][4][8] = { }, }; -void bmmc_put(Bitmap * bm, int x, int y, char c) +void bmmc_put(const Bitmap * bm, int x, int y, char c) { char * dp = bm->data + bm->cwidth * (y & ~7) + ((x & ~7) | (y & 7)); *dp = (*dp & andmask[x & 7]) | (cbytes[c & 3] & ormask[x & 7]); } -char bmmc_get(Bitmap * bm, int x, int y) +char bmmc_get(const Bitmap * bm, int x, int y) { char * dp = bm->data + bm->cwidth * (y & ~7) + (x & ~7) + (y & 7); @@ -47,13 +47,150 @@ char bmmc_get(Bitmap * bm, int x, int y) } +void bmmcu_circle(const Bitmap * bm, int x, int y, char r, char color) +{ + char * lpt = bm->data + bm->cwidth * (y & ~7) + (y & 7); + char * lpb = lpt; + int stride = 8 * bm->cwidth - 8; + char pat = ~cbytes[color & 3]; + + char rx = r, ry = 0; + int d = r / 2; + char * dp; + + while (rx > 0) + { + dp = lpt + ((x + rx) & ~7); + *dp = ((*dp ^ pat) | ormask[(x + rx) & 7]) ^ pat; + dp = lpt + ((x - rx) & ~7); + *dp = ((*dp ^ pat) | ormask[(x - rx) & 7]) ^ pat; + + dp = lpb + ((x + rx) & ~7); + *dp = ((*dp ^ pat) | ormask[(x + rx) & 7]) ^ pat; + dp = lpb + ((x - rx) & ~7); + *dp = ((*dp ^ pat) | ormask[(x - rx) & 7]) ^ pat; + + if (d >= 0) + { + ry++; + d -= ry; + lpb ++; + if (!((int)lpb & 7)) + lpb += stride; + if (!((int)lpt & 7)) + lpt -= stride; + lpt--; + } + if (d < 0) + { + rx--; + d += rx; + } + } + + dp = lpt + (x & ~7); + *dp = ((*dp ^ pat) | ormask[x & 7]) ^ pat; + dp = lpb + (x & ~7); + *dp = ((*dp ^ pat) | ormask[x & 7]) ^ pat; +} + +void bmmc_circle2(const Bitmap * bm, const ClipRect * clip, int x, int y, char r, char color) +{ + char * lpt = bm->data + bm->cwidth * (y & ~7) + (y & 7); + char * lpb = lpt; + int stride = 8 * bm->cwidth - 8; + char pat = ~cbytes[color & 3]; + + char rx = r, ry = 0; + int d = r / 2; + char * dp; + + y -= clip->top; + unsigned h = clip->bottom - clip->top; + unsigned y0 = y, y1 = y; + + while (rx > 0) + { + int x0 = x - rx, x1 = x + rx; + + bool c0 = x0 >= clip->left && x0 < clip->right; + bool c1 = x1 >= clip->left && x1 < clip->right; + + if ((unsigned)y0 < h) + { + if (c0) + { + dp = lpt + (x0 & ~7); + *dp = ((*dp ^ pat) | ormask[x0 & 7]) ^ pat; + } + if (c1) + { + dp = lpt + (x1 & ~7); + *dp = ((*dp ^ pat) | ormask[x1 & 7]) ^ pat; + } + } + + if ((unsigned)y1 < h) + { + if (c0) + { + dp = lpb + (x0 & ~7); + *dp = ((*dp ^ pat) | ormask[x0 & 7]) ^ pat; + } + if (c1) + { + dp = lpb + (x1 & ~7); + *dp = ((*dp ^ pat) | ormask[x1 & 7]) ^ pat; + } + } + + if (d >= 0) + { + ry++; y0--; y1++; + d -= ry; + lpb ++; + if (!((int)lpb & 7)) + lpb += stride; + if (!((int)lpt & 7)) + lpt -= stride; + lpt--; + } + if (d < 0) + { + rx--; + d += rx; + } + } + + if (x >= clip->left && x < clip->right) + { + if ((unsigned)y0 < h) + { + dp = lpt + (x & ~7); + *dp = ((*dp ^ pat) | ormask[x & 7]) ^ pat; + } + if ((unsigned)y1 < h) + { + dp = lpb + (x & ~7); + *dp = ((*dp ^ pat) | ormask[x & 7]) ^ pat; + } + } +} + +void bmmc_circle(const Bitmap * bm, const ClipRect * clip, int x, int y, char r, char color) +{ + if (x - r >= clip->left && x + r < clip->right && y - r >= clip->top && y + r < clip->bottom) + bmmcu_circle(bm, x, y, r, color); + else if (x - r < clip->right && x + r >= clip->left && y - r < clip->bottom && y + r >= clip->top) + bmmc_circle2(bm, clip, x, y, r, color); +} void bmmc_scan_fill(int left, int right, char * lp, int x0, int x1, char pat) { bm_scan_fill(left, right, lp, x0 & ~1, (x1 + 1) & ~1, pat); } -void bmmc_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const char * pattern) +void bmmc_circle_fill(const Bitmap * bm, const ClipRect * clip, int x, int y, char r, const char * pattern) { int y0 = y - r, y1 = y + r + 1; if (y0 < clip->top) @@ -79,7 +216,7 @@ void bmmc_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const } } -void bmmc_trapezoid_fill(Bitmap * bm, ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pattern) +void bmmc_trapezoid_fill(const Bitmap * bm, const ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pattern) { if (y1 <= clip->top || y0 >= clip->bottom) return; @@ -111,7 +248,7 @@ void bmmc_trapezoid_fill(Bitmap * bm, ClipRect * clip, long x0, long x1, long dx } -void bmmc_triangle_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat) +void bmmc_triangle_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat) { int t; if (y1 < y0 && y1 < y2) @@ -162,14 +299,14 @@ void bmmc_triangle_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, in } -void bmmc_quad_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat) +void bmmc_quad_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat) { bmmc_triangle_fill(bm, clip, x0, y0, x1, y1, x2, y2, pat); bmmc_triangle_fill(bm, clip, x0, y0, x2, y2, x3, y3, pat); } -void bmmc_polygon_fill(Bitmap * bm, ClipRect * clip, int * px, int * py, char num, const char * pat) +void bmmc_polygon_fill(const Bitmap * bm, const ClipRect * clip, int * px, int * py, char num, const char * pat) { char mi = 0; int my = py[0]; @@ -247,7 +384,7 @@ struct Edge Edge * next; }; -void bmmc_polygon_nc_fill(Bitmap * bm, ClipRect * clip, int * px, int * py, char num, const char * pattern) +void bmmc_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * px, int * py, char num, const char * pattern) { Edge * first = nullptr, * active = nullptr; Edge * e = (Edge *)BLIT_CODE; @@ -482,7 +619,7 @@ static inline void mcallline(byte * dst, byte bit, int m, char lh) } } -void bmmcu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char color) +void bmmcu_line(const Bitmap * bm, int x0, int y0, int x1, int y1, char color) { x0 >>= 1; x1 >>= 1; @@ -526,7 +663,7 @@ static int mmuldiv(int x, int mul, int div) return (int)((long)x * mul / div); } -void bmmc_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char color) +void bmmc_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, char color) { int dx = x1 - x0, dy = y1 - y0; @@ -614,7 +751,7 @@ void bmmc_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, cha } -void bmmcu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h, char color) +void bmmcu_rect_fill(const Bitmap * dbm, int dx, int dy, int w, int h, char color) { int rx = (dx + w + 1) & ~1; dx &= ~1; @@ -622,7 +759,7 @@ void bmmcu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h, char color) bmu_bitblit(dbm, dx, dy, dbm, dx, dy, rx - dx, h, MixedColors[color][color], BLTOP_PATTERN); } -void bmmcu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern) +void bmmcu_rect_pattern(const Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern) { int rx = (dx + w + 1) & ~1; dx &= ~1; @@ -630,7 +767,7 @@ void bmmcu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * bmu_bitblit(dbm, dx, dy, dbm, dx, dy, rx - dx, h, pattern, BLTOP_PATTERN); } -void bmmcu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) +void bmmcu_rect_copy(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h) { int rx = (dx + w + 1) & ~1; dx &= ~1; @@ -640,7 +777,7 @@ void bmmcu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, } -void bmmc_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, char color) +void bmmc_rect_fill(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, char color) { int rx = (dx + w + 1) & ~1; dx &= ~1; @@ -648,7 +785,7 @@ void bmmc_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, rx - dx, h, MixedColors[color][color], BLTOP_PATTERN); } -void bmmc_rect_pattern(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern) +void bmmc_rect_pattern(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, const char * pattern) { int rx = (dx + w + 1) & ~1; dx &= ~1; @@ -656,7 +793,7 @@ void bmmc_rect_pattern(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, rx - dx, h, pattern, BLTOP_PATTERN); } -void bmmc_rect_copy(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) +void bmmc_rect_copy(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h) { int rx = (dx + w + 1) & ~1; dx &= ~1; @@ -689,7 +826,7 @@ inline char bmmc_checkdp(char * dp, char x, char c) } -void bmmc_flood_fill(Bitmap * bm, ClipRect * clip, int x, int y, char color) +void bmmc_flood_fill(const Bitmap * bm, const ClipRect * clip, int x, int y, char color) { char bx = (char)(x >> 1), by = (char)y; char sp = 0; diff --git a/include/gfx/mcbitmap.h b/include/gfx/mcbitmap.h index 74ca877..804e665 100644 --- a/include/gfx/mcbitmap.h +++ b/include/gfx/mcbitmap.h @@ -8,64 +8,68 @@ extern char MixedColors[4][4][8]; // Set a single pixel -void bmmc_put(Bitmap * bm, int x, int y, char c); +void bmmc_put(const Bitmap * bm, int x, int y, char c); // Get the state of a single pixel -char bmmc_get(Bitmap * bm, int x, int y); +char bmmc_get(const Bitmap * bm, int x, int y); // Draw an unclipped line using an eight bit pattern -void bmmcu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char color); +void bmmcu_line(const Bitmap * bm, int x0, int y0, int x1, int y1, char color); // Draw a clipped line using an eight bit pattern -void bmmc_line(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, char color); +void bmmc_line(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, char color); inline void bmmc_scan_fill(int left, int right, char * lp, int x0, int x1, char pat); +void bmmcu_circle(const Bitmap * bm, int x, int y, char r, char color); + +void bmmc_circle(const Bitmap * bm, const ClipRect * clip, int x, int y, char r, char color); + // Fill a circle with center x/y and radius r and the 8x8 pattern pat. -void bmmc_circle_fill(Bitmap * bm, ClipRect * clip, int x, int y, char r, const char * pat); +void bmmc_circle_fill(const Bitmap * bm, const ClipRect * clip, int x, int y, char r, const char * pat); // Fill a trapezoid with horizontal top and bottom, top left is in x0, top right in x1 // dx0 and dx1 are the horizontal delta for each line. Coordinates are in 16.16 fixed point // numbers. y0 and y1 are vertical coordinates in pixel. -void bmmc_trapezoid_fill(Bitmap * bm, ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pat) +void bmmc_trapezoid_fill(const Bitmap * bm, const ClipRect * clip, long x0, long x1, long dx0, long dx1, int y0, int y1, const char * pat) // Fill a triangle with a pattern, coordinate pairs x0/y0, x1/y1 and x2/y2 are in pixel -void bmmc_triangle_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat); +void bmmc_triangle_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat); // Fill a quad with a pattern, coordinate pairs are in pixel -void bmmc_quad_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat); +void bmmc_quad_fill(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, const char * pat); // Fill a convex polygon with a pattern, coordinate pairs x[]/y[] are in pixel -void bmmc_polygon_fill(Bitmap * bm, ClipRect * clip, int * x, int * y, char num, const char * pat); +void bmmc_polygon_fill(const Bitmap * bm, const ClipRect * clip, int * x, int * y, char num, const char * pat); // Fill an arbitrary polygon with a pattern, coordinate pairs x[]/y[] are in pixel, maximum size is // sixteen vertices -void bmmc_polygon_nc_fill(Bitmap * bm, ClipRect * clip, int * x, int * y, char num, const char * pat); +void bmmc_polygon_nc_fill(const Bitmap * bm, const ClipRect * clip, int * x, int * y, char num, const char * pat); -inline void bmmcu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h, char color); +inline void bmmcu_rect_fill(const Bitmap * dbm, int dx, int dy, int w, int h, char color); // Unclipped rectangle pattern fill -inline void bmmcu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern); +inline void bmmcu_rect_pattern(const Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern); // Unclipped rectangle copy -inline void bmmcu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); +inline void bmmcu_rect_copy(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h); // Clipped rectangle fill -inline void bmmc_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, char color); +inline void bmmc_rect_fill(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, char color); // Clipped rectangle pattern fill -inline void bmmc_rect_pattern(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, const char * pattern); +inline void bmmc_rect_pattern(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h, const char * pattern); // Clipped rectangle copy -inline void bmmc_rect_copy(Bitmap * dbm, ClipRect * clip, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h); +inline void bmmc_rect_copy(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h); -void bmmc_flood_fill(Bitmap * bm, ClipRect * clip, int x, int y, char color); +void bmmc_flood_fill(const Bitmap * bm, const ClipRect * clip, int x, int y, char color); #pragma compile("mcbitmap.c") diff --git a/include/gfx/vector3d.c b/include/gfx/vector3d.c index 5ba7b76..3830f50 100644 --- a/include/gfx/vector3d.c +++ b/include/gfx/vector3d.c @@ -1,5 +1,6 @@ #include "vector3d.h" #include +#include void vec2_sum(Vector2 * vd, const Vector2 * v1, const Vector2 * v2) { @@ -942,3 +943,84 @@ void vec3_project(Vector3 * vd, const Matrix4 * m, const Vector3 * vs) vd->v[0] /= vd->v[2]; vd->v[1] /= vd->v[2]; } + + + +void f12mat3_ident(F12Matrix3 * m) +{ + m->m[0] = FIX12_ONE; + m->m[1] = 0; + m->m[2] = 0; + + m->m[3] = 0; + m->m[4] = FIX12_ONE; + m->m[5] = 0; + + m->m[6] = 0; + m->m[7] = 0; + m->m[8] = FIX12_ONE; +} + +void f12mat3_mmul(F12Matrix3 * md, const F12Matrix3 * ms) +{ + for(char i=0; i<3; i++) + { + char j = 3 * i; + + int m0 = lmul4f12s(md->m[i + 0], ms->m[0]) + lmul4f12s(md->m[i + 3], ms->m[1]) + lmul4f12s(md->m[i + 6], ms->m[2]); + int m3 = lmul4f12s(md->m[i + 0], ms->m[3]) + lmul4f12s(md->m[i + 3], ms->m[4]) + lmul4f12s(md->m[i + 6], ms->m[5]); + int m6 = lmul4f12s(md->m[i + 0], ms->m[6]) + lmul4f12s(md->m[i + 3], ms->m[7]) + lmul4f12s(md->m[i + 6], ms->m[8]); + + md->m[i + 0] = m0; md->m[i + 3] = m3; md->m[i + 6] = m6; + } +} + +void f12mat3_rmmul(F12Matrix3 * md, const F12Matrix3 * ms) +{ + for(char i=0; i<9; i+=3) + { + int m0 = lmul4f12s(md->m[i + 0], ms->m[0]) + lmul4f12s(md->m[i + 1], ms->m[3]) + lmul4f12s(md->m[i + 2], ms->m[6]); + int m1 = lmul4f12s(md->m[i + 0], ms->m[1]) + lmul4f12s(md->m[i + 1], ms->m[4]) + lmul4f12s(md->m[i + 2], ms->m[7]); + int m2 = lmul4f12s(md->m[i + 0], ms->m[2]) + lmul4f12s(md->m[i + 1], ms->m[5]) + lmul4f12s(md->m[i + 2], ms->m[8]); + + md->m[i + 0] = m0; md->m[i + 1] = m1; md->m[i + 2] = m2; + } +} + +void f12mat3_set_rotate_x(F12Matrix3 * m, float a) +{ + int c = (int)(FIX12_ONE * cos(a) + 0.5); + int s = (int)(FIX12_ONE * sin(a) + 0.5); + m->m[0] = FIX12_ONE; m->m[3] = 0; m->m[6] = 0; + m->m[1] = 0; m->m[4] = c; m->m[7] = s; + m->m[2] = 0; m->m[5] =-s; m->m[8] = c; +} + +void f12mat3_set_rotate_y(F12Matrix3 * m, float a) +{ + int c = (int)(FIX12_ONE * cos(a) + 0.5); + int s = (int)(FIX12_ONE * sin(a) + 0.5); + m->m[0] = c; m->m[3] = 0; m->m[6] = s; + m->m[1] = 0; m->m[4] = FIX12_ONE; m->m[7] = 0; + m->m[2] =-s; m->m[5] = 0; m->m[8] = c; +} + + +void f12mat3_set_rotate_z(F12Matrix3 * m, float a) +{ + int c = (int)(FIX12_ONE * cos(a) + 0.5); + int s = (int)(FIX12_ONE * sin(a) + 0.5); + m->m[0] = c; m->m[3] =-s; m->m[6] = 0; + m->m[1] = s; m->m[4] = c; m->m[7] = 0; + m->m[2] = 0; m->m[5] = 0; m->m[8] = FIX12_ONE; +} + +void f12vec3_mmul(F12Vector3 * vd, const F12Matrix3 * m, const F12Vector3 * vs) +{ + F12Vector3 vt; + for(char i=0; i<3; i++) + vt.v[i] = lmul4f12s(m->m[i], vs->v[0]) + lmul4f12s(m->m[3 + i], vs->v[1]) + lmul4f12s(m->m[6 + i], vs->v[2]); + *vd = vt; +} + + diff --git a/include/gfx/vector3d.h b/include/gfx/vector3d.h index ebd27da..68da27c 100644 --- a/include/gfx/vector3d.h +++ b/include/gfx/vector3d.h @@ -256,6 +256,36 @@ void mat4_set_scale(Matrix4 * m, float s); void vec3_project(Vector3 * vd, const Matrix4 * m, const Vector3 * vs); +// And now for some fixpoint math in 4.12 + +struct F12Vector3 +{ + int v[3]; +}; + +struct F12Matrix3 +{ + int m[9]; +}; + +static const int FIX12_ONE = 1 << 12; + +void f12mat3_ident(F12Matrix3 * m); + +void f12mat3_mmul(F12Matrix3 * md, const F12Matrix3 * ms); + +void f12mat3_rmmul(F12Matrix3 * md, const F12Matrix3 * ms); + +void f12mat3_set_rotate_x(F12Matrix3 * m, float a); + +void f12mat3_set_rotate_y(F12Matrix3 * m, float a); + + +void f12mat3_set_rotate_z(F12Matrix3 * m, float a); + +void f12vec3_mmul(F12Vector3 * vd, const F12Matrix3 * m, const F12Vector3 * vs); + + #pragma compile("vector3d.c") #endif diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index bb485b4..e9bfc11 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -2037,6 +2037,22 @@ void InterInstruction::FilterVarsUsage(const GrowingVariableArray& localVars, Nu providedParams += mSrc[1].mVarIndex; } } + else if (mCode == IC_ASSEMBLER) + { + for (int i = 1; i < mNumOperands; i++) + { + if (mSrc[i].mMemory == IM_LOCAL) + { + if (!providedVars[mSrc[i].mVarIndex]) + requiredVars += mSrc[i].mVarIndex; + } + else if (mSrc[i].mMemory == paramMemory) + { + if (!providedParams[mSrc[i].mVarIndex]) + requiredParams += mSrc[i].mVarIndex; + } + } + } } static void PerformTempUseForwarding(int& temp, TempForwardingTable& forwardingTable) @@ -3186,6 +3202,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI InterInstruction* lins = tvalue[ins->mSrc[i].mTemp]; if (lins->mCode == IC_LOAD && lins->mSrc[0].mTemp < 0 && lins->mSrc[0].mMemory == IM_FPARAM) { + ins->mSrc[i].mType = IT_POINTER; ins->mSrc[i].mMemory = IM_FPARAM; ins->mSrc[i].mVarIndex = lins->mSrc[0].mVarIndex; ins->mSrc[i].mIntConst = lins->mSrc[0].mIntConst; @@ -9147,7 +9164,7 @@ void InterCodeProcedure::Disassemble(FILE* file) void InterCodeProcedure::Disassemble(const char* name, bool dumpSets) { -#if 0 +#if 1 #ifdef _WIN32 FILE* file; static bool initial = true; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index e990cc1..f8f8f61 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -7825,6 +7825,17 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0) { + bool isub = false; + int ireg = ins->mSrc[0].mTemp; + AsmInsType iop = ASMIT_ADC; + + if (sins0) + { + isub = true; + ireg = sins0->mSrc[0].mTemp; + iop = ASMIT_SBC; + } + if (sins1) { if (ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == 0) @@ -7840,8 +7851,8 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const } else { - NativeCodeInstruction ainsl(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]); - NativeCodeInstruction ainsh(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1); + NativeCodeInstruction ainsl(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg]); + NativeCodeInstruction ainsh(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1); LoadValueToReg(proc, sins1, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp], &ainsl, &ainsh); } @@ -7849,77 +7860,78 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const } else if (ins->mSrc[1].mTemp < 0) { - mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + + mIns.Push(NativeCodeInstruction(isub ? ASMIT_SEC : ASMIT_CLC, ASMIM_IMPLIED)); if (ins->mSrc[1].mMemory == IM_GLOBAL) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_LOWER)); - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); // if the global variable is smaller than 256 bytes, we can safely ignore the upper byte? mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER)); #if 1 if (ins->mSrc[1].mLinkerObject->mSize < 256 || ins->mSrc[0].IsUByte()) - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_IMMEDIATE, 0)); else #endif - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); } else if (ins->mSrc[1].mMemory == IM_ABSOLUTE) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[1].mIntConst & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[1].mIntConst >> 8) & 0xff)); #if 1 if (ins->mSrc[0].IsUByte()) - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_IMMEDIATE, 0)); else #endif - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); } else if (ins->mSrc[1].mMemory == IM_PROCEDURE) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_LOWER)); - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins->mSrc[0].mIntConst, ins->mSrc[1].mLinkerObject, NCIF_UPPER)); #if 1 if (ins->mSrc[0].IsUByte()) - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_IMMEDIATE, 0)); else #endif - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); } else if (ins->mSrc[1].mMemory == IM_FPARAM) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, BC_REG_FPARAMS + ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst)); - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); if (ins->mSrc[0].IsUByte()) - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_IMMEDIATE, 0)); else - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); } } else { if (ins->mSrc[0].mTemp >= 0 || ins->mSrc[0].mIntConst != 0) - mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(isub ? ASMIT_SEC : ASMIT_CLC, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); if (ins->mSrc[0].mTemp < 0) { if (ins->mSrc[0].mIntConst) - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); } else - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); @@ -7931,9 +7943,9 @@ void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); } else if (ins->mSrc[0].IsUByte()) - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_IMMEDIATE, 0)); else - mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(iop, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ireg] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); } @@ -16231,7 +16243,13 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode block = block->BinaryOperator(iproc, this, ins, nullptr, nullptr); break; case IC_UNARY_OPERATOR: - block->UnaryOperator(iproc, this, ins); + if (i + 1 < iblock->mInstructions.Size() && ins->mOperator == IA_NEG && iblock->mInstructions[i + 1]->mCode == IC_LEA && iblock->mInstructions[i + 1]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[0].mFinal) + { + block->LoadEffectiveAddress(iproc, iblock->mInstructions[i + 1], nullptr, ins); + i++; + } + else + block->UnaryOperator(iproc, this, ins); break; case IC_CONVERSION_OPERATOR: block->NumericConversion(iproc, this, ins); diff --git a/samples/games/make.bat b/samples/games/make.bat index 5bf1843..7d20b89 100644 --- a/samples/games/make.bat +++ b/samples/games/make.bat @@ -1,3 +1,4 @@ call ..\..\bin\oscar64 snake.c call ..\..\bin\oscar64 -n lander.c call ..\..\bin\oscar64 -n maze3d.c +call ..\..\bin\oscar64 -n missile.c diff --git a/samples/games/missile.c b/samples/games/missile.c new file mode 100644 index 0000000..6417963 --- /dev/null +++ b/samples/games/missile.c @@ -0,0 +1,435 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma region(main, 0x0a00, 0xc800, , , {code, data, bss, heap, stack} ) + +const char MissileSprites[] = { +#embed "../resources/missilesprites.bin" +}; + +const char MissileChars[] = { +#embed "../resources/missilechars.bin" +}; + +#define Color1 ((char *)0xc800) +#define Color2 ((char *)0xd800) +#define Hires ((char *)0xe000) +#define Sprites ((char *)0xd000) +#define Charset ((char *)0xd800) + +int CrossX = 160, CrossY = 100; +bool CrossP = false; +char CrossDelay = 0; + +Bitmap sbm; +const ClipRect scr = { 0, 0, 320, 200 }; + +struct Explosion +{ + int x, y; + char r; + Explosion * next; +}; + +struct Missile +{ + int sx, sy, tx, ty, x, y, dx, dy; + int d; + char cnt; + Missile * next; +}; + +Explosion explosions[16]; +Explosion * efree, * eused; + +Missile missiles[8]; +Missile * mfree, * mused; + +Missile icbms[16]; +Missile * ifree, * iused; + +bool cities[6]; + + +void explosion_init(void) +{ + eused = nullptr; + efree = explosions; + for(char i=0; i<15; i++) + explosions[i].next = explosions + i + 1; + explosions[15].next = nullptr; +} + +void explosion_start(int x, int y) +{ + if (efree) + { + Explosion * e = efree; + efree = e->next; + e->next = eused; + eused = e; + + e->r = 0; + e->x = x; + e->y = y; + } +} + +void explosion_animate(void) +{ + Explosion * e = eused, * ep = nullptr; + while (e) + { + Explosion * en = e->next; + e->r++; + if (!(e->r & 3)) + { + if (e->r <= 64) + bmmc_circle(&sbm, &scr, e->x, e->y, e->r >> 2, 1); + else + bmmc_circle(&sbm, &scr, e->x, e->y, 33 - (e->r >> 2), 0); + } + if (e->r == 128) + { + if (ep) + ep->next = e->next; + else + eused = e->next; + e->next = efree; + efree = e; + } + else + ep = e; + + e = en; + } +} + +void missile_init(void) +{ + mused = nullptr; + mfree = missiles; + for(char i=0; i<7; i++) + missiles[i].next = missiles + i + 1; + missiles[7].next = nullptr; +} + +void missile_start(int sx, int sy, int tx, int ty) +{ + if (mfree) + { + Missile * m = mfree; + mfree = m->next; + m->next = mused; + mused = m; + + m->sx = sx >> 1; m->x = sx >> 1; + m->sy = sy; m->y = sy; + m->tx = tx >> 1; + m->ty = ty; + + m->dy = m->sy - m->ty; + m->dx = m->tx - m->sx; + if (m->dx < 0) + m->dx = -m->dx; + + m->d = m->dy - m->dx; + m->dx *= 2; + m->dy *= 2; + } +} + +void missile_animate(void) +{ + Missile * m = mused, * mp = nullptr; + while (m) + { + Missile * mn = m->next; + + if (m->d >= 0) + { + m->y--; + m->d -= m->dx; + } + if (m->d < 0) + { + if (m->tx < m->sx) + m->x--; + else + m->x++; + m->d += m->dy; + } + + if (bmmc_get(&sbm, m->x, m->y) == 1 || m->y == m->ty) + { + bmmcu_line(&sbm, m->sx * 2, m->sy, m->tx * 2, m->ty, 0); + explosion_start(m->x * 2, m->y); + + if (mp) + mp->next = m->next; + else + mused = m->next; + m->next = mfree; + mfree = m; + } + else + { + bmmc_put(&sbm, m->x * 2, m->y, 3); + mp = m; + } + + m = mn; + } +} + +void icbm_init(void) +{ + iused = nullptr; + ifree = icbms; + for(char i=0; i<15; i++) + icbms[i].next = icbms + i + 1; + icbms[15].next = nullptr; +} + +void icbm_start(int sx, int sy, int tx, int ty) +{ + if (ifree) + { + Missile * m = ifree; + ifree = m->next; + m->next = iused; + iused = m; + + m->sx = sx >> 1; m->x = sx >> 1; + m->sy = sy; m->y = sy; + m->tx = tx >> 1; + m->ty = ty; + m->cnt = 4; + + m->dy = m->ty - m->sy; + m->dx = m->tx - m->sx; + if (m->dx < 0) + m->dx = -m->dx; + + m->d = m->dy - m->dx; + m->dx *= 2; + m->dy *= 2; + } +} + +void icbm_animate(void) +{ + Missile * m = iused, * mp = nullptr; + while (m) + { + Missile * mn = m->next; + + m->cnt--; + + if (!m->cnt) + { + bmmc_put(&sbm, m->x * 2, m->y, 2); + + m->cnt = 4; + + if (m->d >= 0) + { + m->y++; + m->d -= m->dx; + } + if (m->d < 0) + { + if (m->tx < m->sx) + m->x--; + else + m->x++; + m->d += m->dy; + } + + if (bmmc_get(&sbm, m->x * 2, m->y) == 1 || m->y == m->ty) + { + bmmcu_line(&sbm, m->sx * 2, m->sy, m->tx * 2, m->ty, 0); + explosion_start(m->x * 2, m->y); + + if (m->y == m->ty) + { + int x = m->x * 2; + char ix; + if (x > 160) + ix = (x - 202) / 32 + 3; + else + ix = (x - 58) / 32; + cities[ix] = false; + spr_show(ix + 1, false); + } + + + if (mp) + mp->next = m->next; + else + iused = m->next; + m->next = ifree; + ifree = m; + } + else + { + bmmc_put(&sbm, m->x * 2, m->y, 1); + mp = m; + } + } + else + mp = m; + + m = mn; + } +} + +void mountains_init(void) +{ + bmmcu_rect_fill(&sbm, 0, 192, 320, 8, 3); + bmmc_quad_fill(&sbm, &scr, 0, 192, 16, 184, 32, 184, 48, 192, MixedColors[3][3]); + bmmc_quad_fill(&sbm, &scr, 136, 192, 152, 184, 176, 184, 192, 192, MixedColors[3][3]); + bmmc_quad_fill(&sbm, &scr, 272, 192, 288, 184, 304, 184, 320, 192, MixedColors[3][3]); +} + +__interrupt void joy_interrupt() +{ + joy_poll(1); + + CrossX += joyx[1]; CrossY += joyy[1]; + + if (CrossX < 8) + CrossX = 8; + else if (CrossX > 312) + CrossX = 312; + if (CrossY < 16) + CrossY = 16; + else if (CrossY > 172) + CrossY = 172; + + spr_move(0, CrossX + 14, CrossY + 40); + + if (joyb[1]) + { + if (CrossDelay == 0) + { + CrossP = true; + CrossDelay = 4; + } + } + else if (CrossDelay > 0) + CrossDelay--; +} + +RIRQCode bottom, top; + +int main(void) +{ + mmap_trampoline(); + + mmap_set(MMAP_RAM); + memcpy(Sprites, MissileSprites, 1024); + memcpy(Charset, MissileChars, 2048); + mmap_set(MMAP_NO_ROM); + + vic_setmode(VICM_HIRES_MC, Color1, Hires); + spr_init(Color1); + + // initialize raster IRQ + rirq_init(true); + + vic.color_back = VCOL_BLACK; + vic.color_border = VCOL_BLACK; + + memset(Color1, 0x18, 1000); + memset(Color2, 0x06, 1000); + memset(Hires, 0, 8000); + memset(Color2 + 40 * 23, 0x07, 80); + + bm_init(&sbm, Hires, 40, 25); + missile_init(); + explosion_init(); + icbm_init(); + mountains_init(); + + spr_set(0, true, CrossX + 14, CrossY + 40, 64, 1, false, false, false); + + for(char i=0; i<3; i++) + { + spr_set(i + 1, true, 70 + 32 * i, 222, 65, 15, false, false, false); + spr_set(i + 4, true, 214 + 32 * i, 222, 65, 15, false, false, false); + + cities[i + 0] = true; + cities[i + 3] = true; + } + + // Build the switch to normal IRQ + rirq_build(&top, 3); + // Change color for ceiling + rirq_delay(&top, 10); + rirq_write(&top, 1, &vic.ctrl1, VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3); + rirq_write(&top, 2, &vic.memptr, 0x28); + // place this at the bottom + rirq_set(0, 57, &top); + + // Build the switch to normal IRQ + rirq_build(&bottom, 3); + rirq_write(&bottom, 0, &vic.memptr, 0x27); + rirq_write(&bottom, 1, &vic.ctrl1, VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3); + // Change color for ceiling + rirq_call(&bottom, 2, joy_interrupt); + // place this at the bottom + rirq_set(1, 250, &bottom); + + // sort the raster IRQs + rirq_sort(); + + // start raster IRQ processing + rirq_start(); + + bool launched = false; + for(;;) + { + if (CrossP) + { + int sx = 160; + if (CrossX < 120) + sx = 24; + else if (CrossX > 200) + sx = 296 + missile_start(sx, 184, CrossX, CrossY); + CrossP = false; + } + + if (!(rand() & 63)) + { + char ci; + do { + ci = rand() & 7; + } while (ci >= 6 || !cities[ci]); + + int cx; + if (ci < 3) + cx = 58 + 32 * ci; + else + cx = 202 + 32 * (ci - 3); + + icbm_start((rand() & 0xff) + 32, 0, cx, 184); + } + + for(char i=0; i<4; i++) + missile_animate(); + icbm_animate(); + explosion_animate(); + + vic_waitFrame(); + } + + return 0; +} diff --git a/samples/hires/cube3d.c b/samples/hires/cube3d.c index 212cd2f..6ef119b 100644 --- a/samples/hires/cube3d.c +++ b/samples/hires/cube3d.c @@ -47,15 +47,6 @@ struct Point int x, y; }; -struct FVector3 -{ - int v[3]; -}; - -struct FMatrix3 -{ - int m[9]; -}; Point tcorners[8], pcorners[8]; @@ -88,89 +79,11 @@ void hideCube(void) #if 1 -FVector3 corners[8]; - -static const int FMOne = 1 << 12; - -void fmat3_ident(FMatrix3 * m) -{ - m->m[0] = FMOne; - m->m[1] = 0; - m->m[2] = 0; - - m->m[3] = 0; - m->m[4] = FMOne; - m->m[5] = 0; - - m->m[6] = 0; - m->m[7] = 0; - m->m[8] = FMOne; -} - -void fmat3_mmul(FMatrix3 * md, const FMatrix3 * ms) -{ - for(char i=0; i<3; i++) - { - char j = 3 * i; - - int m0 = lmul4f12s(md->m[i + 0], ms->m[0]) + lmul4f12s(md->m[i + 3], ms->m[1]) + lmul4f12s(md->m[i + 6], ms->m[2]); - int m3 = lmul4f12s(md->m[i + 0], ms->m[3]) + lmul4f12s(md->m[i + 3], ms->m[4]) + lmul4f12s(md->m[i + 6], ms->m[5]); - int m6 = lmul4f12s(md->m[i + 0], ms->m[6]) + lmul4f12s(md->m[i + 3], ms->m[7]) + lmul4f12s(md->m[i + 6], ms->m[8]); - - md->m[i + 0] = m0; md->m[i + 3] = m3; md->m[i + 6] = m6; - } -} - -void fmat3_rmmul(FMatrix3 * md, const FMatrix3 * ms) -{ - for(char i=0; i<9; i+=3) - { - int m0 = lmul4f12s(md->m[i + 0], ms->m[0]) + lmul4f12s(md->m[i + 1], ms->m[3]) + lmul4f12s(md->m[i + 2], ms->m[6]); - int m1 = lmul4f12s(md->m[i + 0], ms->m[1]) + lmul4f12s(md->m[i + 1], ms->m[4]) + lmul4f12s(md->m[i + 2], ms->m[7]); - int m2 = lmul4f12s(md->m[i + 0], ms->m[2]) + lmul4f12s(md->m[i + 1], ms->m[5]) + lmul4f12s(md->m[i + 2], ms->m[8]); - - md->m[i + 0] = m0; md->m[i + 1] = m1; md->m[i + 2] = m2; - } -} - -void fmat3_set_rotate_x(FMatrix3 * m, float a) -{ - int c = (int)(FMOne * cos(a)); - int s = (int)(FMOne * sin(a)); - m->m[0] = FMOne; m->m[3] = 0; m->m[6] = 0; - m->m[1] = 0; m->m[4] = c; m->m[7] = s; - m->m[2] = 0; m->m[5] =-s; m->m[8] = c; -} - -void fmat3_set_rotate_y(FMatrix3 * m, float a) -{ - int c = (int)(FMOne * cos(a)); - int s = (int)(FMOne * sin(a)); - m->m[0] = c; m->m[3] = 0; m->m[6] = s; - m->m[1] = 0; m->m[4] = FMOne; m->m[7] = 0; - m->m[2] =-s; m->m[5] = 0; m->m[8] = c; -} +F12Vector3 corners[8]; -void fmat3_set_rotate_z(FMatrix3 * m, float a) -{ - int c = (int)(FMOne * cos(a)); - int s = (int)(FMOne * sin(a)); - m->m[0] = c; m->m[3] =-s; m->m[6] = 0; - m->m[1] = s; m->m[4] = c; m->m[7] = 0; - m->m[2] = 0; m->m[5] = 0; m->m[8] = FMOne; -} -void fvec3_mmul(FVector3 * vd, const FMatrix3 * m, const FVector3 * vs) -{ - FVector3 vt; - for(char i=0; i<3; i++) - vt.v[i] = lmul4f12s(m->m[i], vs->v[0]) + lmul4f12s(m->m[3 + i], vs->v[1]) + lmul4f12s(m->m[6 + i], vs->v[2]); - *vd = vt; -} - - -FMatrix3 rmat, tmat; +F12Matrix3 rmat, tmat; int main(void) { @@ -178,25 +91,25 @@ int main(void) for(char i=0; i<8; i++) { - corners[i].v[0] = (i & 1) ? -FMOne : FMOne; - corners[i].v[1] = (i & 2) ? -FMOne : FMOne; - corners[i].v[2] = (i & 4) ? -FMOne : FMOne; + corners[i].v[0] = (i & 1) ? -FIX12_ONE : FIX12_ONE; + corners[i].v[1] = (i & 2) ? -FIX12_ONE : FIX12_ONE; + corners[i].v[2] = (i & 4) ? -FIX12_ONE : FIX12_ONE; } for(int k=0; k<100; k++) { - fmat3_set_rotate_x(&rmat, 0.1 * k); - fmat3_set_rotate_y(&tmat, 0.06 * k); - fmat3_mmul(&rmat, &tmat); + f12mat3_set_rotate_x(&rmat, 0.1 * k); + f12mat3_set_rotate_y(&tmat, 0.06 * k); + f12mat3_mmul(&rmat, &tmat); for(char i=0; i<8; i++) { - FVector3 vd; + F12Vector3 vd; - fvec3_mmul(&vd, &rmat, corners + i); + f12vec3_mmul(&vd, &rmat, corners + i); - tcorners[i].x = lmuldiv16s(vd.v[0], 140, vd.v[2] + 4 * FMOne) + 160; - tcorners[i].y = lmuldiv16s(vd.v[1], 140, vd.v[2] + 4 * FMOne) + 100; + tcorners[i].x = lmuldiv16s(vd.v[0], 140, vd.v[2] + 4 * FIX12_ONE) + 160; + tcorners[i].y = lmuldiv16s(vd.v[1], 140, vd.v[2] + 4 * FIX12_ONE) + 100; } hideCube(); diff --git a/samples/resources/missilechars.bin b/samples/resources/missilechars.bin new file mode 100644 index 0000000000000000000000000000000000000000..aee91fac06bf87508463413b83068ecab9330fb3 GIT binary patch literal 768 zcmX|8yNcXE5G*iEG>F4d2j;$EBC|oGyWsG5G&@iZRxBIcDG;Myx%j?nzhJ+>AX6jR zjZjnltm$%IuW@z&o<@#9#6m8@5#c~eBNd0U2@f`!832XTvey$ZoXk{@lu~j;O!Gu2 z+T-B5UMhfvR6U%e_G(?kF)s;+Aja^t0M^WG0H8MUP@DGG%R2rPc5}^BI?q7MRvNs> z9Qk`$%J~mG%N#J*K*Lj6*Ybpa)?+YD=^=9CM#4G`! zoU;|t**YB)@ngCvfp#E3iEk-e2{^Csx`UYx)!T(W>Zc5hh96~Mz{3v!$DS=# literal 0 HcmV?d00001