From ed37f360eb6b7d075ee7f391a0bf9f77c910985c Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 11 Jan 2022 18:27:13 +0100 Subject: [PATCH] New multicolor bitmap library --- include/gfx/bitmap.c | 2 +- include/gfx/mcbitmap.c | 775 +++++++++++++++++++++++++++++++ include/gfx/mcbitmap.h | 72 +++ oscar64/NativeCodeGenerator.cpp | 58 ++- oscar64/NativeCodeGenerator.h | 1 + oscar64/oscar64.cpp | 2 +- oscar64/oscar64.rc | 8 +- oscar64setup/oscar64setup.vdproj | 173 ++++++- samples/build.sh | 4 + samples/hiresmc/build.sh | 4 + samples/hiresmc/floodfill.c | 55 +++ samples/hiresmc/func3d.c | 230 +++++++++ samples/hiresmc/make.bat | 3 + samples/hiresmc/polygon.c | 86 ++++ samples/make.bat | 4 + 15 files changed, 1467 insertions(+), 10 deletions(-) create mode 100644 include/gfx/mcbitmap.c create mode 100644 include/gfx/mcbitmap.h create mode 100644 samples/hiresmc/build.sh create mode 100644 samples/hiresmc/floodfill.c create mode 100644 samples/hiresmc/func3d.c create mode 100644 samples/hiresmc/make.bat create mode 100644 samples/hiresmc/polygon.c diff --git a/include/gfx/bitmap.c b/include/gfx/bitmap.c index b56b98d..c47219b 100644 --- a/include/gfx/bitmap.c +++ b/include/gfx/bitmap.c @@ -1074,7 +1074,7 @@ inline void bmu_rect_pattern(Bitmap * dbm, int dx, int dy, int w, int h, const c inline void bmu_rect_copy(Bitmap * dbm, int dx, int dy, Bitmap * sbm, int sx, int sy, int w, int h) { - bm_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, nullptr, BLTOP_COPY); + bmu_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, nullptr, BLTOP_COPY); } diff --git a/include/gfx/mcbitmap.c b/include/gfx/mcbitmap.c new file mode 100644 index 0000000..6572afd --- /dev/null +++ b/include/gfx/mcbitmap.c @@ -0,0 +1,775 @@ +#include "mcbitmap.h" +#include + +static char andmask[8] = {0x3f, 0x3f, 0xcf, 0xcf, 0xf3, 0xf3, 0xfc, 0xfc}; +static char ormask[8] = {0xc0, 0xc0, 0x30, 0x30, 0x0c, 0x0c, 0x03, 0x03}; +static char cbytes[4] = {0x00, 0x55, 0xaa, 0xff}; + +char MixedColors[4][4][8] = { + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44}, + {0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88}, + {0x33, 0xcc, 0x33, 0xcc, 0x33, 0xcc, 0x33, 0xcc}, + }, + { + {0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11}, + {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}, + {0x66, 0x99, 0x66, 0x99, 0x66, 0x99, 0x66, 0x99}, + {0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd}, + }, + { + {0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22}, + {0x99, 0x66, 0x99, 0x66, 0x99, 0x66, 0x99, 0x66}, + {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, + {0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee}, + }, + { + {0xcc, 0x33, 0xcc, 0x33, 0xcc, 0x33, 0xcc, 0x33}, + {0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77}, + {0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb, 0xee, 0xbb}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + }, +}; + +void bmmc_put(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 * dp = bm->data + bm->cwidth * (y & ~7) + (x & ~7) + (y & 7); + + return (*dp >> (6 - (x & 6))) & 3; +} + + + +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) +{ + int y0 = y - r, y1 = y + r + 1; + if (y0 < clip->top) + y0 = clip->top; + if (y1 > clip->bottom) + y1 = clip->bottom; + + const char * pat = pattern; + char * lp = bm->data + bm->cwidth * (y0 & ~7) + (y0 & 7); + int stride = 8 * bm->cwidth - 8; + + unsigned rr = r * r + r; + for(char iy=y0; iy<(char)y1; iy++) + { + int d = (iy - y); + + int t = bm_usqrt(rr - d * d); + + bmmc_scan_fill(clip->left, clip->right, lp, x - t, x + t + 1, pat[iy & 7]); + lp ++; + if (!((int)lp & 7)) + lp += stride; + } +} + +void bmmc_trapezoid_fill(Bitmap * bm, 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; + + long tx0 = x0, tx1 = x1; + + if (y1 > clip->bottom) + y1 = clip->bottom; + if (y0 < clip->top) + { + tx0 += (clip->top - y0) * dx0; + tx1 += (clip->top - y0) * dx1; + y0 = clip->top; + } + + const char * pat = pattern; + char * lp = bm->data + bm->cwidth * (y0 & ~7) + (y0 & 7); + int stride = 8 * bm->cwidth - 8; + + for(char iy=y0; iy<(char)y1; iy++) + { + bmmc_scan_fill(clip->left, clip->right, lp, tx0 >> 16, tx1 >> 16, pat[iy & 7]); + tx0 += dx0; + tx1 += dx1; + lp ++; + if (!((int)lp & 7)) + lp += stride; + } +} + + +void bmmc_triangle_fill(Bitmap * bm, ClipRect * clip, int x0, int y0, int x1, int y1, int x2, int y2, const char * pat) +{ + int t; + if (y1 < y0 && y1 < y2) + { + t = y0; y0 = y1; y1 = t; + t = x0; x0 = x1; x1 = t; + } + else if (y2 < y0) + { + t = y0; y0 = y2; y2 = t; + t = x0; x0 = x2; x2 = t; + } + + if (y2 < y1) + { + t = y1; y1 = y2; y2 = t; + t = x1; x1 = x2; x2 = t; + } + + if (y0 < y2) + { + long dx1, lx1; + long dx2 = ((long)(x2 - x0) << 16) / (y2 - y0); + long lx2 = (long)x0 << 16; + + if (y1 > y0) + { + dx1 = ((long)(x1 - x0) << 16) / (y1 - y0); + + if (dx1 < dx2) + bmmc_trapezoid_fill(bm, clip, lx2, lx2, dx1, dx2, y0, y1, pat); + else + bmmc_trapezoid_fill(bm, clip, lx2, lx2, dx2, dx1, y0, y1, pat); + if (y2 == y1) + return; + + lx2 += dx2 * (y1 - y0); + } + + dx1 = ((long)(x2 - x1) << 16) / (y2 - y1); + lx1 = (long)x1 << 16; + + if (lx1 < lx2) + bmmc_trapezoid_fill(bm, clip, lx1, lx2, dx1, dx2, y1, y2, pat); + else + bmmc_trapezoid_fill(bm, clip, lx2, lx1, dx2, dx1, y1, y2, pat); + } +} + + +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) +{ + 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) +{ + char mi = 0; + int my = py[0]; + + for(char i=1; i my) + { + long dlx = (((long)px[li] << 16) - lx) / (py[li] - my); + long drx = (((long)px[ri] << 16) - rx) / (py[ri] - my); + + if (lx < rx || lx == rx && dlx < drx) + bmmc_trapezoid_fill(bm, clip, lx, rx, dlx, drx, my, ty, pat); + else + bmmc_trapezoid_fill(bm, clip, rx, lx, drx, dlx, my, ty, pat); + + lx += (ty - my) * dlx; + rx += (ty - my) * drx; + + my = ty; + + while (py[li] == my) + { + lx = (long)px[li] << 16; + if (li == 0) + li = num; + li--; + } + + while (py[ri] == my) + { + rx = (long)px[ri] << 16; + ri++; + if (ri == num) + ri = 0; + } + + ty = py[li] < py[ri] ? py[li] : py[ri]; + } + +} + +struct Edge +{ + char minY, maxY; + long px, dx; + Edge * next; +}; + +void bmmc_polygon_nc_fill(Bitmap * bm, ClipRect * clip, int * px, int * py, char num, const char * pattern) +{ + Edge * first = nullptr, * active = nullptr; + Edge * e = (Edge *)BLIT_CODE; + + char n = num; + if (n > 16) + n = 16; + + int top = clip->top, bottom = clip->bottom; + + for(char i=0; i= n) + j = 0; + + if (py[i] != py[j]) + { + if (py[i] > py[j]) + { + k = j; j = i; + } + + int minY = py[k], maxY = py[j]; + if (minY < bottom && maxY > top) + { + e->px = ((long)px[k] << 16) + 0x8000; + e->dx = (((long)px[j] << 16) - e->px) / (maxY - minY); + + if (minY < top) + { + e->px += e->dx * (top - minY); + minY = top; + } + if (maxY > bottom) + maxY = bottom; + + e->minY = minY; e->maxY = maxY; + + Edge * pp = nullptr, * pe = first; + + while (pe && minY >= pe->minY) + { + pp = pe; + pe = pe->next; + } + + e->next = pe; + if (pp) + pp->next = e; + else + first = e; + + e++; + } + } + } + + if (first) + { + char y = first->minY; + + const char * pat = pattern; + char * lp = bm->data + bm->cwidth * (y & ~7) + (y & 7); + int stride = 8 * bm->cwidth - 8; + + while (first || active) + { + while (first && first->minY == y) + { + Edge * next = first->next; + + Edge * pp = nullptr, * pe = active; + while (pe && (first->px > pe->px || first->px == pe->px && first->dx > pe->dx)) + { + pp = pe; + pe = pe->next; + } + + first->next = pe; + if (pp) + pp->next = first; + else + active = first; + + first = next; + } + + Edge * e0 = active; + while (e0) + { + Edge * e1 = e0->next; + bmmc_scan_fill(clip->left, clip->right, lp, e0->px >> 16, e1->px >> 16, pat[y & 7]); + e0 = e1->next; + } + + lp ++; + if (!((int)lp & 7)) + lp += stride; + + y++; + + // remove final edges + Edge * pp = nullptr, * pe = active; + while (pe) + { + if (pe->maxY == y) + { + if (pp) + pp->next = pe->next; + else + active = pe->next; + } + else + { + pe->px += pe->dx; + pp = pe; + } + pe = pe->next; + } + } + } +} + + +#define REG_SP 0x03 +#define REG_DP 0x05 +#define REG_PAT 0x07 +#define REG_S0 0x08 +#define REG_S1 0x09 +#define REG_D0 0x0a +#define REG_D1 0x0b + +static void mbuildline(char ly, char lx, int dx, int dy, int stride, bool left, bool up, char color) +{ + char ip = 0; + + // ylow + ip += asm_im(BLIT_CODE + ip, ASM_LDY, ly); + ip += asm_im(BLIT_CODE + ip, ASM_LDX, lx); + + // set pixel + + ip += asm_iy(BLIT_CODE + ip, ASM_LDA, REG_SP); + ip += asm_im(BLIT_CODE + ip, ASM_EOR, color); + ip += asm_zp(BLIT_CODE + ip, ASM_ORA, REG_D0); + ip += asm_im(BLIT_CODE + ip, ASM_EOR, color); + ip += asm_iy(BLIT_CODE + ip, ASM_STA, REG_SP); + + // m >= 0 + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1); + ip += asm_rl(BLIT_CODE + ip, ASM_BMI, 5 + 15 + 13); + + ip += asm_np(BLIT_CODE + ip, up ? ASM_DEY : ASM_INY); + ip += asm_im(BLIT_CODE + ip, ASM_CPY, up ? 0xff : 0x08); + ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 15); + + ip += asm_np(BLIT_CODE + ip, ASM_CLC); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP); + ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride & 0xff); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1); + ip += asm_im(BLIT_CODE + ip, ASM_ADC, stride >> 8); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1); + ip += asm_im(BLIT_CODE + ip, ASM_LDY, up ? 0x07 : 0x00); + + ip += asm_np(BLIT_CODE + ip, ASM_SEC); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP); + ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx & 0xff); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1); + ip += asm_im(BLIT_CODE + ip, ASM_SBC, dx >> 8); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1); + + // m < 0 + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1); + ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 4 + 15 + 13); + + ip += asm_zp(BLIT_CODE + ip, left ? ASM_ASL : ASM_LSR, REG_D0); + ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0); + ip += asm_rl(BLIT_CODE + ip, ASM_BCC, 15); + + ip += asm_zp(BLIT_CODE + ip, left ? ASM_ROL : ASM_ROR, REG_D0); + ip += asm_np(BLIT_CODE + ip, ASM_CLC); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP); + ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xf8 : 0x08); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_SP + 1); + ip += asm_im(BLIT_CODE + ip, ASM_ADC, left ? 0xff : 0x00); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_SP + 1); + + ip += asm_np(BLIT_CODE + ip, ASM_CLC); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP); + ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy & 0xff); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP); + ip += asm_zp(BLIT_CODE + ip, ASM_LDA, REG_DP + 1); + ip += asm_im(BLIT_CODE + ip, ASM_ADC, dy >> 8); + ip += asm_zp(BLIT_CODE + ip, ASM_STA, REG_DP + 1); + + // l -- + ip += asm_np(BLIT_CODE + ip, ASM_DEX); + ip += asm_rl(BLIT_CODE + ip, ASM_BNE, 2 - ip); + ip += asm_zp(BLIT_CODE + ip, ASM_DEC, REG_D1); + ip += asm_rl(BLIT_CODE + ip, ASM_BPL, 2 - ip); + + ip += asm_np(BLIT_CODE + ip, ASM_RTS); +} + +#pragma native(buildline) + +static inline void mcallline(byte * dst, byte bit, int m, char lh) +{ + __asm + { + lda dst + sta REG_SP + lda dst + 1 + sta REG_SP + 1 + + lda m + sta REG_DP + lda m + 1 + sta REG_DP + 1 + + lda lh + sta REG_D1 + + lda bit + sta REG_D0 + + jsr BLIT_CODE + } +} + +void bmmcu_line(Bitmap * bm, int x0, int y0, int x1, int y1, char color) +{ + x0 >>= 1; + x1 >>= 1; + + int dx = x1 - x0, dy = y1 - y0; + byte quad = 0; + if (dx < 0) + { + quad = 1; + dx = -dx; + } + if (dy < 0) + { + quad |= 2; + dy = -dy; + } + + int l; + if (dx > dy) + l = dx; + else + l = dy; + + int m = dy - dx; + dx *= 2; + dy *= 2; + + char * dp = bm->data + bm->cwidth * (y0 & ~7) + 2 * (x0 & ~3); + char bit = ormask[2 * (x0 & 3)]; + char ry = y0 & 7; + int stride = 8 * bm->cwidth; + + mbuildline(ry, (l + 1) & 0xff, dx, dy, (quad & 2) ? -stride : stride, quad & 1, quad & 2, ~cbytes[color]); + + mcallline(dp, bit, m, l >> 8); +} + + +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) +{ + int dx = x1 - x0, dy = y1 - y0; + + if (x0 < x1) + { + if (x1 < clip->left || x0 >= clip->right) + return; + + if (x0 < clip->left) + { + y0 += mmuldiv(clip->left - x0, dy, dx); + x0 = clip->left; + } + + if (x1 >= clip->right) + { + y1 -= mmuldiv(x1 + 1 - clip->right, dy, dx); + x1 = clip->right - 1; + } + } + else if (x1 < x0) + { + if (x0 < clip->left || x1 >= clip->right) + return; + + if (x1 < clip->left) + { + y1 += mmuldiv(clip->left - x1, dy, dx); + x1 = clip->left; + } + + if (x0 >= clip->right) + { + y0 -= mmuldiv(x0 + 1- clip->right, dy, dx); + x0 = clip->right - 1; + } + } + else + { + if (x0 < clip->left || x0 >= clip->right) + return; + } + + if (y0 < y1) + { + if (y1 < clip->top || y0 >= clip->bottom) + return; + + if (y0 < clip->top) + { + x0 += mmuldiv(clip->top - y0, dx, dy); + y0 = clip->top; + } + + if (y1 >= clip->bottom) + { + x1 -= mmuldiv(y1 + 1 - clip->bottom, dx, dy); + y1 = clip->bottom - 1; + } + } + else if (y1 < y0) + { + if (y0 < clip->top || y1 >= clip->bottom) + return; + + if (y1 < clip->top) + { + x1 += mmuldiv(clip->top - y1, dx, dy); + y1 = clip->top; + } + + if (y0 >= clip->bottom) + { + x0 -= mmuldiv(y0 + 1 - clip->bottom, dx, dy); + y0 = clip->bottom - 1; + } + } + else + { + if (y0 < clip->top || y0 >= clip->bottom) + return; + } + + bmmcu_line(bm, x0, y0, x1, y1, color); +} + + +void bmmcu_rect_fill(Bitmap * dbm, int dx, int dy, int w, int h, char color) +{ + int rx = (dx + w + 1) & ~1; + dx &= ~1; + + 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) +{ + int rx = (dx + w + 1) & ~1; + dx &= ~1; + + 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) +{ + int rx = (dx + w + 1) & ~1; + dx &= ~1; + sx &= ~1 + + bmu_bitblit(dbm, dx, dy, sbm, sx, sy, rx - dx, h, nullptr, BLTOP_COPY); +} + + +void bmmc_rect_fill(Bitmap * dbm, ClipRect * clip, int dx, int dy, int w, int h, char color) +{ + int rx = (dx + w + 1) & ~1; + dx &= ~1; + + 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) +{ + int rx = (dx + w + 1) & ~1; + dx &= ~1; + + 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) +{ + int rx = (dx + w + 1) & ~1; + dx &= ~1; + sx &= ~1 + + bm_bitblit(dbm, clip, dx, dy, sbm, sx, sy, rx - dx, h, nullptr, BLTOP_COPY); +} + +extern byte BLIT_CODE[16 * 14]; + +inline void bmmc_putdp(char * dp, char x, char c) +{ + dp += 2 * (x & ~3); + + *dp = (*dp & andmask[2 * (x & 3)]) | (c & ormask[2 * (x & 3)]); +} + +inline char bmmc_getdp(char * dp, char x) +{ + dp += 2 * (x & ~3); + + return (*dp >> 2 * (3 - (x & 3))) & 3; +} + +inline char bmmc_checkdp(char * dp, char x, char c) +{ + dp += 2 * (x & ~3); + + return ((*dp ^ c) & ormask[2 * (x & 3)]); +} + + +void bmmc_flood_fill(Bitmap * bm, ClipRect * clip, int x, int y, char color) +{ + char bx = (char)(x >> 1), by = (char)y; + char sp = 0; + char left = clip->left >> 1, right = clip->right >> 1; + + char * dp = bm->data + bm->cwidth * (by & ~7) + (by & 7); + + char back = cbytes[bmmc_getdp(dp, bx)]; + + color = cbytes[color]; + + BLIT_CODE[sp++] = bx; + BLIT_CODE[sp++] = by; + + while (sp > 0) + { + by = BLIT_CODE[--sp]; + bx = BLIT_CODE[--sp]; + + dp = bm->data + bm->cwidth * (by & ~7) + (by & 7); + + if (bmmc_checkdp(dp, bx, back) == 0) + { + bmmc_putdp(dp, bx, color); + + char x0 = bx; + while (x0 > left && bmmc_checkdp(dp, x0 - 1, back) == 0) + { + x0--; + bmmc_putdp(dp, x0, color); + } + + char x1 = bx; + while (x1 + 1 < right && bmmc_checkdp(dp, x1 + 1, back) == 0) + { + x1++; + bmmc_putdp(dp, x1, color); + } + + bool check = false; + if (by > clip->top) + { + dp = bm->data + bm->cwidth * ((by - 1) & ~7) + ((by - 1) & 7); + + for(bx=x0; bx<=x1; bx++) + { + if (bmmc_checkdp(dp, bx, back) == 0) + { + if (!check) + { + BLIT_CODE[sp++] = bx; + BLIT_CODE[sp++] = by - 1; + check = true; + } + } + else + check = false; + } + } + + check = false; + if (by + 1 < clip->bottom) + { + dp = bm->data + bm->cwidth * ((by + 1) & ~7) + ((by + 1) & 7); + + for(bx=x0; bx<=x1; bx++) + { + if (bmmc_checkdp(dp, bx, back) == 0) + { + if (!check) + { + BLIT_CODE[sp++] = bx; + BLIT_CODE[sp++] = by + 1; + check = true; + } + } + else + check = false; + } + } + } + } +} diff --git a/include/gfx/mcbitmap.h b/include/gfx/mcbitmap.h new file mode 100644 index 0000000..74ca877 --- /dev/null +++ b/include/gfx/mcbitmap.h @@ -0,0 +1,72 @@ +#ifndef MCBITMAP_H +#define MCBITMAP_H + +#include "bitmap.h" + + +extern char MixedColors[4][4][8]; + + +// Set a single pixel +void bmmc_put(Bitmap * bm, int x, int y, char c); + + +// Get the state of a single pixel +char bmmc_get(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); + +// 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); + + +inline void bmmc_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 bmmc_circle_fill(Bitmap * bm, 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) + +// 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); + +// 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); + + +// 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); + +// 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); + +inline void bmmcu_rect_fill(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); + +// Unclipped rectangle copy +inline void bmmcu_rect_copy(Bitmap * dbm, int dx, int dy, 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); + +// Clipped rectangle pattern fill +inline void bmmc_rect_pattern(Bitmap * dbm, 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); + + +void bmmc_flood_fill(Bitmap * bm, ClipRect * clip, int x, int y, char color); + +#pragma compile("mcbitmap.c") + +#endif diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index b36ed11..199a6b9 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -10040,6 +10040,46 @@ bool NativeCodeBasicBlock::MoveCLCLoadAddZPStoreUp(int at) return false; } +bool NativeCodeBasicBlock::ReverseLoadCommutativeOpUp(int aload, int aop) +{ + int j = aload - 1; + while (j > 0) + { + if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[aop].mAddress) + { + AsmInsType type = mIns[aop].mType; + mIns[aop] = mIns[aload]; + mIns[aop].mType = type; + mIns[aload].mType = ASMIT_NOP; + mIns[aload].mMode = ASMIM_IMPLIED; + + while (j < aop) + { + mIns[j].mLive |= LIVE_CPU_REG_A; + j++; + } + + j = aload; + while (j < aop) + { + mIns[j].mLive |= mIns[aload - 1].mLive; + j++; + } + + return true; + } + + if (mIns[j].ChangesAccu()) + return false; + if (mIns[j].ChangesZeroPage(mIns[aop].mAddress)) + return false; + + j--; + } + + return false; +} + bool NativeCodeBasicBlock::MoveLoadAddZPStoreUp(int at) { int j = at - 1; @@ -11748,7 +11788,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) NativeCodeInstruction pins = mIns[i]; mIns[i] = mIns[i + 1]; mIns[i + 1] = pins; - changed = true; +// changed = true; } } } @@ -11757,6 +11797,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) #if 1 + // reverse "sta t,lda abs,clc,adc t" to "sta t,clc,adc abs,nop" + + for (int i = 1; i + 2 < mIns.Size(); i++) + { + if (mIns[i + 2].IsCommutative() && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && (mIns[i + 1].mType == ASMIT_CLC || mIns[i + 1].mType == ASMIT_SEC) && mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode != ASMIM_ZERO_PAGE) + { + if (ReverseLoadCommutativeOpUp(i, i + 2)) + changed = true; + } + else if (mIns[i + 1].IsCommutative() && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode != ASMIM_ZERO_PAGE) + { + if (ReverseLoadCommutativeOpUp(i, i + 1)) + changed = true; + } + } + // shortcut index for (int i = 0; i + 1 < mIns.Size(); i++) diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 1d09850..a180af6 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -220,6 +220,7 @@ public: bool MoveStoreXUp(int at); bool MoveStoreHighByteDown(int at); bool MoveAddHighByteDown(int at); + bool ReverseLoadCommutativeOpUp(int aload, int aop); bool ValueForwarding(const NativeRegisterDataSet& data, bool global); diff --git a/oscar64/oscar64.cpp b/oscar64/oscar64.cpp index 4af6458..f2f5557 100644 --- a/oscar64/oscar64.cpp +++ b/oscar64/oscar64.cpp @@ -73,7 +73,7 @@ int main(int argc, const char** argv) #else strcpy(strProductName, "oscar64"); - strcpy(strProductVersion, "1.2.59"); + strcpy(strProductVersion, "1.2.61"); #ifdef __APPLE__ uint32_t length = sizeof(basePath); diff --git a/oscar64/oscar64.rc b/oscar64/oscar64.rc index 0492db4..4706fd7 100644 --- a/oscar64/oscar64.rc +++ b/oscar64/oscar64.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,2,59,0 - PRODUCTVERSION 1,2,59,0 + FILEVERSION 1,2,61,0 + PRODUCTVERSION 1,2,61,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BEGIN VALUE "CompanyName", "oscar64" VALUE "FileDescription", "oscar64 compiler" - VALUE "FileVersion", "1.2.59.0" + VALUE "FileVersion", "1.2.61.0" VALUE "InternalName", "oscar64.exe" VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "OriginalFilename", "oscar64.exe" VALUE "ProductName", "oscar64" - VALUE "ProductVersion", "1.2.59.0" + VALUE "ProductVersion", "1.2.61.0" END END BLOCK "VarFileInfo" diff --git a/oscar64setup/oscar64setup.vdproj b/oscar64setup/oscar64setup.vdproj index 5aa8d19..4b7e41a 100644 --- a/oscar64setup/oscar64setup.vdproj +++ b/oscar64setup/oscar64setup.vdproj @@ -22,6 +22,12 @@ } "Entry" { + "MsmKey" = "8:_007FA3120B09491581F435FEE187EC9F" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_035D8376B0CC41EA90DBB294D667A617" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -100,6 +106,12 @@ } "Entry" { + "MsmKey" = "8:_2C39AA436BFE4300AB4738C879E6E4F4" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_2D828D0247F144CDB0112B2AD4004C2C" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -118,6 +130,12 @@ } "Entry" { + "MsmKey" = "8:_37F135A207264D5984B4B81EC44A4337" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_38759DBF58B3475AA934C0DA70FB5B81" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -238,6 +256,12 @@ } "Entry" { + "MsmKey" = "8:_79985361F09A43299E258E1A8E5ED934" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_7A9E700FC438425580655F7C1BC07FD3" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -406,6 +430,12 @@ } "Entry" { + "MsmKey" = "8:_BC5DE43AE7DE49AAA858A5CD2B985416" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_BC6636B5CB534552BC23A19BCF4DD252" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -556,6 +586,12 @@ } "Entry" { + "MsmKey" = "8:_EF27132EAC3147A492E72EC29DD9A16D" + "OwnerKey" = "8:_UNDEFINED" + "MsmSig" = "8:_UNDEFINED" + } + "Entry" + { "MsmKey" = "8:_F06F7114D6184A03962BE1C8AA697FEF" "OwnerKey" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED" @@ -697,6 +733,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_007FA3120B09491581F435FEE187EC9F" + { + "SourcePath" = "8:..\\samples\\hiresmc\\func3d.c" + "TargetName" = "8:func3d.c" + "Tag" = "8:" + "Folder" = "8:_3E74C69B2EF64E938EA60950128C5A74" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_035D8376B0CC41EA90DBB294D667A617" { "SourcePath" = "8:..\\samples\\rasterirq\\make.bat" @@ -957,6 +1013,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2C39AA436BFE4300AB4738C879E6E4F4" + { + "SourcePath" = "8:..\\samples\\hiresmc\\polygon.c" + "TargetName" = "8:polygon.c" + "Tag" = "8:" + "Folder" = "8:_3E74C69B2EF64E938EA60950128C5A74" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2D828D0247F144CDB0112B2AD4004C2C" { "SourcePath" = "8:..\\samples\\scrolling\\tunnel.c" @@ -1017,6 +1093,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_37F135A207264D5984B4B81EC44A4337" + { + "SourcePath" = "8:..\\samples\\hiresmc\\make.bat" + "TargetName" = "8:make.bat" + "Tag" = "8:" + "Folder" = "8:_3E74C69B2EF64E938EA60950128C5A74" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_38759DBF58B3475AA934C0DA70FB5B81" { "SourcePath" = "8:..\\samples\\hires\\polygon.c" @@ -1417,6 +1513,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_79985361F09A43299E258E1A8E5ED934" + { + "SourcePath" = "8:..\\include\\gfx\\mcbitmap.c" + "TargetName" = "8:mcbitmap.c" + "Tag" = "8:" + "Folder" = "8:_E0C7A8689A4144D0842BCEDA85A07B5D" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7A9E700FC438425580655F7C1BC07FD3" { "SourcePath" = "8:..\\samples\\rasterirq\\textcrawler.c" @@ -1977,6 +2093,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BC5DE43AE7DE49AAA858A5CD2B985416" + { + "SourcePath" = "8:..\\samples\\hiresmc\\floodfill.c" + "TargetName" = "8:floodfill.c" + "Tag" = "8:" + "Folder" = "8:_3E74C69B2EF64E938EA60950128C5A74" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BC6636B5CB534552BC23A19BCF4DD252" { "SourcePath" = "8:..\\include\\c64\\sprites.c" @@ -2477,6 +2613,26 @@ "IsDependency" = "11:FALSE" "IsolateTo" = "8:" } + "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_EF27132EAC3147A492E72EC29DD9A16D" + { + "SourcePath" = "8:..\\include\\gfx\\mcbitmap.h" + "TargetName" = "8:mcbitmap.h" + "Tag" = "8:" + "Folder" = "8:_E0C7A8689A4144D0842BCEDA85A07B5D" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Vital" = "11:TRUE" + "ReadOnly" = "11:FALSE" + "Hidden" = "11:FALSE" + "System" = "11:FALSE" + "Permanent" = "11:FALSE" + "SharedLegacy" = "11:FALSE" + "PackageAs" = "3:1" + "Register" = "3:1" + "Exclude" = "11:FALSE" + "IsDependency" = "11:FALSE" + "IsolateTo" = "8:" + } "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F06F7114D6184A03962BE1C8AA697FEF" { "SourcePath" = "8:..\\samples\\scrolling\\colorram.c" @@ -2643,6 +2799,17 @@ { } } + "{9EF0B969-E518-4E46-987F-47570745A589}:_3E74C69B2EF64E938EA60950128C5A74" + { + "Name" = "8:hiresmc" + "AlwaysCreate" = "11:FALSE" + "Condition" = "8:" + "Transitive" = "11:FALSE" + "Property" = "8:_2C07A88E15EF43EE9F73E4D4B611EA5A" + "Folders" + { + } + } "{9EF0B969-E518-4E46-987F-47570745A589}:_758C6547998745659548D0656D380FEA" { "Name" = "8:resources" @@ -2820,15 +2987,15 @@ { "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:oscar64" - "ProductCode" = "8:{0FD18B45-6278-4295-B7DA-CBFDA7D59683}" - "PackageCode" = "8:{B3D48267-25AC-4439-A2FC-D86188FA21CF}" + "ProductCode" = "8:{FDB14C01-E512-47D7-AB10-6431DB1DC40B}" + "PackageCode" = "8:{8C16AAEE-9A02-4BA9-9DD9-BD5606D870F6}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE" "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.2.59" + "ProductVersion" = "8:1.2.61" "Manufacturer" = "8:oscar64" "ARPHELPTELEPHONE" = "8:" "ARPHELPLINK" = "8:" diff --git a/samples/build.sh b/samples/build.sh index eab4cb0..870b242 100644 --- a/samples/build.sh +++ b/samples/build.sh @@ -7,6 +7,10 @@ cd hires ./build.sh cd .. +cd hiresmc +./build.sh +cd .. + cd kernalio ./build.sh cd .. diff --git a/samples/hiresmc/build.sh b/samples/hiresmc/build.sh new file mode 100644 index 0000000..cb79ae9 --- /dev/null +++ b/samples/hiresmc/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh +../../bin/oscar64 func3d.c -n +../../bin/oscar64 polygon.c -n +../../bin/oscar64 floodfill.c -n diff --git a/samples/hiresmc/floodfill.c b/samples/hiresmc/floodfill.c new file mode 100644 index 0000000..33c613e --- /dev/null +++ b/samples/hiresmc/floodfill.c @@ -0,0 +1,55 @@ +#include +#include +#include +#include +#include +#include +#include + +#pragma region(main, 0x0a00, 0xc800, , , {code, data, bss, heap, stack} ) + +#define Color1 ((char *)0xc800) +#define Color2 ((char *)0xd800) +#define Hires ((char *)0xe000) + +Bitmap sbm; + +int main(void) +{ + mmap_trampoline(); + + vic_setmode(VICM_HIRES_MC, Color1, Hires); + + mmap_set(MMAP_NO_ROM); + + vic.color_back = VCOL_BLACK; + vic.color_border = VCOL_BLACK; + + memset(Color1, 0x67, 1000); + memset(Color2, 0x02, 1000); + memset(Hires, 0, 8000); + + bm_init(&sbm, Hires, 40, 25); + + ClipRect scr = { 0, 0, 320, 200 }; + + for(;;) + { + for(int i=0; i<20; i++) + { + bmmc_circle_fill(&sbm, &scr, rand() % 320, rand() % 200, 5 + rand() % 40, MixedColors[1][1]); + } + for(int i=0; i<20; i++) + { + bmmc_circle_fill(&sbm, &scr, rand() % 320, rand() % 200, 5 + rand() % 40, MixedColors[0][0]); + } + bmmc_flood_fill(&sbm, &scr, 210, 100, 2); + bmmc_flood_fill(&sbm, &scr, 60, 140, 3); + } + + mmap_set(MMAP_ROM); + + getch(); + + return 0; +} diff --git a/samples/hiresmc/func3d.c b/samples/hiresmc/func3d.c new file mode 100644 index 0000000..4d0af57 --- /dev/null +++ b/samples/hiresmc/func3d.c @@ -0,0 +1,230 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma region(main, 0x0a00, 0xc800, , , {code, data, bss, heap, stack} ) + + +#define Color1 ((char *)0xc800) +#define Color2 ((char *)0xd800) +#define Hires ((char *)0xe000) + +Bitmap Screen = { + Hires, nullptr, 40, 25, 320 +}; + +ClipRect SRect = { + 0, 0, 320, 200 +} + + +Matrix4 wmat, pmat, tmat, rmat; +Vector3 vlight; + + +void init(void) +{ + mmap_set(MMAP_NO_BASIC); + + vic_setmode(VICM_HIRES_MC, Color1, Hires); + + vic.color_back = VCOL_DARK_GREY; + vic.color_border = VCOL_DARK_GREY; + + mmap_trampoline(); + mmap_set(MMAP_NO_ROM); + + memset(Color1, 0xcf, 1000); + memset(Color2, 0x01, 1000); + memset(Hires, 0, 8000); +} + +void restore(void) +{ + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); + mmap_set(MMAP_ROM); +} + +struct Point +{ + int x, y; +}; + +#define HALF 15 +#define FULL (HALF + HALF) +#define SIZE (FULL + 1) +#define QFULL (FULL * FULL) + +Vector3 v[SIZE][SIZE]; +Point p[SIZE][SIZE]; +float z[SIZE][SIZE]; + +struct Surf +{ + float z; + char x, y; +} surfs[QFULL]; + + + +void qsort(Surf * n, int s) +{ + if (s > 1) + { + Surf pn = n[0]; + int pi = 0; + for(int i=1; i pn.z) + { + n[pi] = n[i]; + pi++; + n[i] = n[pi] + } + } + n[pi] = pn; + + qsort(n, pi); + qsort(n + pi + 1, s - pi - 1); + } +} + + +int main(void) +{ + init(); + + bm_put_string(&Screen, &SRect, 0, 0, "Preparing function", BLTOP_COPY); + + mat4_ident(&wmat); + mat4_make_perspective(&pmat, 0.5 * PI, 1.0, 0.0, 200.0); + + bm_put + + for(int ix=0; ix 0) + { + c = 1 + (int)(f * 6); + if (c > 4) + patt = 0; + } + + bmmc_quad_fill(&Screen, &SRect, + p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y, + p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, + p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, + p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, + MixedColors[c >> 1][(c + 1) >> 1]); + +#if 0 + bmmc_line(&Screen, &SRect, + p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y, + p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, patt); + + bmmc_line(&Screen, &SRect, + p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, + p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt); + + bmmc_line(&Screen, &SRect, + p[iy + 0][ix + 0].x, p[iy + 0][ix + 0].y, + p[iy + 1][ix + 0].x, p[iy + 1][ix + 0].y, patt); + + bmmc_line(&Screen, &SRect, + p[iy + 0][ix + 1].x, p[iy + 0][ix + 1].y, + p[iy + 1][ix + 1].x, p[iy + 1][ix + 1].y, patt); +#endif + } + + mmap_set(MMAP_NO_BASIC); + getch(); + + restore(); + + return 0; +} \ No newline at end of file diff --git a/samples/hiresmc/make.bat b/samples/hiresmc/make.bat new file mode 100644 index 0000000..d146567 --- /dev/null +++ b/samples/hiresmc/make.bat @@ -0,0 +1,3 @@ +call ..\..\bin\oscar64 floodfill.c -n +call ..\..\bin\oscar64 polygon.c -n +call ..\..\bin\oscar64 func3d.c -n diff --git a/samples/hiresmc/polygon.c b/samples/hiresmc/polygon.c new file mode 100644 index 0000000..d023cb0 --- /dev/null +++ b/samples/hiresmc/polygon.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include +#include +#include + +#define Color1 ((char *)0xc800) +#define Color2 ((char *)0xd800) +#define Hires ((char *)0xe000) + +Bitmap Screen; + +void init(void) +{ + mmap_trampoline(); + mmap_set(MMAP_RAM); + + memset(Color1, 0x67, 1000); + memset(Color2, 0x02, 1000); + memset(Hires, 0x00, 8000); + + mmap_set(MMAP_NO_ROM); + + vic_setmode(VICM_HIRES_MC, Color1, Hires); + + vic.color_back = VCOL_BLACK; + vic.color_border = VCOL_BLACK; + + bm_init(&Screen, Hires, 40, 25); +} + +void done(void) +{ + mmap_set(MMAP_ROM); + + getch(); + + vic_setmode(VICM_TEXT, (char *)0x0400, (char *)0x1000); +} + +int main(void) +{ + init(); + + bmmcu_rect_fill(&Screen, 0, 0, 320, 200, 1); + bmmcu_rect_fill(&Screen, 8, 8, 304, 184, 2); + bmmcu_rect_fill(&Screen, 10, 10, 300, 180, 0); + + ClipRect cr = {10, 10, 310, 190}; + + float px[10], py[10]; + + for(int i=0; i<10; i++) + { + float w = i * PI / 5, c = cos(w), s = sin(w), r = (i & 1) ? 1.0 : 0.4; + px[i] = r * c; py[i] = r * s; + + } + + for(int i=0; i<128; i++) + { + int rpx[10], rpy[10]; + float r = i + 4; + float w = i * PI / 16, c = r * cos(w), s = r * sin(w), cw = r * cos(w * 2.0), sw = r * sin(w * 2.0); + + for(int j=0; j<10; j++) + { + float fx = px[j], fy = py[j]; + rpx[j] = 160 + cw + fx * c + fy * s; + rpy[j] = 100 + sw - fx * s + fy * c; + } + + bmmc_polygon_nc_fill(&Screen, &cr, rpx, rpy, 10, MixedColors[i & 3][(i >> 2) & 3]); + + for(int j=0; j<10; j++) + { + int k = (j + 1) % 10; + bmmc_line(&Screen, &cr, rpx[j], rpy[j], rpx[k], rpy[k], 0); + } + } + + done(); + + return 0; +} diff --git a/samples/make.bat b/samples/make.bat index 8dcacd5..fb4b5d1 100644 --- a/samples/make.bat +++ b/samples/make.bat @@ -6,6 +6,10 @@ cd hires call make.bat cd .. +cd hiresmc +call make.bat +cd .. + cd kernalio call make.bat cd ..