#include "gint/display-cg.h" #include "gint/display.h" #include "parameters.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "extrakeyboard.h" #include "pinball_entities.h" #include "simulations.h" #include "stdint-gcc.h" #include "tables.h" #include "utilities.h" #include "vector2D.h" #include #include "tables.h" #include bool screenshot = false; bool record = false; bool textoutput = false; bool exitToOS = false; uint8_t texttodraw = 1; #define SCALE_PIXEL 1 #define X_RESOL (DWIDTH / SCALE_PIXEL) #define Y_RESOL (DHEIGHT / SCALE_PIXEL) float elapsedTime = 0.0f; float cumulatedTime = 0.0f; uint32_t time_update = 0, time_render = 0; prof_t perf_update, perf_render; static kmalloc_arena_t extended_ram = {0}; static kmalloc_arena_t *_uram; kmalloc_gint_stats_t *_uram_stats; kmalloc_gint_stats_t *extram_stats; KeyboardExtra MyKeyboard; Scene MyPinball; libnum::num32 flipperHeight; libnum::num32 cScale; libnum::num32 simWidth; libnum::num32 simHeight; /* create the pinball board */ void SetupScene(int which_table) { if (which_table == 0) Setup_Table_0(); else if (which_table == 1) Setup_Table_1(); else if (which_table == 2) Setup_Table_2(); else if (which_table == 3) Setup_Table_3(); else if (which_table == 4) Setup_Table_4(); else Setup_Table_0(); cumulatedTime = 0.0f; } static void hook_prefrag(int id, void *fragment, int size) { if (!screenshot && !record) return; /* Screenshot takes precedence */ char const *type = screenshot ? "image" : "video"; int pipe = usb_ff_bulk_output(); if (id == 0) { usb_fxlink_header_t h; usb_fxlink_image_t sh; int size = azrp_width * azrp_height * 2; usb_fxlink_fill_header(&h, "fxlink", type, size + sizeof sh); sh.width = htole32(azrp_width); sh.height = htole32(azrp_height); sh.pixel_format = htole32(USB_FXLINK_IMAGE_RGB565); usb_write_sync(pipe, &h, sizeof h, false); usb_write_sync(pipe, &sh, sizeof sh, false); } usb_write_sync(pipe, fragment, size, false); if (id == azrp_frag_count - 1) { usb_commit_sync(pipe); screenshot = false; } } static void update(float dt) { MyPinball.dt = libnum::num32(dt); if (cumulatedTime>1.0f) MyPinball.locker_is_enabled = true; for (int i = 0; i < MyPinball.flippers.size(); i++) MyPinball.flippers[i].Simulate(MyPinball.dt); for (int i = 0; i < MyPinball.balls.size(); i++) { /* Update the position of the flippers */ MyPinball.balls[i].Simulate(MyPinball.dt, MyPinball.gravity); /* Update the balls and check for collisions between balls (if more than two * balls) */ if (MyPinball.balls.size() >= 2) { for (int j = 0; j < MyPinball.balls.size(); j++) if (i != j) HandleBallBallCollision(&MyPinball.balls[i], &MyPinball.balls[j]); } /* Check for collision with bumpers (improve the score) */ for (int j = 0; j < MyPinball.obstacles.size(); j++) HandleBallObstacleCollision(&MyPinball.balls[i], MyPinball.obstacles[j]); /* Check for collision with islands (geometric forms to deviate the balls)*/ for (int j = 0; j < MyPinball.islands.size(); j++) { HandleBallIslandCollision(&MyPinball.balls[i], MyPinball.islands[j], libnum::num(0.01)); } /* Check for collision with the pinball entry locker borders */ if (MyPinball.has_locker && MyPinball.locker_is_enabled) HandleBallIslandCollision(&MyPinball.balls[i], MyPinball.locker, libnum::num(0.01)); /* Check for collision with flippers */ for (int j = 0; j < MyPinball.flippers.size(); j++) HandleBallFlipperCollision(&MyPinball.balls[i], MyPinball.flippers[j]); /* Check for collision with the pinball borders */ HandleBallBorderCollision(&MyPinball.balls[i], MyPinball.borders); } } static void render(void) { /* Clear Screen */ azrp_clear(RGB565_BLACK); if (MyPinball.sideimage != nullptr) azrp_image_p8(azrp_width - MyPinball.sideimage->width - 25, 5, MyPinball.sideimage, DIMAGE_NONE); CollectionRender( MyPinball.borders, RGB565_WHITE ); if (MyPinball.has_locker) CollectionRender( MyPinball.locker, MyPinball.locker_is_enabled ? RGB565_WHITE : RGB565_BLOODYRED); for (int i = 0; i < MyPinball.obstacles.size(); i++) MyPinball.obstacles[i].Render(); for (int i = 0; i < MyPinball.islands.size(); i++) CollectionRender( MyPinball.islands[i] , RGB565_WHITE); for (int i = 0; i < MyPinball.balls.size(); i++) MyPinball.balls[i].Render(); for (int i = 0; i < MyPinball.flippers.size(); i++) MyPinball.flippers[i].Render(); // azrp_draw_text(150, 0, "FPS = %.0f - Mem Free = %d - Time = %.2 f" , // (float)(1.0f / elapsedTime), // _uram_stats->free_memory + extram_stats->free_memory, cumulatedTime); azrp_draw_pinball(250, 200, RGB565_DEEPPURPLE, "Score:%d", MyPinball.score); } static void get_inputs(float dt) { /* EXIT THE GAME */ if (MyKeyboard.IsKeyPressed(MYKEY_SHIFT) && MyKeyboard.IsKeyHoldPressed(MYKEY_EXIT)) { exitToOS = true; }; /* LEFT FLIPPER */ if (MyKeyboard.IsKeyPressed(MYKEY_F1)) { for (int i = 0; i < MyPinball.flippers.size(); i++) if (MyPinball.flippers[i].side == LEFT) MyPinball.flippers[i].touchIdentifier = libnum::num32(0); } else { for (int i = 0; i < MyPinball.flippers.size(); i++) if (MyPinball.flippers[i].side == LEFT) MyPinball.flippers[i].touchIdentifier = libnum::num32(-1); } /* RIGHT FLIPPER */ if (MyKeyboard.IsKeyPressed(MYKEY_F6)) { for (int i = 0; i < MyPinball.flippers.size(); i++) if (MyPinball.flippers[i].side == RIGHT) MyPinball.flippers[i].touchIdentifier = libnum::num32(0); } else { for (int i = 0; i < MyPinball.flippers.size(); i++) if (MyPinball.flippers[i].side == RIGHT) MyPinball.flippers[i].touchIdentifier = libnum::num32(-1); } /* RESET THE GAME */ if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyHoldPressed(MYKEY_F1)) { SetupScene(0); } if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyHoldPressed(MYKEY_F2)) { SetupScene(1); } if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyHoldPressed(MYKEY_F3)) { SetupScene(2); } if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyHoldPressed(MYKEY_F4)) { SetupScene(3); } if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyHoldPressed(MYKEY_F5)) { SetupScene(4); } // TODO : to be changed to remove cumulatedTime if (MyKeyboard.IsKeyReleasedEvent(MYKEY_VARS) && MyPinball.has_locker && cumulatedTime<1.0f) { MyPinball.locker_is_enabled = !MyPinball.locker_is_enabled; } #if (DEBUG_MODE) if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyPressedEvent(MYKEY_7) && usb_is_open()) { screenshot = true; }; if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyPressedEvent(MYKEY_8) && usb_is_open()) { record = true; }; if (MyKeyboard.IsKeyPressed(MYKEY_OPTN) && MyKeyboard.IsKeyPressedEvent(MYKEY_9) && usb_is_open()) { record = false; }; #endif /* we can have either LEFT or RIGHT or NONE OF THEM pressed for the direction */ } bool AddMoreRAM(void) { /* allow more RAM */ char const *osv = (char *)0x80020020; if ((!strncmp(osv, "03.", 3) && osv[3] <= '8') && gint[HWCALC] == HWCALC_FXCG50) // CG-50 { extended_ram.name = "extram"; extended_ram.is_default = true; extended_ram.start = (void *)0x8c200000; extended_ram.end = (void *)0x8c4e0000; kmalloc_init_arena(&extended_ram, true); kmalloc_add_arena(&extended_ram); return true; } else if (gint[HWCALC] == HWCALC_PRIZM) // CG-10/20 { extended_ram.name = "extram"; extended_ram.is_default = true; uint16_t *vram1, *vram2; dgetvram(&vram1, &vram2); dsetvram(vram1, vram1); extended_ram.start = vram2; extended_ram.end = (char *)vram2 + 396 * 224 * 2; kmalloc_init_arena(&extended_ram, true); kmalloc_add_arena(&extended_ram); return true; } else if (gint[HWCALC] == HWCALC_FXCG_MANAGER) // CG-50 EMULATOR { extended_ram.name = "extram"; extended_ram.is_default = true; extended_ram.start = (void *)0x88200000; extended_ram.end = (void *)0x884e0000; kmalloc_init_arena(&extended_ram, true); kmalloc_add_arena(&extended_ram); return true; } else { return false; } } void FreeMoreRAM(void) { memset(extended_ram.start, 0, (char *)extended_ram.end - (char *)extended_ram.start); } int main(void) { exitToOS = false; _uram = kmalloc_get_arena("_uram"); bool canWeAllocate3Mb = AddMoreRAM(); __printf_enable_fp(); __printf_enable_fixed(); 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); usb_interface_t const *interfaces[] = {&usb_ff_bulk, NULL}; usb_open(interfaces, GINT_CALL_NULL); SetupScene(4); prof_init(); do { perf_update = prof_make(); prof_enter(perf_update); { // all the stuff to be update should be put here MyKeyboard.Update(); get_inputs(elapsedTime); update(elapsedTime); // update the RAM consumption status _uram_stats = kmalloc_get_gint_stats(_uram); extram_stats = kmalloc_get_gint_stats(&extended_ram); } prof_leave(perf_update); time_update = prof_time(perf_update); perf_render = prof_make(); prof_enter(perf_render); { // all the stuff to be rendered should be put here render(); azrp_update(); } prof_leave(perf_render); time_render = prof_time(perf_render); /* elapsedTime expressed in microseconds when coming from the libprof high * accuracy time measurement */ // elapsedTime = ((float)(time_update + time_render)) / 1000000.0f; elapsedTime = ((float)1.0f / 60.0f); cumulatedTime += elapsedTime; } while (exitToOS == false); prof_quit(); usb_close(); if (canWeAllocate3Mb) FreeMoreRAM(); return 1; }