initial commit

This commit is contained in:
2026-07-18 20:34:55 +02:00
commit 59ad004c96
474 changed files with 226635 additions and 0 deletions
File diff suppressed because it is too large Load Diff
+172
View File
@@ -0,0 +1,172 @@
#ifndef BITMAP_H
#define BITMAP_H
#include <c64/types.h>
struct Bitmap
{
char * data, * rdata;
char cwidth;
char cheight;
unsigned width;
};
struct ClipRect
{
int left, top, right, bottom;
};
#define BLIT_OP 0x03
#define BLIT_AND 0x01
#define BLIT_ORA 0x02
#define BLIT_EOR 0x03
#define BLIT_IMM 0x04
#define BLIT_SRC 0x08
#define BLIT_DST 0x10
#define BLIT_PATTERN 0x20
#define BLIT_INVERT 0x40
enum BlitOp
{
BLTOP_SET = BLIT_IMM | BLIT_INVERT,
BLTOP_RESET = BLIT_IMM,
BLTOP_NOT = BLIT_DST | BLIT_IMM | BLIT_INVERT | BLIT_EOR,
BLTOP_XOR = BLIT_SRC | BLIT_DST | BLIT_EOR,
BLTOP_OR = BLIT_SRC | BLIT_DST | BLIT_ORA,
BLTOP_AND = BLIT_SRC | BLIT_DST | BLIT_AND,
BLTOP_AND_NOT = BLIT_SRC | BLIT_DST | BLIT_INVERT | BLIT_AND,
BLTOP_COPY = BLIT_SRC,
BLTOP_NCOPY = BLIT_SRC | BLIT_INVERT,
BLTOP_PATTERN = BLIT_PATTERN,
BLTOP_PATTERN_AND_SRC = BLIT_SRC | BLIT_PATTERN | BLIT_AND
};
enum LineOp
{
LINOP_SET,
LINOP_OR,
LINOP_AND,
LINOP_XOR
};
extern char NineShadesOfGrey[9][8];
// Fast unsigned integer square root
unsigned bm_usqrt(unsigned n);
// Initialize a bitmap structure, size is given in char cells (8x8 pixel)
void bm_init(Bitmap * bm, char * data, char cw, char ch);
// Initialize a bitmap structure with allocated memory, size is given in char cells (8x8 pixel)
void bm_alloc(Bitmap * bm, char cw, char ch);
// Free the memory of a bitmap
void bm_free(Bitmap * bm);
// Fill a bitmap with the data byte
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(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(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(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(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(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(const Bitmap * bm, const ClipRect * clip, int * x, int * y, char num, const char * pat);
// Set a single pixel
inline void bm_set(const Bitmap * bm, int x, int y);
// Clear a single pixel
inline void bm_clr(const Bitmap * bm, int x, int y);
// Get the state of a single pixel
inline bool bm_get(const Bitmap * bm, int x, int y);
// Set or clear a single pixel
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(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(const Bitmap * bm, const ClipRect * clip, int x0, int y0, int x1, int y1, char pattern, LineOp op);
// Unclipped bit blit
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(const Bitmap * dbm, int dx, int dy, int w, int h);
// Unclipped rectangle clear
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(const Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern);
// Unclipped rectangle copy
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(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(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, int w, int h);
// Clipped rectangle clear
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(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(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(const Bitmap * bm, char lx, 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(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(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(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(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")
#endif
+921
View File
@@ -0,0 +1,921 @@
#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(const Bitmap * bm, int x, int y, char c)
{
char * dp = bm->data + bm->cwidth * (y & ~7) + ((x & ~7) | (y & 7));
char pat = cbytes[c & 3];
*dp = ((*dp ^ pat) & andmask[x & 7]) ^ pat;
}
char bmmc_get(const 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 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(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)
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;
unsigned d = rr - (y0 - y) * (y0 - y);
int tt = 2 * (y0 - y) + 1;
for(char iy=y0; iy<(char)y1; iy++)
{
int t = bm_usqrt(d);
bmmc_scan_fill(clip->left, clip->right, lp, x - t, x + t + 1, pat[iy & 7]);
lp ++;
if (!((int)lp & 7))
lp += stride;
d -= tt;
tt += 2;
}
}
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;
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(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)
{
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(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(const Bitmap * bm, const 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(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;
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(mbuildline)
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(const 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(const Bitmap * bm, const 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(const 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(const 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(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;
sx &= ~1;
bmu_bitblit(dbm, dx, dy, sbm, sx, sy, rx - dx, h, nullptr, BLTOP_COPY);
}
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;
bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, rx - dx, h, MixedColors[color][color], BLTOP_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;
bm_bitblit(dbm, clip, dx, dy, dbm, dx, dy, rx - dx, h, pattern, BLTOP_PATTERN);
}
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;
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(const Bitmap * bm, const 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];
if (back == color)
return;
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;
}
}
}
}
}
#pragma native(bmmc_flood_fill)
+76
View File
@@ -0,0 +1,76 @@
#ifndef MCBITMAP_H
#define MCBITMAP_H
#include "bitmap.h"
extern char MixedColors[4][4][8];
// Set a single pixel
void bmmc_put(const Bitmap * bm, int x, int y, char c);
// Get the state of a single pixel
char bmmc_get(const Bitmap * bm, int x, int y);
// Draw an unclipped line using an eight bit pattern
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(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(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(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(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(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(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(const Bitmap * bm, const ClipRect * clip, int * x, int * y, char num, const char * pat);
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(const Bitmap * dbm, int dx, int dy, int w, int h, const char * pattern);
// Unclipped rectangle copy
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(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(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(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(const Bitmap * bm, const ClipRect * clip, int x, int y, char color);
#pragma compile("mcbitmap.c")
#endif
+39
View File
@@ -0,0 +1,39 @@
#include "tinyfont.h"
const char TinyFont[] = {
0x00, 0x04, 0x05, 0x08, 0x0D, 0x12, 0x17, 0x1C, 0x1D, 0x21, 0x25, 0x2A, 0x2D, 0x2E, 0x31, 0x32,
0x35, 0x39, 0x3D, 0x41, 0x45, 0x49, 0x4D, 0x51, 0x55, 0x59, 0x5D, 0x5E, 0x5F, 0x62, 0x65, 0x68,
0x6C, 0x71, 0x76, 0x7A, 0x7E, 0x82, 0x86, 0x8A, 0x8E, 0x92, 0x95, 0x99, 0x9D, 0xA1, 0xA6, 0xAB,
0xAF, 0xB3, 0xB7, 0xBB, 0xBF, 0xC4, 0xC8, 0xCD, 0xD2, 0xD7, 0xDC, 0xE1, 0xE5, 0xE8, 0xEC, 0xF1,
0xF5, 0xF9, 0xFD, 0x01, 0x05, 0x09, 0x0D, 0x10, 0x14, 0x18, 0x19, 0x1B, 0x1F, 0x21, 0x26, 0x2A,
0x2E, 0x32, 0x36, 0x3A, 0x3E, 0x41, 0x45, 0x49, 0x4E, 0x52, 0x56, 0x5A, 0x5E, 0x5F, 0x63, 0x67,
0x10, 0x04, 0x0C, 0x14, 0x14, 0x14, 0x14, 0x04, 0x10, 0x10, 0x14, 0x0C, 0x04, 0x0C, 0x04, 0x0C,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x04, 0x04, 0x0C, 0x0C, 0x0C, 0x10,
0x14, 0x14, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x10, 0x10, 0x10, 0x14, 0x14, 0x10,
0x10, 0x10, 0x10, 0x10, 0x14, 0x10, 0x14, 0x14, 0x14, 0x14, 0x14, 0x10, 0x0C, 0x10, 0x14, 0x10,
0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x0D, 0x11, 0x11, 0x05, 0x09, 0x11, 0x09, 0x15, 0x11, 0x11,
0x11, 0x11, 0x11, 0x11, 0x0D, 0x11, 0x11, 0x15, 0x11, 0x11, 0x11, 0x11, 0x05, 0x11, 0x11, 0x11,
0x00, 0x00, 0x00, 0x00, 0xFA, 0xC0, 0x00, 0xC0, 0x28, 0x7C, 0x28, 0x7C, 0x28, 0x20, 0x54, 0xD6,
0x54, 0x08, 0x04, 0x48, 0x10, 0x24, 0x40, 0x6C, 0x92, 0x92, 0x6C, 0x0A, 0xC0, 0x38, 0x44, 0x82,
0x82, 0x82, 0x82, 0x44, 0x38, 0x10, 0x54, 0x38, 0x54, 0x10, 0x10, 0x38, 0x10, 0x03, 0x10, 0x10,
0x10, 0x02, 0x06, 0x38, 0xC0, 0x7C, 0x82, 0x82, 0x7C, 0x22, 0x42, 0xFE, 0x02, 0x46, 0x8A, 0x92,
0x62, 0x44, 0x82, 0x92, 0x6C, 0xF0, 0x10, 0x3E, 0x10, 0xE4, 0x92, 0x92, 0x8C, 0x7C, 0x92, 0x92,
0x4C, 0x80, 0x8E, 0x90, 0xE0, 0x6C, 0x92, 0x92, 0x6C, 0x64, 0x92, 0x92, 0x7C, 0x28, 0x0B, 0x10,
0x28, 0x44, 0x28, 0x28, 0x28, 0x44, 0x28, 0x10, 0x40, 0x80, 0x9A, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3E, 0x50, 0x90, 0x50, 0x3E, 0xFE, 0x92, 0x92, 0x6C, 0x7C, 0x82, 0x82, 0x44, 0xFE, 0x82,
0x82, 0x7C, 0xFE, 0x92, 0x92, 0x82, 0xFE, 0x90, 0x90, 0x80, 0x7C, 0x82, 0x92, 0x1C, 0xFE, 0x10,
0x10, 0xFE, 0x82, 0xFE, 0x82, 0x84, 0x82, 0x82, 0xFC, 0xFE, 0x10, 0x28, 0xC6, 0xFE, 0x02, 0x02,
0x02, 0xFE, 0x40, 0x20, 0x40, 0xFE, 0xFE, 0x40, 0x20, 0x10, 0xFE, 0x7C, 0x82, 0x82, 0x7C, 0xFE,
0x90, 0x90, 0x60, 0x7C, 0x82, 0x84, 0x7A, 0xFE, 0x90, 0x90, 0x6E, 0x64, 0x92, 0x92, 0x4C, 0x80,
0x80, 0xFE, 0x80, 0x80, 0xFC, 0x02, 0x02, 0xFC, 0xE0, 0x18, 0x06, 0x18, 0xE0, 0xFE, 0x04, 0x08,
0x04, 0xFE, 0xC6, 0x28, 0x10, 0x28, 0xC6, 0xE0, 0x10, 0x1E, 0x10, 0xE0, 0x86, 0x8A, 0x92, 0xA2,
0xC2, 0xFE, 0x82, 0x82, 0x82, 0xC0, 0x38, 0x06, 0x82, 0x82, 0x82, 0xFE, 0x20, 0x40, 0x80, 0x40,
0x20, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x2A, 0x2A, 0x1E, 0xFE, 0x22, 0x22,
0x1C, 0x1C, 0x22, 0x22, 0x14, 0x1C, 0x22, 0x22, 0xFE, 0x1C, 0x2A, 0x2A, 0x18, 0x20, 0x7E, 0xA0,
0x18, 0x25, 0x25, 0x3E, 0xFE, 0x20, 0x20, 0x1E, 0xBE, 0x01, 0xBE, 0xFE, 0x10, 0x28, 0x46, 0xFC,
0x02, 0x3E, 0x20, 0x1E, 0x20, 0x1E, 0x3E, 0x20, 0x20, 0x1E, 0x1C, 0x22, 0x22, 0x1C, 0x3F, 0x24,
0x24, 0x18, 0x18, 0x24, 0x24, 0x3F, 0x3E, 0x10, 0x20, 0x10, 0x12, 0x2A, 0x2A, 0x04, 0x20, 0x7C,
0x22, 0x3C, 0x02, 0x02, 0x3E, 0x38, 0x04, 0x02, 0x3C, 0x3C, 0x02, 0x1C, 0x02, 0x3C, 0x26, 0x18,
0x0C, 0x32, 0x38, 0x05, 0x05, 0x3E, 0x26, 0x2A, 0x2A, 0x32, 0x10, 0x6C, 0x82, 0x82, 0xFE, 0x82,
0x82, 0x6C, 0x10, 0x10, 0x20, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00
};
+8
View File
@@ -0,0 +1,8 @@
#ifndef TINYFONT_H
#define TINYFONT_H
extern const char TinyFont[];
#pragma compile("tinyfont.c")
#endif
File diff suppressed because it is too large Load Diff
+294
View File
@@ -0,0 +1,294 @@
#ifndef VECTOR3D_H
#define VECTOR3D_H
struct Vector2
{
float v[2];
};
inline void vec2_set(Vector2 * vd, float x, float y);
void vec2_sum(Vector2 * vd, const Vector2 * v1, const Vector2 * v2);
void vec2_diff(Vector2 * vd, const Vector2 * v1, const Vector2 * v2);
void vec2_add(Vector2 * vd, const Vector2 * vs);
void vec2_sub(Vector2 * vd, const Vector2 * vs);
void vec2_madd(Vector2 * vd, float s, const Vector2 * vs);
void vec2_scale(Vector2 * vd, float s);
void vec2_lincomb(Vector2 * vd, const Vector2 * vb, float x, const Vector2 * vx);
void vec2_lincomb2(Vector2 * vd, const Vector2 * vb, float x, const Vector2 * vx, float y, const Vector2 * vy);
void vec2_lerp(Vector2 * vd, const Vector2 * v1, const Vector2 * v2, float t);
bool vec2_is_zero(const Vector2 * v);
float vec2_vmul(const Vector2 * v1, const Vector2 * v2);
void vec2_norm(Vector2 * v);
float vec2_length(const Vector2 * v);
float vec2_qlength(const Vector2 * v);
float vec2_distance(const Vector2 * v1, const Vector2 * v2);
float vec2_qdistance(const Vector2 * v1, const Vector2 * v2);
struct Matrix2
{
float m[4];
};
void mat2_ident(Matrix2 * md);
void mat2_add(Matrix2 * md, const Matrix2 * ms);
void mat2_scale(Matrix2 * md, float s);
void mat2_mmul(Matrix2 * md, const Matrix2 * ms);
void mat2_rmmul(Matrix2 * md, const Matrix2 * ms);
void mat2_tranpose(Matrix2 * md);
void vec2_mmul(Vector2 * vd, const Matrix2 * m, const Vector2 * vs);
void vec2_mimul(Vector2 * vd, const Matrix2 * m, const Vector2 * vs);
void mat2_set_rotate(Matrix2 * md, float a);
void mat2_rotate(Matrix2 * md, float a);
float mat2_det(const Matrix2 * ms);
void mat2_invert(Matrix2 * md, const Matrix2 * ms);
struct Vector3
{
float v[3];
};
inline void vec3_set(Vector3 * vd, float x, float y, float z);
void vec3_sum(Vector3 * vd, const Vector3 * v1, const Vector3 * v2);
void vec3_diff(Vector3 * vd, const Vector3 * v1, const Vector3 * v2);
void vec3_add(Vector3 * vd, const Vector3 * vs);
void vec3_sub(Vector3 * vd, const Vector3 * vs);
void vec3_madd(Vector3 * vd, float s, const Vector3 * vs);
void vec3_scale(Vector3 * vd, float s);
void vec3_lincomb(Vector3 * vd, const Vector3 * vb, float x, const Vector3 * vx);
void vec3_lincomb2(Vector3 * vd, const Vector3 * vb, float x, const Vector3 * vx, float y, const Vector3 * vy);
void vec3_lerp(Vector3 * vd, const Vector3 * v1, const Vector3 * v2, float t);
bool vec3_is_zero(const Vector3 * v);
float vec3_vmul(const Vector3 * v1, const Vector3 * v2);
void vec3_norm(Vector3 * v);
float vec3_length(const Vector3 * v);
float vec3_qlength(const Vector3 * v);
float vec3_distance(const Vector3 * v1, const Vector3 * v2);
float vec3_qdistance(const Vector3 * v1, const Vector3 * v2);
void vec3_mcadd(Vector3 * vd, const Vector3 * v1, const Vector3 * v2);
void vec3_mscadd(Vector3 * vd, float s, const Vector3 * v1, const Vector3 * v2);
void vec3_cmul(Vector3 * vd, const Vector3 * v1, const Vector3 * v2);
void vec3_xmul(Vector3 * vd, const Vector3 * v1, const Vector3 * v2);
void vec3_mbase(Vector3 * v1, Vector3 * v2, Vector3 * v3);
void vec3_bend(Vector3 * vd, const Vector3 * vs, float chi1, float chi2);
struct Matrix3
{
float m[9];
};
void mat3_ident(Matrix3 * m);
void mat3_scale(Matrix3 * md, float s);
void mat3_add(Matrix3 * md, const Matrix3 * ms);
void mat3_mmul(Matrix3 * md, const Matrix3 * ms);
void mat3_rmmul(Matrix3 * md, const Matrix3 * ms);
void mat3_transpose(Matrix3 * md, const Matrix3 * ms);
float mat3_det(const Matrix3 * ms);
void mat3_invert(Matrix3 * md, const Matrix3 * ms);
void vec3_mmul(Vector3 * vd, const Matrix3 * m, const Vector3 * vs);
void mat3_set_rotate_x(Matrix3 * m, float a);
void mat3_set_rotate_y(Matrix3 * m, float a);
void mat3_set_rotate_z(Matrix3 * m, float a);
void mat3_set_rotate(Matrix3 * m, const Vector3 * v, float a);
struct Vector4
{
float v[4];
};
inline void vec4_set(Vector4 * vd, float x, float y, float z, float w);
void vec4_sum(Vector4 * vd, const Vector4 * v1, const Vector4 * v2);
void vec4_diff(Vector4 * vd, const Vector4 * v1, const Vector4 * v2);
void vec4_add(Vector4 * vd, const Vector4 * vs);
void vec4_sub(Vector4 * vd, const Vector4 * vs);
void vec4_madd(Vector4 * vd, float s, const Vector4 * vs);
void vec4_scale(Vector4 * vd, float s);
void vec4_lincomb(Vector4 * vd, const Vector4 * vb, float x, const Vector4 * vx);
void vec4_lincomb2(Vector4 * vd, const Vector4 * vb, float x, const Vector4 * vx, float y, const Vector4 * vy);
void vec4_lerp(Vector4 * vd, const Vector4 * v1, const Vector4 * v2, float t);
bool vec4_is_zero(const Vector4 * v);
float vec4_vmul(const Vector4 * v1, const Vector4 * v2);
void vec4_norm(Vector4 * v);
float vec4_length(const Vector4 * v);
float vec4_qlength(const Vector4 * v);
float vec4_distance(const Vector4 * v1, const Vector4 * v2);
float vec4_qdistance(const Vector4 * v1, const Vector4 * v2);
void vec4_mcadd(Vector4 * vd, const Vector4 * v1, const Vector4 * v2);
void vec4_mscadd(Vector4 * vd, float s, const Vector4 * v1, const Vector4 * v2);
void vec4_cmul(Vector4 * vd, const Vector4 * v1, const Vector4 * v2);
void vec4_xmul(Vector4 * vd, const Vector4 * v1, const Vector4 * v2);
void vec4_mbase(Vector4 * v1, Vector4 * v2, Vector4 * v3);
void vec4_bend(Vector4 * vd, const Vector4 * vs, float chi1, float chi2);
struct Matrix4
{
float m[16];
};
void mat4_ident(Matrix4 * m);
void mat4_from_vec4(Matrix4 * m, const Vector4 * vx, const Vector4 * vy, const Vector4 * vz, const Vector4 * vw);
void mat4_from_vec3(Matrix4 * m, const Vector3 * vx, const Vector3 * vy, const Vector3 * vz, const Vector3 * vw);
void mat4_make_perspective(Matrix4 * m, float fieldOfViewInRadians, float aspect, float near, float far);
void mat4_make_view(Matrix4 * m, const Vector3 * pos, const Vector3 * target, const Vector3 * up);
void mat4_scale(Matrix4 * md, float s);
void mat4_add(Matrix4 * md, const Matrix4 * ms);
void mat4_mmul(Matrix4 * md, const Matrix4 * ms);
void mat4_rmmul(Matrix4 * md, const Matrix4 * ms);
float mat4_det(const Matrix4 * m);
void mat4_invert(Matrix4 * md, const Matrix4 * ms);
void vec4_mmul(Vector4 * vd, const Matrix4 * m, const Vector4 * vs);
void vec3_mmulp(Vector3 * vd, const Matrix4 * m, const Vector3 * vs);
void vec3_mmuld(Vector3 * vd, const Matrix4 * m, const Vector3 * vs);
void mat4_set_rotate_x(Matrix4 * m, float a);
void mat4_set_rotate_y(Matrix4 * m, float a);
void mat4_set_rotate_z(Matrix4 * m, float a);
void mat4_set_rotate(Matrix4 * m, const Vector3 * v, float a);
void mat4_set_translate(Matrix4 * m, const Vector3 * v);
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