From 8ec39f68b8c74875d8cf3fa74f5fa7ef0bf969cd Mon Sep 17 00:00:00 2001 From: SlyVTT Date: Wed, 30 Aug 2023 19:13:47 +0200 Subject: [PATCH] Converted all shaders to new Azur methodology --- CMakeLists.txt | 5 + src/AzurShaders.h | 27 ++++++ src/circle.cpp | 147 ++++++++++++++++++++++++++++ src/filledcircle.cpp | 124 ++++++++++++++++++++++++ src/filledpoly.cpp | 171 +++++++++++++++++++++++++++++++++ src/line.cpp | 211 +++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 20 ++-- src/parameters.h | 1 + src/pinball_entities.h | 6 +- src/poly.cpp | 16 ++++ src/tables.h | 19 ++-- src/utilities.h | 4 - 12 files changed, 725 insertions(+), 26 deletions(-) create mode 100644 src/AzurShaders.h create mode 100644 src/circle.cpp create mode 100644 src/filledcircle.cpp create mode 100644 src/filledpoly.cpp create mode 100644 src/line.cpp create mode 100644 src/poly.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a8e4a72..9a470b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,11 @@ find_package(LibProf 2.4 REQUIRED) set(SOURCES src/main.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 diff --git a/src/AzurShaders.h b/src/AzurShaders.h new file mode 100644 index 0000000..716e1b2 --- /dev/null +++ b/src/AzurShaders.h @@ -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 \ No newline at end of file diff --git a/src/circle.cpp b/src/circle.cpp new file mode 100644 index 0000000..ebc5226 --- /dev/null +++ b/src/circle.cpp @@ -0,0 +1,147 @@ +#include + +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++; +} \ No newline at end of file diff --git a/src/filledcircle.cpp b/src/filledcircle.cpp new file mode 100644 index 0000000..b87793a --- /dev/null +++ b/src/filledcircle.cpp @@ -0,0 +1,124 @@ +#include + +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++; +} \ No newline at end of file diff --git a/src/filledpoly.cpp b/src/filledpoly.cpp new file mode 100644 index 0000000..4f1123b --- /dev/null +++ b/src/filledpoly.cpp @@ -0,0 +1,171 @@ +#include +#include + +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 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 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) 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) 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 ; ixmin; + 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++; +} \ No newline at end of file diff --git a/src/line.cpp b/src/line.cpp new file mode 100644 index 0000000..ca1c354 --- /dev/null +++ b/src/line.cpp @@ -0,0 +1,211 @@ +#include + +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 ((xAxmax && xB>xmax) || (yAymax && 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; +} diff --git a/src/main.cpp b/src/main.cpp index cd6a5e2..f76e3d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,14 +4,19 @@ #include #include + +#include "AzurShaders.h" + #include #include #include #if (DEBUG_MODE) + #if !(CALCEMU) #include #include + #endif #endif #include @@ -85,6 +90,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"; @@ -110,6 +116,7 @@ static void hook_prefrag(int id, void *fragment, int size) { usb_commit_sync(pipe); screenshot = false; } +#endif } static void update(float dt) { @@ -269,6 +276,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; @@ -281,6 +289,7 @@ static void get_inputs(float dt) { MyKeyboard.IsKeyPressedEvent(MYKEY_9) && usb_is_open()) { record = false; }; + #endif #endif } @@ -293,18 +302,13 @@ 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 (DEBUG_MODE) +#if !(CALCEMU) usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL}; usb_open(interfaces, GINT_CALL_NULL); +#endif #endif // TODO : Currently Loads Table #4 that is the most complete one @@ -350,7 +354,9 @@ int main(void) { prof_quit(); #if (DEBUG_MODE) + #if !(CALCEMU) usb_close(); + #endif #endif return 1; diff --git a/src/parameters.h b/src/parameters.h index 80409a5..f30588e 100644 --- a/src/parameters.h +++ b/src/parameters.h @@ -6,6 +6,7 @@ #define DEBUG_MODE 1 #define BIAS 1 #define NOBIAS (1-BIAS) + #define CALCEMU 1 #define SCALE_PIXEL 1 diff --git a/src/pinball_entities.h b/src/pinball_entities.h index 18145d7..9ba821e 100644 --- a/src/pinball_entities.h +++ b/src/pinball_entities.h @@ -179,11 +179,14 @@ public: uint16_t color; }; -struct Scene { +struct Scene +{ + /* some parameters to simulate the physics of the pinball */ Vector2D gravity; libnum::num32 dt; uint32_t score; bool pause; + std::vector borders; std::vector balls; std::vector obstacles; @@ -194,7 +197,6 @@ struct Scene { bool has_locker; std::vector locker; bool locker_is_enabled; - //Target Locker_enabler; libnum::num32 Lock_radius; Vector2D Lock_pos; uint16_t Lock_color; diff --git a/src/poly.cpp b/src/poly.cpp new file mode 100644 index 0000000..a376e6f --- /dev/null +++ b/src/poly.cpp @@ -0,0 +1,16 @@ +#include +#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 island2; @@ -566,10 +559,10 @@ void Setup_Table_4(void) { libnum::num32 flip_restitution = libnum::num32(0.0); Vector2D flip_pos1(libnum::num32(0.26), libnum::num32(0.22)); - MyPinball.flippers.emplace_back( flip_radius, flip_pos1, flip_length, -flip_restAngle, flip_maxRotation, flip_angularVelocity, flip_restitution, LEFT, RGB565_OCEANBLUE ); + MyPinball.flippers.emplace_back( flip_radius, flip_pos1, flip_length, -flip_restAngle, flip_maxRotation, flip_angularVelocity, flip_restitution, LEFT, RGB565_OCEANBLUE ); - Vector2D flip_pos2(libnum::num32(0.74), libnum::num32(0.22)); - MyPinball.flippers.emplace_back( flip_radius, flip_pos2, flip_length, libnum::num32(PI) + flip_restAngle, -flip_maxRotation, flip_angularVelocity, flip_restitution, RIGHT, RGB565_OCEANBLUE ); + Vector2D flip_pos2(libnum::num32(0.74), libnum::num32(0.22)); + MyPinball.flippers.emplace_back( flip_radius, flip_pos2, flip_length, libnum::num32(PI) + flip_restAngle, -flip_maxRotation, flip_angularVelocity, flip_restitution, RIGHT, RGB565_OCEANBLUE ); } #endif \ No newline at end of file diff --git a/src/utilities.h b/src/utilities.h index 94112bf..6364fa8 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -51,8 +51,6 @@ libnum::num32 COS(libnum::num32 angle) { float a = (float)angle; float c = cos(a); return libnum::num32(c); - - // return cos_num32( angle ); } libnum::num32 SIN(libnum::num32 angle) { @@ -60,8 +58,6 @@ libnum::num32 SIN(libnum::num32 angle) { float a = (float)angle; float s = sin(a); return libnum::num32(s); - - // return sin_num32( angle ); } extern libnum::num32 flipperHeight;