ScreenSaver/src/main.cpp

468 lines
13 KiB
C++

#include <gint/display.h>
#include <gint/keyboard.h>
#include <gint/dma.h>
#include <gint/rtc.h>
#include <gint/clock.h>
#include <fxlibc/printf.h>
#include "config.h"
#include <libprof.h>
#include <gint/kmalloc.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "utilities/fast_trig.h"
#include "utilities/extrakeyboard.h"
#include "utilities/utilities.h"
#include "effects/effects.h"
#include <string>
#define TOTAL_NB_EFFECT 17
typedef void (*PtrToFunc)( bopti_image_t * );
typedef void (*PtrToFuncDt)( bopti_image_t *, float );
typedef char* (*PtrTextFunc)( void );
PtrTextFunc Effect_Text[] = { &fire_text, &dotflag_text, &rotatesphere_text, &starfield_text, &motionblur_text, &moire_text, &linemorph_text, &spline_text, &splineblur_text, &rotozoom_text, &plasma_text, &morph_text, &lens_text, &firecube_text, &matrix_text, &morphfire_text, &raindrops_text };
PtrToFunc Effects_Init[] = { &fire_init, &dotflag_init, &rotatesphere_init, &starfield_init, &motionblur_init, &moire_init, &linemorph_init, &spline_init, &splineblur_init, &rotozoom_init, &plasma_init, &morph_init, &lens_init, &firecube_init, &matrix_init, &morphfire_init, &raindrops_init };
PtrToFuncDt Effects_Update[] = { &fire_update, &dotflag_update, &rotatesphere_update, &starfield_update, &motionblur_update, &moire_update, &linemorph_update, &spline_update, &splineblur_update, &rotozoom_update, &plasma_update, &morph_update, &lens_update, &firecube_update, &matrix_update, &morphfire_update, &raindrops_update };
PtrToFunc Effects_Render[] = { &fire_render, &dotflag_render, &rotatesphere_render, &starfield_render, &motionblur_render, &moire_render, &linemorph_render, &spline_render, &splineblur_render, &rotozoom_render, &plasma_render, &morph_render, &lens_render, &firecube_render, &matrix_render, &morphfire_render, &raindrops_render };
PtrToFunc Effects_DeInit[] = { &fire_deinit, &dotflag_deinit, &rotatesphere_deinit, &starfield_deinit, &motionblur_deinit, &moire_deinit, &linemorph_deinit, &spline_deinit, &splineblur_deinit, &rotozoom_deinit, &plasma_deinit, &morph_deinit, &lens_deinit, &firecube_deinit, &matrix_deinit, &morphfire_deinit, &raindrops_deinit };
int current_effect = 0;
#if(MORE_RAM)
static kmalloc_arena_t extended_ram = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0,0,0,0,0,0 };
static kmalloc_arena_t *_uram;
kmalloc_gint_stats_t *_uram_stats;
kmalloc_gint_stats_t *extram_stats;
#else
static kmalloc_arena_t *_uram;
kmalloc_gint_stats_t *_uram_stats;
#endif
bool exitToOS = false;
bool skip_intro = false;
bool screenshot = false;
bool record = false;
bool showFPS = false;
bool showName = true;
bool showOption = false;
bool EffectLoop = true;
uint8_t MenuOptionSelected = 1;
bool choosePrevious = false;
bool chooseNext = false;
int reverse = false;
float timeSinceLastEffect = 0.0f;
uint8_t effect_duration_seconds = 20;
KeyboardExtra Keyboard;
float elapsedTime = 0.0f;
uint32_t time_update=0, time_render=0;
prof_t perf_update, perf_render;
extern font_t font_matrix;
extern font_t font_label;
bopti_image_t *screen;
static void Initialise( void );
static void Update( void );
static void Render( void );
static void Close( void );
int get_pixel(bopti_image_t const *img, int x, int y)
{
return image_get_pixel(img, x, y);
}
void set_pixel(bopti_image_t *img, int x, int y, int color)
{
image_set_pixel(img, x, y, color);
}
bool AddMoreRAM( void )
{
#if(MORE_RAM && !CALCEMU)
/* allow more RAM */
char const *osv = (char*) 0x80020020;
if((!strncmp(osv, "03.", 3) && osv[3] <= '6') && 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 false;
}
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;
}
#elif (MORE_RAM && CALCEMU)
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
return false;
#endif
return false;
}
void FreeMoreRAM( void )
{
#if(MORE_RAM)
memset(extended_ram.start, 0, (char *)extended_ram.end - (char *)extended_ram.start);
#endif
}
static void GetInputs( [[maybe_unused]] float dt )
{
if (Keyboard.IsKeyPressed(MYKEY_EXIT)) {exitToOS = true; };
if (Keyboard.IsKeyPressedEvent(MYKEY_OPTN)) showOption = !showOption;
if ((Keyboard.IsKeyPressedEvent(MYKEY_F1) || choosePrevious) && current_effect>=1)
{
if (choosePrevious) choosePrevious = false;
timeSinceLastEffect = 0.0f;
// close the current effect by calling its DeInitFunction
Close();
// switch to new effect
current_effect--;
// initialise the current effect
Initialise();
}
if ((Keyboard.IsKeyPressedEvent(MYKEY_F6) || chooseNext) && current_effect<=TOTAL_NB_EFFECT-2)
{
if (chooseNext) chooseNext = false;
timeSinceLastEffect = 0.0f;
// close the current effect by calling its DeInitFunction
Close();
// switch to new effect
current_effect++;
// initialise the current effect
Initialise();
}
}
static void GetInputsOption( [[maybe_unused]] float dt )
{
//if (Keyboard.IsKeyPressed(MYKEY_EXIT)) {exitToOS = true; };
if (Keyboard.IsKeyPressedEvent(MYKEY_OPTN)) showOption = !showOption;
if (Keyboard.IsKeyPressedEvent(MYKEY_UP))
{
MenuOptionSelected--;
if (MenuOptionSelected==0) MenuOptionSelected=4;
}
if (Keyboard.IsKeyPressedEvent(MYKEY_DOWN))
{
MenuOptionSelected++;
if (MenuOptionSelected==5) MenuOptionSelected=1;
}
if (Keyboard.IsKeyPressedEvent(MYKEY_LEFT))
{
switch(MenuOptionSelected)
{
case 1:
showFPS = !showFPS;
break;
case 2:
showName = !showName;
break;
case 3:
EffectLoop = !EffectLoop;
break;
case 4:
effect_duration_seconds--;
if (effect_duration_seconds<5) effect_duration_seconds=5;
}
}
if (Keyboard.IsKeyPressedEvent(MYKEY_RIGHT))
{
switch(MenuOptionSelected)
{
case 1:
showFPS = !showFPS;
break;
case 2:
showName = !showName;
break;
case 3:
EffectLoop = !EffectLoop;
break;
case 4:
effect_duration_seconds++;
if (effect_duration_seconds>60) effect_duration_seconds=60;
}
}
}
static void ShowOptionBox( void )
{
extern bopti_image_t optionbox;
uint16_t w = optionbox.width;
uint16_t h = optionbox.height;
dimage( (DWIDTH-w)/2, (MAXHEIGHT-h)/2, &optionbox );
dfont( &font_label );
dprint( (DWIDTH-w)/2 +26, (MAXHEIGHT-h)/2 +6, C_RED, "Show FPS : %s", showFPS == true ? "< Yes >" : "< No >" );
dprint( (DWIDTH-w)/2 +25, (MAXHEIGHT-h)/2 +5, MenuOptionSelected==1 ? RGB565_LEMONYELLOW : RGB565_WHITE, "Show FPS : %s", showFPS == true ? "< Yes >" : "< No >" );
dprint( (DWIDTH-w)/2 +26, (MAXHEIGHT-h)/2 +26, C_RED, "Effect Name : %s", showName == true ? "< Yes >" : "< No >" );
dprint( (DWIDTH-w)/2 +25, (MAXHEIGHT-h)/2 +25, MenuOptionSelected==2 ? RGB565_LEMONYELLOW : RGB565_WHITE, "Effect Name : %s", showName == true ? "< Yes >" : "< No >" );
dprint( (DWIDTH-w)/2 +26, (MAXHEIGHT-h)/2 +46, C_RED, "Cycling : %s", EffectLoop == false ? "< Autoreverse >" : "< Loop >" );
dprint( (DWIDTH-w)/2 +25, (MAXHEIGHT-h)/2 +45, MenuOptionSelected==3 ? RGB565_LEMONYELLOW : RGB565_WHITE, "Cycling : %s", EffectLoop == false ? "< Autoreverse >" : "< Loop >" );
dprint( (DWIDTH-w)/2 +26, (MAXHEIGHT-h)/2 +66, C_RED, "Effect Duration : < %d s >", effect_duration_seconds );
dprint( (DWIDTH-w)/2 +25, (MAXHEIGHT-h)/2 +65, MenuOptionSelected==4 ? RGB565_LEMONYELLOW : RGB565_WHITE, "Effect Duration : < %d s >", effect_duration_seconds );
}
static void Initialise( void )
{
(*Effects_Init[ current_effect ])( screen );
}
static void Render( void )
{
(*Effects_Render[ current_effect ])( screen );
if(showFPS)
{
dfont( &font_label );
dprint( 11, 6, C_RED, "Framerate : %.0f FPS", (float) (1000000.0f/elapsedTime) );
dprint( 10, 5, C_WHITE, "Framerate : %.0f FPS", (float) (1000000.0f/elapsedTime) );
}
if (showName)
{
dfont( &font_label );
dprint( 11, 206, C_RED, "%s", (*Effect_Text[current_effect])() );
dprint( 10, 205, C_WHITE, "%s", (*Effect_Text[current_effect])() );
}
if(showOption)
{
ShowOptionBox();
}
}
static void Update( [[maybe_unused]] float dt )
{
(*Effects_Update[ current_effect ])( screen, dt );
}
static void Close( void )
{
(*Effects_DeInit[ current_effect ])( screen );
}
int main(void)
{
_uram = kmalloc_get_arena("_uram");
#if(MORE_RAM)
bool canWeAllocateMoreRam = AddMoreRAM();
#endif
int EntryClockLevel;
EntryClockLevel = clock_get_speed();
clock_set_speed( CLOCK_SPEED_F4 );
srand( rtc_ticks() );
screen = image_alloc( DWIDTH, MAXHEIGHT, IMAGE_P8_RGB565 );
screen->width = DWIDTH;
screen->height = MAXHEIGHT;
image_alloc_palette(screen, 256);
exitToOS = false;
Initialise();
__printf_enable_fp();
__printf_enable_fixed();
prof_init();
do
{
perf_update = prof_make();
prof_enter(perf_update);
{
// all the stuff to be update should be put here
Keyboard.Update( elapsedTime );
// read inputs from the player
if (!showOption) GetInputs( elapsedTime );
else GetInputsOption( elapsedTime );
// update as per the time spend to do the loop
Update( elapsedTime );
// update the RAM consumption status
_uram_stats = kmalloc_get_gint_stats(_uram);
#if(MORE_RAM)
extram_stats = kmalloc_get_gint_stats(&extended_ram);
#endif
}
prof_leave(perf_update);
time_update = prof_time(perf_update);
perf_render = prof_make();
prof_enter(perf_render);
{
// Call the render functions
Render();
dupdate();
}
prof_leave(perf_render);
time_render = prof_time(perf_render);
elapsedTime = ((float) (time_update+time_render));
timeSinceLastEffect += elapsedTime / 1000000.0f;
if (timeSinceLastEffect >= effect_duration_seconds)
{
if(EffectLoop)
{
Close();
current_effect++;
current_effect = current_effect % TOTAL_NB_EFFECT;
timeSinceLastEffect = 0.0f;
Initialise();
}
else
{
if(!reverse)
{
if(current_effect<TOTAL_NB_EFFECT-1) chooseNext=true;
else
{
reverse = true;
choosePrevious = true;
}
}
else
{
if(current_effect>0) choosePrevious=true;
else
{
reverse = false;
chooseNext = true;
}
}
}
}
}
while (exitToOS==false);
Close();
image_free( screen );
prof_quit();
clock_set_speed( EntryClockLevel );
#if(MORE_RAM)
if (canWeAllocateMoreRam) FreeMoreRAM( );
#endif
return 1;
}