Files
mazegame/engine/src/draw.c
T

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)