New multicolor bitmap library

This commit is contained in:
drmortalwombat 2022-01-11 18:27:13 +01:00
parent 55affa4de9
commit ed37f360eb
15 changed files with 1467 additions and 10 deletions

View File

@ -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) 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);
} }

775
include/gfx/mcbitmap.c Normal file
View File

@ -0,0 +1,775 @@
#include "mcbitmap.h"
#include <c64/asm6502.h>
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<num; i++)
{
if (py[i] < my)
{
my = py[i];
mi = i;
}
}
char li = mi, ri = mi;
long lx, rx;
do
{
lx = (long)px[li] << 16;
if (li == 0)
li = num;
li--;
} while(py[li] == my);
do
{
rx = (long)px[ri] << 16;
ri++;
if (ri == num)
ri = 0;
}
while (py[ri] == my);
int ty = py[li] < py[ri] ? py[li] : py[ri];
while (ty > 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; i++)
{
char j = i + 1, k = i;
if (j >= 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;
}
}
}
}
}

72
include/gfx/mcbitmap.h Normal file
View File

@ -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

View File

@ -10040,6 +10040,46 @@ bool NativeCodeBasicBlock::MoveCLCLoadAddZPStoreUp(int at)
return false; 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) bool NativeCodeBasicBlock::MoveLoadAddZPStoreUp(int at)
{ {
int j = at - 1; int j = at - 1;
@ -11748,7 +11788,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
NativeCodeInstruction pins = mIns[i]; NativeCodeInstruction pins = mIns[i];
mIns[i] = mIns[i + 1]; mIns[i] = mIns[i + 1];
mIns[i + 1] = pins; mIns[i + 1] = pins;
changed = true; // changed = true;
} }
} }
} }
@ -11757,6 +11797,22 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
#if 1 #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 // shortcut index
for (int i = 0; i + 1 < mIns.Size(); i++) for (int i = 0; i + 1 < mIns.Size(); i++)

View File

@ -220,6 +220,7 @@ public:
bool MoveStoreXUp(int at); bool MoveStoreXUp(int at);
bool MoveStoreHighByteDown(int at); bool MoveStoreHighByteDown(int at);
bool MoveAddHighByteDown(int at); bool MoveAddHighByteDown(int at);
bool ReverseLoadCommutativeOpUp(int aload, int aop);
bool ValueForwarding(const NativeRegisterDataSet& data, bool global); bool ValueForwarding(const NativeRegisterDataSet& data, bool global);

View File

@ -73,7 +73,7 @@ int main(int argc, const char** argv)
#else #else
strcpy(strProductName, "oscar64"); strcpy(strProductName, "oscar64");
strcpy(strProductVersion, "1.2.59"); strcpy(strProductVersion, "1.2.61");
#ifdef __APPLE__ #ifdef __APPLE__
uint32_t length = sizeof(basePath); uint32_t length = sizeof(basePath);

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,2,59,0 FILEVERSION 1,2,61,0
PRODUCTVERSION 1,2,59,0 PRODUCTVERSION 1,2,61,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -43,12 +43,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "oscar64" VALUE "CompanyName", "oscar64"
VALUE "FileDescription", "oscar64 compiler" VALUE "FileDescription", "oscar64 compiler"
VALUE "FileVersion", "1.2.59.0" VALUE "FileVersion", "1.2.61.0"
VALUE "InternalName", "oscar64.exe" VALUE "InternalName", "oscar64.exe"
VALUE "LegalCopyright", "Copyright (C) 2021" VALUE "LegalCopyright", "Copyright (C) 2021"
VALUE "OriginalFilename", "oscar64.exe" VALUE "OriginalFilename", "oscar64.exe"
VALUE "ProductName", "oscar64" VALUE "ProductName", "oscar64"
VALUE "ProductVersion", "1.2.59.0" VALUE "ProductVersion", "1.2.61.0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -22,6 +22,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_007FA3120B09491581F435FEE187EC9F"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_035D8376B0CC41EA90DBB294D667A617" "MsmKey" = "8:_035D8376B0CC41EA90DBB294D667A617"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -100,6 +106,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_2C39AA436BFE4300AB4738C879E6E4F4"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_2D828D0247F144CDB0112B2AD4004C2C" "MsmKey" = "8:_2D828D0247F144CDB0112B2AD4004C2C"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -118,6 +130,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_37F135A207264D5984B4B81EC44A4337"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_38759DBF58B3475AA934C0DA70FB5B81" "MsmKey" = "8:_38759DBF58B3475AA934C0DA70FB5B81"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -238,6 +256,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_79985361F09A43299E258E1A8E5ED934"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_7A9E700FC438425580655F7C1BC07FD3" "MsmKey" = "8:_7A9E700FC438425580655F7C1BC07FD3"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -406,6 +430,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_BC5DE43AE7DE49AAA858A5CD2B985416"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_BC6636B5CB534552BC23A19BCF4DD252" "MsmKey" = "8:_BC6636B5CB534552BC23A19BCF4DD252"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -556,6 +586,12 @@
} }
"Entry" "Entry"
{ {
"MsmKey" = "8:_EF27132EAC3147A492E72EC29DD9A16D"
"OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_F06F7114D6184A03962BE1C8AA697FEF" "MsmKey" = "8:_F06F7114D6184A03962BE1C8AA697FEF"
"OwnerKey" = "8:_UNDEFINED" "OwnerKey" = "8:_UNDEFINED"
"MsmSig" = "8:_UNDEFINED" "MsmSig" = "8:_UNDEFINED"
@ -697,6 +733,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_035D8376B0CC41EA90DBB294D667A617"
{ {
"SourcePath" = "8:..\\samples\\rasterirq\\make.bat" "SourcePath" = "8:..\\samples\\rasterirq\\make.bat"
@ -957,6 +1013,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_2D828D0247F144CDB0112B2AD4004C2C"
{ {
"SourcePath" = "8:..\\samples\\scrolling\\tunnel.c" "SourcePath" = "8:..\\samples\\scrolling\\tunnel.c"
@ -1017,6 +1093,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_38759DBF58B3475AA934C0DA70FB5B81"
{ {
"SourcePath" = "8:..\\samples\\hires\\polygon.c" "SourcePath" = "8:..\\samples\\hires\\polygon.c"
@ -1417,6 +1513,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_7A9E700FC438425580655F7C1BC07FD3"
{ {
"SourcePath" = "8:..\\samples\\rasterirq\\textcrawler.c" "SourcePath" = "8:..\\samples\\rasterirq\\textcrawler.c"
@ -1977,6 +2093,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_BC6636B5CB534552BC23A19BCF4DD252"
{ {
"SourcePath" = "8:..\\include\\c64\\sprites.c" "SourcePath" = "8:..\\include\\c64\\sprites.c"
@ -2477,6 +2613,26 @@
"IsDependency" = "11:FALSE" "IsDependency" = "11:FALSE"
"IsolateTo" = "8:" "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" "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_F06F7114D6184A03962BE1C8AA697FEF"
{ {
"SourcePath" = "8:..\\samples\\scrolling\\colorram.c" "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" "{9EF0B969-E518-4E46-987F-47570745A589}:_758C6547998745659548D0656D380FEA"
{ {
"Name" = "8:resources" "Name" = "8:resources"
@ -2820,15 +2987,15 @@
{ {
"Name" = "8:Microsoft Visual Studio" "Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:oscar64" "ProductName" = "8:oscar64"
"ProductCode" = "8:{0FD18B45-6278-4295-B7DA-CBFDA7D59683}" "ProductCode" = "8:{FDB14C01-E512-47D7-AB10-6431DB1DC40B}"
"PackageCode" = "8:{B3D48267-25AC-4439-A2FC-D86188FA21CF}" "PackageCode" = "8:{8C16AAEE-9A02-4BA9-9DD9-BD5606D870F6}"
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}" "UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
"AspNetVersion" = "8:2.0.50727.0" "AspNetVersion" = "8:2.0.50727.0"
"RestartWWWService" = "11:FALSE" "RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE" "RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE" "DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE" "InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.2.59" "ProductVersion" = "8:1.2.61"
"Manufacturer" = "8:oscar64" "Manufacturer" = "8:oscar64"
"ARPHELPTELEPHONE" = "8:" "ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:" "ARPHELPLINK" = "8:"

View File

@ -7,6 +7,10 @@ cd hires
./build.sh ./build.sh
cd .. cd ..
cd hiresmc
./build.sh
cd ..
cd kernalio cd kernalio
./build.sh ./build.sh
cd .. cd ..

4
samples/hiresmc/build.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/sh
../../bin/oscar64 func3d.c -n
../../bin/oscar64 polygon.c -n
../../bin/oscar64 floodfill.c -n

View File

@ -0,0 +1,55 @@
#include <c64/vic.h>
#include <c64/memmap.h>
#include <gfx/mcbitmap.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <math.h>
#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;
}

230
samples/hiresmc/func3d.c Normal file
View File

@ -0,0 +1,230 @@
#include <c64/memmap.h>
#include <c64/vic.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <math.h>
#include <gfx/vector3d.h>
#include <gfx/mcbitmap.h>
#include <stdio.h>
#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<s; i++)
{
if (n[i].z > 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<SIZE; ix++)
{
for(int iy=0; iy<SIZE; iy++)
{
float x = (ix - HALF) * (1.0 / HALF), y = (HALF - iy) * (1.0 / HALF);
float r = sqrt(x * x + y * y);
float f = - cos(r * 16) * exp(- 2 * r);
vec3_set(&(v[iy][ix]), x, f * 0.5, y);
}
}
bm_put_string(&Screen, &SRect, 0, 8, "Projecting vertices", BLTOP_COPY);
vec3_set(&vlight, 2.0, -2.0, -1.0);
vec3_norm(&vlight);
mat4_scale(&wmat, 18);
mat4_set_rotate_x(&rmat, -0.98);
mat4_set_rotate_y(&tmat, 0.3);
mat4_rmmul(&rmat, &tmat);
mat4_rmmul(&rmat, &wmat);
rmat.m[14] += 20.0;
tmat = pmat;
mat4_mmul(&tmat, &rmat);
for(int ix=0; ix<SIZE; ix++)
{
for(int iy=0; iy<SIZE; iy++)
{
Vector3 vp;
vec3_project(&vp, &tmat, &(v[iy][ix]));
p[iy][ix].x = vp.v[0] * 140 + 160;
p[iy][ix].y = vp.v[1] * 140 + 80;
z[iy][ix] = vp.v[2];
}
}
bm_put_string(&Screen, &SRect, 0, 16, "Sorting surfaces", BLTOP_COPY);
for(int iy=0; iy<FULL; iy++)
{
for(int ix=0; ix<FULL; ix++)
{
surfs[FULL * iy + ix].z =
z[iy + 0][ix + 0] +
z[iy + 0][ix + 1] +
z[iy + 1][ix + 0] +
z[iy + 1][ix + 1];
surfs[FULL * iy + ix].x = ix;
surfs[FULL * iy + ix].y = iy;
}
}
qsort(surfs, QFULL);
bm_put_string(&Screen, &SRect, 0, 24, "Drawing surfaces", BLTOP_COPY);
for(int i=0; i< QFULL; i++)
{
char ix = surfs[i].x, iy = surfs[i].y;
Vector3 d0, d1, n;
vec3_diff(&d0, &(v[iy + 0][ix + 0]), &(v[iy + 1][ix + 1]));
vec3_diff(&d1, &(v[iy + 1][ix + 0]), &(v[iy + 0][ix + 1]));
vec3_xmul(&n, &d0, &d1);
vec3_norm(&n);
float f = vec3_vmul(&vlight, &n);
int c = 0;
char patt = 3;
if (f > 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;
}

3
samples/hiresmc/make.bat Normal file
View File

@ -0,0 +1,3 @@
call ..\..\bin\oscar64 floodfill.c -n
call ..\..\bin\oscar64 polygon.c -n
call ..\..\bin\oscar64 func3d.c -n

86
samples/hiresmc/polygon.c Normal file
View File

@ -0,0 +1,86 @@
#include <c64/memmap.h>
#include <c64/vic.h>
#include <gfx/mcbitmap.h>
#include <string.h>
#include <conio.h>
#include <math.h>
#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;
}

View File

@ -6,6 +6,10 @@ cd hires
call make.bat call make.bat
cd .. cd ..
cd hiresmc
call make.bat
cd ..
cd kernalio cd kernalio
call make.bat call make.bat
cd .. cd ..