Converted all shaders to new Azur methodology

This commit is contained in:
Sylvain PILLOT 2023-08-30 18:52:45 +02:00
parent c4ac50a79a
commit 1d7c044cd4
10 changed files with 717 additions and 13 deletions

View File

@ -44,6 +44,11 @@ set(SOURCES
src/utilities.cpp
src/player.cpp
src/level.cpp
src/circle.cpp
src/poly.cpp
src/filledcircle.cpp
src/filledpoly.cpp
src/line.cpp
# ...
)
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets

27
src/AzurShaders.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef AZURSHADERS
#define AZURSHADERS
void azrp_shader_line_configure(void);
void azrp_shader_circle_configure(void);
void azrp_shader_filledcircle_configure(void);
void azrp_shader_filledpoly_configure(void);
void azrp_shader_poly_configure(void);
/* azrp_line(): Draw a line with clipping to the screen resolution between point (x1,y1) and (x2,y2) */
void azrp_line( int x1, int y1, int x2, int y2, uint16_t color );
/* azrp_circle() : Draw a circle with clipping to the screen resolution with a center (xc,yc) and a radius rad */
void azrp_circle( int xc, int yx, uint16_t rad, uint16_t color );
/* azrp_filledcircle() : Draw a filled circle with clipping to the screen resolution with a center (xc,yc) and a radius rad */
void azrp_filledcircle( int xc, int yx, uint16_t rad, uint16_t color );
/* azrp_poly() : Draw a polygon with clipping*/
void azrp_poly(int *x, int *y, int nb_vertices, uint16_t color);
/* azrp_filledpoly() : Draw a filled polygon with clipping*/
void azrp_filledpoly(int *x, int *y, int nb_vertices, uint16_t color);
#endif

147
src/circle.cpp Normal file
View File

@ -0,0 +1,147 @@
#include <azur/gint/render.h>
uint8_t AZRP_SHADER_CIRCLE = -1;
static void azrp_shader_circle_configure(void)
{
azrp_set_uniforms(AZRP_SHADER_CIRCLE, (void *)azrp_width);
}
__attribute__((constructor))
static void register_shader(void)
{
extern azrp_shader_t azrp_shader_circle;
AZRP_SHADER_CIRCLE = azrp_register_shader(azrp_shader_circle, azrp_shader_circle_configure);
}
static int min(int x, int y)
{
return (x < y) ? x : y;
}
static int max(int x, int y)
{
return (x > y) ? x : y;
}
//---
#define TABLE_WIDTH 256
struct command {
uint8_t shader_id;
uint16_t color;
uint8_t curr_frag;
uint16_t NbPixels[14]; // Nunmber of pixels in each fragment
uint16_t DataPixelsX[14*TABLE_WIDTH]; // 14 fragments each able to store as much pixels as width
uint16_t DataPixelsY[14*TABLE_WIDTH]; // 14 fragments each able to store as much pixels as width
};
void AddPixelCircle( int16_t xp, int16_t yp, struct command *cmd )
{
if (xp >= 0 && xp < azrp_width && yp >= 0 && yp < azrp_height)
{
uint8_t cfrag = yp / azrp_frag_height;
uint16_t nbpixinfrag = cmd->NbPixels[ cfrag ];
uint16_t index = cfrag * TABLE_WIDTH + nbpixinfrag;
cmd->DataPixelsX[ index ] = xp;
cmd->DataPixelsY[ index ] = yp & 15;
cmd->NbPixels[ cfrag ]++;
}
}
void azrp_circle(int xc, int yc, uint16_t rad, uint16_t color)
{
prof_enter(azrp_perf_cmdgen);
int xmin = xc - rad;
int xmax = xc + rad;
int ymin = yc - rad;
int ymax = yc + rad;
// The circle is fully outside the screen
if ((xmax < 0) || (xmin >= azrp_width) || (ymax < 0) || (ymin >= azrp_height))
{
prof_leave(azrp_perf_cmdgen);
return;
}
int ytop = max( ymin, 0 );
int ybot = min( ymax, azrp_height-1 );
int frag_first = ytop / azrp_frag_height;
int frag_last = ybot / azrp_frag_height;
int frag_count = frag_last - frag_first + 1;
struct command *cmd = (struct command *) azrp_new_command(sizeof *cmd, frag_first, frag_count);
if(!cmd) {
prof_leave(azrp_perf_cmdgen);
return;
}
cmd->shader_id = AZRP_SHADER_CIRCLE;
cmd->color = color;
cmd->curr_frag = frag_first;
// reset the point counters in each cell of the table
for( int i = 0; i < 14; i++ )
cmd->NbPixels[i]=0;
int x = 0;
int y = rad;
int m = 5 - 4*rad;
while (x <= y)
{
AddPixelCircle( xc+x, yc+y, cmd );
AddPixelCircle( xc+y, yc+x, cmd );
AddPixelCircle( xc-x, yc+y, cmd );
AddPixelCircle( xc-y, yc+x, cmd );
AddPixelCircle( xc+x, yc-y, cmd );
AddPixelCircle( xc+y, yc-x, cmd );
AddPixelCircle( xc-x, yc-y, cmd );
AddPixelCircle( xc-y, yc-x, cmd );
if (m > 0)
{
y--;
m -= 8*y;
}
x++;
m += 8*x + 4;
}
prof_leave(azrp_perf_cmdgen);
}
void azrp_shader_circle( void *uniforms, void *comnd, void *fragment )
{
struct command *cmd = (struct command *) comnd;
uint16_t *frag = (uint16_t *) fragment;
uint16_t *taille = (uint16_t *) cmd->NbPixels;
uint16_t *DX = (uint16_t *) cmd->DataPixelsX;
uint16_t *DY = (uint16_t *) cmd->DataPixelsY;
uint16_t nbpix = taille[ cmd->curr_frag ];
int BaseAdress = cmd->curr_frag * TABLE_WIDTH;
for( int i = 0; i < nbpix; i++ )
{
uint16_t X = DX[ BaseAdress + i ];
uint16_t Y = DY[ BaseAdress + i ];
frag[ azrp_width * Y + X ] = cmd->color;
}
cmd->curr_frag++;
}

124
src/filledcircle.cpp Normal file
View File

@ -0,0 +1,124 @@
#include <azur/gint/render.h>
uint8_t AZRP_SHADER_FILLEDCIRCLE = -1;
static void azrp_shader_filledcircle_configure(void) {
azrp_set_uniforms(AZRP_SHADER_FILLEDCIRCLE, (void *)azrp_width);
}
__attribute__((constructor)) static void register_shader(void) {
extern azrp_shader_t azrp_shader_filledcircle;
AZRP_SHADER_FILLEDCIRCLE = azrp_register_shader(azrp_shader_filledcircle, azrp_shader_filledcircle_configure);
}
static int min(int x, int y) { return (x < y) ? x : y; }
static int max(int x, int y) { return (x > y) ? x : y; }
//---
#define TABLE_WIDTH
struct command {
uint8_t shader_id;
uint16_t color;
uint8_t curr_frag;
int16_t DataFilling[2 * 224]; // Each line of the screen can have a xmin and
// a xmax value
};
void AddPixelFilledCircle(int16_t xpmin, int16_t xpmax, int16_t yp,
struct command *cmd) {
if (yp >= 0 && yp < azrp_height) {
if (xpmin >= 0)
cmd->DataFilling[2 * yp] = xpmin;
else
cmd->DataFilling[2 * yp] = 0;
if (xpmax < azrp_width)
cmd->DataFilling[2 * yp + 1] = xpmax;
else
cmd->DataFilling[2 * yp + 1] = azrp_width - 1;
}
}
void azrp_filledcircle(int xc, int yc, uint16_t rad, uint16_t color) {
prof_enter(azrp_perf_cmdgen);
int xmin = xc - rad;
int xmax = xc + rad;
int ymin = yc - rad;
int ymax = yc + rad;
// The circle is fully outside the screen
if ((xmax < 0) || (xmin >= azrp_width) || (ymax < 0) ||
(ymin >= azrp_height)) {
prof_leave(azrp_perf_cmdgen);
return;
}
int ytop = max(ymin, 0);
int ybot = min(ymax, azrp_height - 1);
int frag_first = ytop / azrp_frag_height;
int frag_last = ybot / azrp_frag_height;
int frag_count = frag_last - frag_first + 1;
struct command *cmd = (struct command *) azrp_new_command(sizeof *cmd, frag_first, frag_count);
if(!cmd) {
prof_leave(azrp_perf_cmdgen);
return;
}
cmd->shader_id = AZRP_SHADER_FILLEDCIRCLE;
cmd->color = color;
cmd->curr_frag = frag_first;
// reset the point counters in each cell of the table
for (int i = 0; i < 224; i++) {
cmd->DataFilling[2 * i] = -1; // reset with value equels -1
cmd->DataFilling[2 * i + 1] = -1; // reset with value equals -1
}
int x = 0;
int y = rad;
int m = 5 - 4 * rad;
while (x <= y) {
AddPixelFilledCircle(xc - x, xc + x, yc - y, cmd);
AddPixelFilledCircle(xc - y, xc + y, yc - x, cmd);
AddPixelFilledCircle(xc - x, xc + x, yc + y, cmd);
AddPixelFilledCircle(xc - y, xc + y, yc + x, cmd);
if (m > 0) {
y--;
m -= 8 * y;
}
x++;
m += 8 * x + 4;
}
prof_leave(azrp_perf_cmdgen);
}
void azrp_shader_filledcircle(void *uniforms, void *comnd, void *fragment) {
struct command *cmd = (struct command *)comnd;
uint16_t *frag = (uint16_t *)fragment;
int16_t *data = (int16_t *)cmd->DataFilling;
int BaseAdress = cmd->curr_frag * azrp_frag_height * 2;
for (int i = 0; i < azrp_frag_height; i++) {
int16_t Xmin = data[BaseAdress + 2 * i];
int16_t Xmax = data[BaseAdress + 2 * i + 1];
if (Xmin != -1 && Xmax != -1)
for (int j = Xmin; j <= Xmax; j++)
frag[azrp_width * i + j] = cmd->color;
}
cmd->curr_frag++;
}

171
src/filledpoly.cpp Normal file
View File

@ -0,0 +1,171 @@
#include <azur/gint/render.h>
#include <cstdlib>
uint8_t AZRP_SHADER_FILLEDPOLY = -1;
static void azrp_shader_filledpoly_configure(void) {
azrp_set_uniforms(AZRP_SHADER_FILLEDPOLY, (void *)azrp_width);
}
__attribute__((constructor)) static void register_shader(void) {
extern azrp_shader_t azrp_shader_filledpoly;
AZRP_SHADER_FILLEDPOLY = azrp_register_shader(azrp_shader_filledpoly, azrp_shader_filledpoly_configure);
}
static int min(int x, int y) { return (x < y) ? x : y; }
static int max(int x, int y) { return (x > y) ? x : y; }
//---
#define TABLE_WIDTH
struct command {
uint8_t shader_id;
uint16_t color;
uint8_t curr_frag;
int16_t xmin[224];
int16_t xmax[224];
uint8_t empty[224];
};
void AddPixelFilledPoly(int16_t xpmin, int16_t xpmax, int16_t yp,
struct command *cmd) {
if (yp >= 0 && yp < azrp_height) {
if (xpmin >= 0)
cmd->xmin[yp] = xpmin;
else
cmd->xmin[yp] = 0;
if (xpmax < azrp_width)
cmd->xmax[yp] = xpmax;
else
cmd->xmax[yp] = azrp_width - 1;
}
}
void azrp_filledpoly(int *x, int *y, int nb_vertices, uint16_t color) {
prof_enter(azrp_perf_cmdgen);
int i, ymin, ymax, xmin2, xmax2, *xmin, *xmax;
char *empty;
if(nb_vertices < 3) {
prof_leave(azrp_perf_cmdgen);
return;
}
ymin = ymax = y[0];
xmin2 = xmax2 = x[0];
for(i=0 ; i<nb_vertices ; i++) {
if(y[i] < ymin) ymin = y[i];
if(y[i] > ymax) ymax = y[i];
if(x[i] < xmin2) xmin2 = x[i];
if(x[i] > xmax2) xmax2 = x[i];
}
// The polygon is fully outside the screen
if ((xmax2 < 0) || (xmin2 >= azrp_width) || (ymax < 0) ||
(ymin >= azrp_height)) {
prof_leave(azrp_perf_cmdgen);
return;
}
xmin = (int*) malloc((ymax-ymin+1)*sizeof(int));
xmax = (int*) malloc((ymax-ymin+1)*sizeof(int));
empty = (char*) malloc(ymax-ymin+1);
int ytop = max(ymin, 0);
int ybot = min(ymax, azrp_height - 1);
int frag_first = ytop / azrp_frag_height;
int frag_last = ybot / azrp_frag_height;
int frag_count = frag_last - frag_first + 1;
struct command *cmd = (struct command *) azrp_new_command(sizeof *cmd, frag_first, frag_count);
if(!cmd) {
prof_leave(azrp_perf_cmdgen);
return;
}
cmd->shader_id = AZRP_SHADER_FILLEDPOLY;
cmd->color = color;
cmd->curr_frag = frag_first;
// reset the point counters in each cell of the table
for (int i = 0; i < 224; i++) {
cmd->xmin[i] = -1; // reset with value equels -1
cmd->xmax[i] = -1; // reset with value equals -1
}
if(xmin && xmax && empty) {
for(i=0 ; i<ymax-ymin+1 ; i++) empty[i] = 1;
for(i=0 ; i<nb_vertices ; i++) {
int j, px, py, dx, dy, sx, sy, cumul;
px = x[i];
py = y[i];
dx = x[(i+1)%nb_vertices]-px;
dy = y[(i+1)%nb_vertices]-py;
sx = (dx > 0) ? 1 : -1;
sy = (dy > 0) ? 1 : -1;
dx = (dx > 0) ? dx : -dx;
dy = (dy > 0) ? dy : -dy;
if(empty[py-ymin]) xmax[py-ymin]=xmin[py-ymin]=px, empty[py-ymin]=0; else xmax[py-ymin]=px;
if(dx > dy) {
cumul = dx >> 1;
for(j=1 ; j<dx ; j++) {
px += sx;
cumul += dy;
if(cumul > dx) cumul -= dx, py += sy;
if(empty[py-ymin]) xmax[py-ymin]=xmin[py-ymin]=px, empty[py-ymin]=0; else xmax[py-ymin]=px;
}
} else {
cumul = dy >> 1;
for(j=1 ; j<dy ; j++) {
py += sy;
cumul += dx;
if(cumul > dy) cumul -= dy, px += sx;
if(empty[py-ymin]) xmax[py-ymin]=xmin[py-ymin]=px, empty[py-ymin]=0; else xmax[py-ymin]=px;
}
}
}
for(i=0 ; i<ymax-ymin+1 ; i++)
AddPixelFilledPoly(xmin[i], xmax[i], ymin+i, cmd);
}
free(xmin);
free(xmax);
free(empty);
prof_leave(azrp_perf_cmdgen);
}
void azrp_shader_filledpoly(void *uniforms, void *comnd, void *fragment) {
struct command *cmd = (struct command *)comnd;
uint16_t *frag = (uint16_t *)fragment;
int16_t *Xmindata = (int16_t *)cmd->xmin;
int16_t *Xmaxdata = (int16_t *)cmd->xmax;
int BaseAdress = cmd->curr_frag * azrp_frag_height;
for (int i = 0; i < azrp_frag_height; i++)
{
int16_t Xmin = Xmindata[BaseAdress + i];
int16_t Xmax = Xmaxdata[BaseAdress + i];
if (Xmin != -1 && Xmax != -1)
{
if (Xmin<=Xmax)
for (int j = Xmin; j <= Xmax; j++) frag[azrp_width * i + j] = cmd->color;
else
for (int j = Xmax; j <= Xmin; j++) frag[azrp_width * i + j] = cmd->color;
}
}
cmd->curr_frag++;
}

View File

@ -5,6 +5,7 @@
#include "player.h"
#include <azur/azur.h>
#include <azur/gint/render.h>
#include "AzurShaders.h"
#include <num/num.h>

211
src/line.cpp Normal file
View File

@ -0,0 +1,211 @@
#include <azur/gint/render.h>
uint8_t AZRP_SHADER_LINE = -1;
static void azrp_shader_line_configure(void)
{
azrp_set_uniforms(AZRP_SHADER_LINE, (void *)azrp_width);
}
__attribute__((constructor))
static void register_shader(void)
{
extern azrp_shader_t azrp_shader_line;
AZRP_SHADER_LINE = azrp_register_shader(azrp_shader_line, azrp_shader_line_configure );
}
//---
struct command {
uint8_t shader_id;
uint16_t color;
uint16_t curr_y;
uint16_t curr_x;
int16_t dx, dy, sx, sy;
int16_t cumul;
int16_t i;
};
int ABS( int x1 )
{
if (x1 >= 0) return x1;
else return (-1 * x1);
}
int SGN( int x1 )
{
if (x1 > 0) return 1;
else if (x1 == 0) return 0;
else return -1;
}
void azrp_line(int xA, int yA, int xB, int yB, uint16_t color)
{
prof_enter(azrp_perf_cmdgen);
//clipping algorithm as per "Another Simple but Faster Method for 2D Line Clipping"
//from Dimitrios Matthes and Vasileios Drakopoulos
//International Journal of Computer Graphics & Animation (IJCGA) Vol.9, No.1/2/3, July 2019
int xmin = 0;
int xmax = azrp_width-1;
int ymin = 0;
int ymax = azrp_height-1;
//step 1 line are fully out of the screen
if ((xA<xmin && xB<xmin) || (xA>xmax && xB>xmax) || (yA<ymin && yB<ymin) || (yA>ymax && yB>ymax)) {
prof_leave(azrp_perf_cmdgen);
return;
}
int x1, x2, y1, y2;
// step 1.5 - specific to Azur fragment approach
// we swap to always start with the point on top as the fragment are updated from top to bottom
// (x1,y1) is the most top point and (x2,y2) is the most bottom point (rankig as per y values only
if (yA <= yB) {
x1 = xA; y1 = yA;
x2 = xB; y2 = yB;
}
else {
x1 = xB; y1 = yB;
x2 = xA; y2 = yA;
}
//step 2 line clipping within the box (xmin,ymin) --> (xmax,ymax)
int x[2];
int y[2];
x[0] = x1; x[1] = x2;
y[0] = y1; y[1] = y2;
for(int i=0; i<2; i++) {
if (x[i] < xmin) {
x[i] = xmin; y[i] = ((y2-y1) * (xmin-x1)) / (x2-x1) + y1;
}
else if (x[i] > xmax) {
x[i] = xmax; y[i] = ((y2-y1) * (xmax-x1)) / (x2-x1) + y1;
}
if (y[i] < ymin) {
x[i] = ((x2-x1) * (ymin-y1)) / (y2-y1) + x1; y[i] = ymin;
}
else if (y[i] > ymax) {
x[i] = ((x2-x1) * (ymax-y1)) / (y2-y1) + x1; y[i] = ymax;
}
}
if((x[0] < xmin && x[1] < xmin) || (x[0] > xmax && x[1] > xmax)) {
prof_leave(azrp_perf_cmdgen);
return;
}
x1 = x[0];
y1 = y[0];
x2 = x[1];
y2 = y[1];
int frag_first = y1 / azrp_frag_height;
int frag_last = y2 / azrp_frag_height;
int frag_count = frag_last - frag_first + 1;
struct command *cmd = (struct command *) azrp_new_command(sizeof *cmd, frag_first, frag_count);
if(!cmd) {
prof_leave(azrp_perf_cmdgen);
return;
}
cmd->shader_id = AZRP_SHADER_LINE;
cmd->color = color;
cmd->curr_x = x1;
cmd->curr_y = y1 & 15;
cmd->dx = ABS(x2-x1);
cmd->sx = SGN(x2-x1);
cmd->dy = ABS(y2-y1);
cmd->sy = SGN(y2-y1);
cmd->i = 0;
cmd->cumul = (cmd->dx >= cmd->dy) ? cmd->dx/2 : cmd->dy/2;
prof_leave(azrp_perf_cmdgen);
}
void azrp_shader_line( void *uniforms, void *comnd, void *fragment )
{
struct command *cmd = (struct command *) comnd;
uint16_t *frag = (uint16_t *) fragment;
frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color;
int i;
if (cmd->dy == 0)
{
for( i = cmd->i; i < cmd->dx ; i++ )
{
cmd->curr_x += cmd->sx;
frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color;
}
}
else if (cmd->dx == 0)
{
for( i = cmd->i; i < cmd->dy ; i++ )
{
cmd->curr_y += cmd->sy;
// if curr_y=16, this means we are changing to next fragment
if (cmd->curr_y == azrp_frag_height) break;
frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color;
}
}
else if (cmd->dx >= cmd->dy)
{
for( i = cmd->i; i < cmd->dx; i++ )
{
cmd->curr_x += cmd->sx;
cmd->cumul += cmd->dy;
if (cmd->cumul > cmd->dx)
{
cmd->cumul -= cmd->dx;
cmd->curr_y += cmd->sy;
}
// if curr_y=16, this means we are changing to next fragment
if (cmd->curr_y == azrp_frag_height ) break;
frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color;
}
}
else
{
for( i = cmd->i; i < cmd->dy; i++ )
{
cmd->curr_y += cmd->sy;
cmd->cumul += cmd->dx;
if (cmd->cumul > cmd->dy)
{
cmd->cumul -= cmd->dy;
cmd->curr_x += cmd->sx;
}
// if curr_y=16, this means we are changing to next fragment
if (cmd->curr_y == azrp_frag_height) break;
frag[ azrp_width * cmd->curr_y + cmd->curr_x ] = cmd->color;
}
}
cmd->curr_y = cmd->curr_y & 15;
cmd->i = i+1;
}

View File

@ -2,6 +2,8 @@
#include "parameters.h"
#include <azur/azur.h>
#include "AzurShaders.h"
#include <azur/gint/render.h>
#include <gint/drivers/r61524.h>
#include <gint/rtc.h>
@ -9,8 +11,11 @@
#include <gint/clock.h>
#include <gint/kmalloc.h>
#if !(CALCEMU)
#include <gint/usb-ff-bulk.h>
#include <gint/usb.h>
#endif
#include <libprof.h>
#include <cstdint>
@ -70,6 +75,7 @@ static void hook_prefrag(int id, void *fragment, int size) {
if (!screenshot && !record)
return;
#if !(CALCEMU)
/* Screenshot takes precedence */
char const *type = screenshot ? "image" : "video";
@ -95,6 +101,7 @@ static void hook_prefrag(int id, void *fragment, int size) {
usb_commit_sync(pipe);
screenshot = false;
}
#endif
}
static void update(float dt) {
@ -147,6 +154,7 @@ static void get_inputs(float dt) {
};
#if (DEBUG_MODE)
#if !(CALCEMU)
if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) &&
MyKeyboard.IsKeyPressedEvent(MYKEY_7) && usb_is_open()) {
screenshot = true;
@ -159,6 +167,7 @@ static void get_inputs(float dt) {
MyKeyboard.IsKeyPressedEvent(MYKEY_9) && usb_is_open()) {
record = false;
};
#endif
if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) &&
MyKeyboard.IsKeyPressedEvent(MYKEY_VARS)) {
@ -306,17 +315,12 @@ int main(void) {
azrp_config_scale(SCALE_PIXEL);
azrp_shader_clear_configure();
azrp_shader_image_rgb16_configure();
azrp_shader_image_p8_configure();
azrp_shader_image_p4_configure();
azrp_shader_line_configure();
azrp_shader_circle_configure();
azrp_hook_set_prefrag(hook_prefrag);
#if !(CALCEMU)
usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL};
usb_open(interfaces, GINT_CALL_NULL);
#endif
// MyLevel.ChangeMap(2, &MyPlayer);
@ -353,14 +357,8 @@ int main(void) {
render();
azrp_filledcircle((int)MyPlayer.nextx, (int)MyPlayer.nexty, 24, C_GREEN);
azrp_filledcircle((int)MyPlayer.currx, (int)MyPlayer.curry, 16, C_BLUE);
azrp_filledcircle((int)MyPlayer.currx, (int)MyPlayer.curry, 8, C_RED);
azrp_filledpoly( pointX, pointY, 4, C_RED );
azrp_poly( pointX, pointY, 4, C_WHITE );
azrp_line((int)MyPlayer.currx - 3, (int)MyPlayer.curry,
(int)MyPlayer.currx + 3, (int)MyPlayer.curry, C_GREEN);
azrp_line((int)MyPlayer.currx, (int)MyPlayer.curry - 3,
@ -382,7 +380,10 @@ int main(void) {
} while (exitToOS == false);
prof_quit();
#if !(CALCEMU)
usb_close();
#endif
FreeMoreRAM();

View File

@ -5,5 +5,6 @@
#define DEBUG_MODE 1
#define BIAS 1
#define NOBIAS (1-BIAS)
#define CALCEMU 1
#endif

16
src/poly.cpp Normal file
View File

@ -0,0 +1,16 @@
#include <azur/gint/render.h>
#include "AzurShaders.h"
void azrp_poly(int *x, int *y, int nb_vertices, uint16_t color) {
prof_enter(azrp_perf_cmdgen);
for( int i=0 ; i<nb_vertices ; i++) {
int px = x[i];
int py = y[i];
int px2 = x[(i+1)%nb_vertices];
int py2 = y[(i+1)%nb_vertices];
azrp_line( px, py, px2, py2, color );
}
prof_leave(azrp_perf_cmdgen);
}