Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
163 lines
4.2 KiB
C
163 lines
4.2 KiB
C
// ____________________________
|
|
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄
|
|
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ██ █ ██▄▀ ▄▀██ █ ██
|
|
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ██▄▀ ██ ▀▄██ █▀█▀
|
|
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘
|
|
// by Guillaume 'Aoineko' Blanchard under CC BY-SA license
|
|
//─────────────────────────────────────────────────────────────────────────────
|
|
#include "draw.h"
|
|
|
|
#if (MSX_VERSION >= MSX_2)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Draws a line (one pixel wide)
|
|
void Draw_Line(UX x1, UY y1, UX x2, UY y2, u8 color, u8 op)
|
|
{
|
|
u16 dx, dy, nx, ny;
|
|
u8 arg;
|
|
|
|
arg = 0;
|
|
if (x1 > x2)
|
|
{
|
|
arg |= VDP_ARG_DIX_LEFT;
|
|
dx = x1 - x2 /*+ 1*/;
|
|
}
|
|
else // (x1 <= x2)
|
|
{
|
|
arg |= VDP_ARG_DIX_RIGHT;
|
|
dx = x2 - x1 /*+ 1*/;
|
|
}
|
|
if (y1 > y2)
|
|
{
|
|
arg |= VDP_ARG_DIY_UP;
|
|
dy = y1 - y2 /*+ 1*/;
|
|
}
|
|
else // (y1 <= y2)
|
|
{
|
|
arg |= VDP_ARG_DIY_DOWN;
|
|
dy = y2 - y1 /*+ 1*/;
|
|
}
|
|
if (dx > dy)
|
|
{
|
|
arg |= VDP_ARG_MAJ_H;
|
|
nx = dx;
|
|
ny = dy;
|
|
}
|
|
else // (dx <= dy)
|
|
{
|
|
arg |= VDP_ARG_MAJ_V;
|
|
nx = dy;
|
|
ny = dx;
|
|
}
|
|
|
|
VDP_CommandLINE(x1, y1, nx, ny, color, arg, op);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Draws a horizontal line (one pixel wide)
|
|
void Draw_LineH(UX x1, UX x2, UY y, u8 color, u8 op)
|
|
{
|
|
u16 dx, nx;
|
|
if (x1 > x2)
|
|
{
|
|
dx = x2;
|
|
nx = x1 - x2 + 1;
|
|
}
|
|
else
|
|
{
|
|
dx = x1;
|
|
nx = x2 - x1 + 1;
|
|
}
|
|
VDP_CommandLMMV(dx, y, nx, 1, color, op);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Draws a vertical line (one pixel wide)
|
|
void Draw_LineV(UX x, UY y1, UY y2, u8 color, u8 op)
|
|
{
|
|
u16 dy, ny;
|
|
if (y1 < y2)
|
|
{
|
|
dy = y1;
|
|
ny = y2 - y1 + 1;
|
|
}
|
|
else
|
|
{
|
|
dy = y2;
|
|
ny = y1 - y2 + 1;
|
|
}
|
|
VDP_CommandLMMV(x, dy, 1, ny, color, op);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Draws a box (one pixel wide)
|
|
void Draw_Box(UX x1, UY y1, UX x2, UY y2, u8 color, u8 op)
|
|
{
|
|
Draw_LineH(x1, x2, y1, color, op);
|
|
Draw_LineH(x1, x2, y2, color, op);
|
|
Draw_LineV(x1, y1, y2, color, op);
|
|
Draw_LineV(x2, y1, y2, color, op);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Draws a fully filled box
|
|
void Draw_FillBox(UX x1, UY y1, UX x2, UY y2, u8 color, u8 op)
|
|
{
|
|
VDP_CommandLMMV(x1, y1, x2 - x1 + 1, y2 - y1 + 1, color, op);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Draws a circle (one pixel wide)
|
|
// @author Ibán Cereijo (https://ibancg.github.io/A-fast-circle-algorithm-for-ZX-Spectrum)
|
|
void Draw_Circle(UX dx, UY dy, u8 radius, u8 color, u8 op)
|
|
{
|
|
USX x = radius;
|
|
USY y = 0;
|
|
USX e = 0;
|
|
|
|
while (1)
|
|
{
|
|
// VDP_CommandPSET(dx + x, dy + y, color, op);
|
|
g_VDP_Command.DX = dx + x;
|
|
g_VDP_Command.DY = dy + y;
|
|
g_VDP_Command.CLR = color;
|
|
g_VDP_Command.ARG = 0;
|
|
g_VDP_Command.CMD = VDP_CMD_PSET + op;
|
|
VDP_CommandSetupR36();
|
|
// VDP_CommandPSET(dx + x, dy - y, color, op);
|
|
g_VDP_Command.DY = dy - y;
|
|
VDP_CommandSetupR36();
|
|
// VDP_CommandPSET(dx - x, dy - y, color, op);
|
|
g_VDP_Command.DX = dx - x;
|
|
VDP_CommandSetupR36();
|
|
// VDP_CommandPSET(dx - x, dy + y, color, op);
|
|
g_VDP_Command.DY = dy + y;
|
|
VDP_CommandSetupR36();
|
|
// VDP_CommandPSET(dx + y, dy + x, color, op);
|
|
g_VDP_Command.DX = dx + y;
|
|
g_VDP_Command.DY = dy + x;
|
|
VDP_CommandSetupR36();
|
|
// VDP_CommandPSET(dx + y, dy - x, color, op);
|
|
g_VDP_Command.DY = dy - x;
|
|
VDP_CommandSetupR36();
|
|
// VDP_CommandPSET(dx - y, dy - x, color, op);
|
|
g_VDP_Command.DX = dx - y;
|
|
VDP_CommandSetupR36();
|
|
// VDP_CommandPSET(dx - y, dy + x, color, op);
|
|
g_VDP_Command.DY = dy + x;
|
|
VDP_CommandSetupR36();
|
|
|
|
if (x <= y)
|
|
break;
|
|
e += (2 * y) + 1;
|
|
y++;
|
|
if (e > x)
|
|
{
|
|
e += 1 - (2 * x);
|
|
x--;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // (MSX_VERSION >= MSX_2)
|