add filled circles and filled rotated rectangles

This commit is contained in:
Lephenixnoir 2021-08-21 12:10:53 +02:00
parent a7e865b201
commit 26c94b6e66
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
4 changed files with 140 additions and 26 deletions

View File

@ -2,7 +2,7 @@
# toolchain file and module path of the fxSDK
cmake_minimum_required(VERSION 3.15)
project(MyAddin)
project(Duet)
include(GenerateG1A)
include(GenerateG3A)
@ -11,31 +11,19 @@ find_package(Gint 2.1 REQUIRED)
set(SOURCES
src/main.c
src/render.c
# ...
)
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets
set(ASSETS
# ...
)
set(ASSETS_fx
assets-fx/example.png
# ...
)
set(ASSETS_cg
assets-cg/example.png
# ...
)
fxconv_declare_assets(${ASSETS} ${ASSETS_fx} ${ASSETS_cg} WITH_METADATA)
fxconv_declare_assets(${ASSETS} WITH_METADATA)
add_executable(myaddin ${SOURCES} ${ASSETS} ${ASSETS_${FXSDK_PLATFORM}})
target_compile_options(myaddin PRIVATE -Wall -Wextra -Os)
target_link_libraries(myaddin Gint::Gint)
add_executable(addin ${SOURCES} ${ASSETS})
target_compile_options(addin PRIVATE -Wall -Wextra -Os)
target_link_libraries(addin Gint::Gint)
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
generate_g1a(TARGET myaddin OUTPUT "MyAddin.g1a"
NAME "MyAddin" ICON assets-fx/icon.png)
elseif("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
generate_g3a(TARGET myaddin OUTPUT "MyAddin.g3a"
NAME "MyAddin" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)
endif()
generate_g3a(TARGET addin OUTPUT "Duet.g3a"
NAME "Duet" ICONS assets-cg/icon-uns.png assets-cg/icon-sel.png)

View File

@ -1,9 +1,12 @@
#pragma once
#include <gint/display.h>
#include <gint/defs/types.h>
#include <stdint.h>
#include <stdbool.h>
#include <gint/display.h>
#define __BSD_VISIBLE 1
#include <math.h>
//---
@ -14,6 +17,7 @@ typedef struct {
float w, h; /* px */
float x, y; /* px */
float vx, vy; /* px/s */
float r; /* rad */
float vr; /* rad/s */
} rect_t;
@ -57,4 +61,8 @@ typedef struct {
// Rendering
//---
void dcircle(int x, int y, int color);
void dcircle(int x, int y, int r, int color, bool fill);
void dtriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color);
void drectoid(rect_t const *r, int color);

View File

@ -1,15 +1,26 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include "duet.h"
//rectmeta_t level1[] = {
// {.time = 0, .shape = Shape_LongBar, .position = Position_Left}
//};
int main(void)
{
dclear(C_WHITE);
dtext(1, 1, C_BLACK, "Sample fxSDK add-in.");
rect_t r = {
.w = 80,
.h = 20,
.x = 200,
.y = 150,
.r = M_PI / 12,
};
dcircle(100, 100, 20, C_RED, true);
dtriangle(0, 0, 8, 20, 20, 0, C_BLACK);
drectoid(&r, C_RED);
dupdate();
getkey();

View File

@ -1,3 +1,110 @@
void dcircle(int x, int y, int color)
#include "duet.h"
#include <stdlib.h>
/* Bresenham algorithm */
void dcircle(int cx, int cy, int r0, int color, bool fill)
{
int x=-r0, y=0, e=2-2*r0, r=r0;
do {
dpixel(cx-x, cy-y, color);
dpixel(cx+y, cy-x, color);
dpixel(cx+x, cy+y, color);
dpixel(cx-y, cy+x, color);
if(fill) {
dline(cx+x, cy-y, cx-x, cy-y, color);
dline(cx+x, cy+y, cx-x, cy+y, color);
}
r = e;
if(r <= y)
e += (++y * 2) + 1;
if(r > x || e > y)
e += (++x * 2) + 1;
}
while(x < 0);
}
/* From Windmill::render_triangle_black */
static int edge_start(int x1, int y1, int x2, int y2, int px, int py)
{
return (y2 - y1) * (px - x1) - (x2 - x1) * (py - y1);
}
static int min(int x, int y)
{
return (x < y) ? x : y;
}
static int max(int x, int y)
{
return (x > y) ? x : y;
}
void dtriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color)
{
if(y2 > y3) {
int tx=x2, ty=y2;
x2=x3, y2=y3;
x3=tx, y3=ty;
}
if(y1 > y2) {
int tx=x1, ty=y1;
x1=x2, y1=y2;
x2=tx, y2=ty;
}
// calcul du rectangle circonscrit au triangle
int min_x = max(0, min(x1, min(x2, x3)));
int max_x = min(DWIDTH-1, max(x1, max(x2, x3)));
int min_y = max(0, min(y1, min(y2, y3)));
int max_y = min(DHEIGHT-1, max(y1, max(y2, y3)));
// calcul des produits vectoriels
int u0_start = edge_start(x2, y2, x3, y3, min_x, min_y);
int u0_step_x = y3 - y2;
int u0_step_y = x2 - x3;
int u1_start = edge_start(x3, y3, x1, y1, min_x, min_y);
int u1_step_x = y1 - y3;
int u1_step_y = x3 - x1;
int u2_start = edge_start(x1, y1, x2, y2, min_x, min_y);
int u2_step_x = y2 - y1;
int u2_step_y = x1 - x2;
int u0, u1, u2;
// parcours en ligne
for(int x=min_x; x<=max_x; x++)
{
u0 = u0_start; u1 = u1_start; u2 = u2_start;
// parcours en colonne
for(int y=min_y; y<=max_y; y++)
{
// si le pixel (x;y) est dans le triangle
if ((u0 | u1 | u2) > 0)
{
dpixel(x, y, color);
}
u0 += u0_step_y; u1 += u1_step_y; u2 += u2_step_y;
}
u0_start += u0_step_x; u1_start += u1_step_x; u2_start += u2_step_x;
}
}
void drectoid(rect_t const *r, int color)
{
float sin, cos;
sincosf(r->r, &sin, &cos);
float x0[4] = { r->w/2, -r->w/2, -r->w/2, r->w/2 };
float y0[4] = { -r->h/2, -r->h/2, r->h/2, r->h/2 };
int x[4], y[4];
for(int i = 0; i < 4; i++) {
x[i] = r->x + x0[i] * cos + y0[i] * sin;
y[i] = r->y - x0[i] * sin + y0[i] * cos;
}
dtriangle(x[0], y[0], x[1], y[1], x[2], y[2], color);
dtriangle(x[2], y[2], x[3], y[3], x[0], y[0], color);
}