349 lines
7.5 KiB
C++
349 lines
7.5 KiB
C++
#include "util.h"
|
|
|
|
#include <gint/display.h>
|
|
#include <gint/keyboard.h>
|
|
#include <gint/timer.h>
|
|
#include <gint/gint.h>
|
|
#include <gint/cpu.h>
|
|
#include <gint/defs/util.h>
|
|
|
|
//---
|
|
// Internal timers routines
|
|
//---
|
|
|
|
static int __menu_offset_update(int *menu_offset)
|
|
{
|
|
if(*menu_offset < 0)
|
|
*menu_offset = min(*menu_offset + 6, 0);
|
|
if(*menu_offset > 0)
|
|
*menu_offset = max(*menu_offset - 6, 0);
|
|
|
|
return TIMER_CONTINUE;
|
|
}
|
|
|
|
static int __title_blink_update(int *blink)
|
|
{
|
|
*blink ^= 1;
|
|
return TIMER_CONTINUE;
|
|
}
|
|
|
|
//---
|
|
// Internal menu content management
|
|
//---
|
|
|
|
#define annimX(x) ((x) + offset)
|
|
#define annimY(y) (y)
|
|
|
|
static void menu_display_start(int offset, int title_blink)
|
|
{
|
|
extern image_t img_bosonx_logo;
|
|
extern image_t img_bosonx_title;
|
|
|
|
dimage(
|
|
annimX((DWIDTH / 2) - (img_bosonx_logo.width / 2)),
|
|
annimY((DHEIGHT / 4) - (img_bosonx_logo.height / 2) - 6),
|
|
&img_bosonx_logo
|
|
);
|
|
dimage(
|
|
annimX((DWIDTH / 2) - (img_bosonx_title.width / 2)),
|
|
annimY((DHEIGHT / 2) - (img_bosonx_title.height / 2)),
|
|
&img_bosonx_title
|
|
);
|
|
dtext_opt(
|
|
annimX(DWIDTH / 2),
|
|
annimY((DHEIGHT / 2) + 18),
|
|
C_WHITE, C_NONE,
|
|
DTEXT_CENTER, DTEXT_TOP,
|
|
" status: undiscovered"
|
|
);
|
|
if (title_blink != 0 && offset == 0) {
|
|
dtext_opt(
|
|
DWIDTH / 2,
|
|
(DHEIGHT / 2) + 48,
|
|
C_WHITE, C_NONE,
|
|
DTEXT_CENTER, DTEXT_TOP,
|
|
"PRESS SHIFT TO START"
|
|
);
|
|
}
|
|
}
|
|
|
|
static void menu_display_about(int offset)
|
|
{
|
|
extern image_t img_bosonx_logo_empty;
|
|
extern image_t img_lepheyatis_logo;
|
|
|
|
dimage(
|
|
annimX((DWIDTH / 2) - (img_bosonx_logo_empty.width / 2)),
|
|
annimY((DHEIGHT / 4) - (img_bosonx_logo_empty.height / 2) - 6),
|
|
&img_bosonx_logo_empty
|
|
);
|
|
dimage(
|
|
annimX((DWIDTH / 2) - (img_lepheyatis_logo.width / 2)),
|
|
annimY((DHEIGHT / 2) + (DHEIGHT / 4) - (img_lepheyatis_logo.height / 2) - 15),
|
|
&img_lepheyatis_logo
|
|
);
|
|
|
|
dtext(annimX(8), annimY( 6), C_WHITE, "BIBLIOGRAPHY");
|
|
dtext(annimX(8), annimY(16), C_WHITE, "and acknowledgments");
|
|
dline(annimX(6), annimY(28), annimX(DWIDTH - 6), annimY(28), C_WHITE);
|
|
|
|
dtext_opt(
|
|
annimX(DWIDTH/ 2),
|
|
annimY(47),
|
|
C_WHITE, C_NONE,
|
|
DTEXT_CENTER, DTEXT_MIDDLE,
|
|
"ORIGINAL GAME BY IAN MACLARTY AND JON KERNEY"
|
|
);
|
|
dtext_opt(
|
|
annimX(DWIDTH/ 2),
|
|
annimY(60),
|
|
C_WHITE, C_NONE,
|
|
DTEXT_CENTER, DTEXT_MIDDLE,
|
|
"www.boson-x.com"
|
|
);
|
|
|
|
dtext_opt(
|
|
annimX(DWIDTH / 2),
|
|
annimY(DHEIGHT / 2) - 5,
|
|
C_WHITE, C_NONE,
|
|
DTEXT_CENTER, DTEXT_MIDDLE,
|
|
"ADAPTED BY LEPHENIXNOIR AND YATIS"
|
|
);
|
|
}
|
|
|
|
//---
|
|
// public
|
|
//---
|
|
|
|
int menu_title(void)
|
|
{
|
|
volatile int title_blink;
|
|
int selected = 0;
|
|
int timer0;
|
|
int timer1;
|
|
unsigned int exit;
|
|
uint16_t start_col;
|
|
uint16_t about_col;
|
|
volatile int menu_offset = 0;
|
|
|
|
timer0 = timer_configure(
|
|
TIMER_ANY,
|
|
3300,
|
|
GINT_CALL(&__menu_offset_update, &menu_offset)
|
|
);
|
|
|
|
title_blink = 1;
|
|
timer1 = timer_configure(
|
|
TIMER_ANY,
|
|
500000,
|
|
GINT_CALL(&__title_blink_update, &title_blink)
|
|
);
|
|
|
|
timer_start(timer0);
|
|
timer_start(timer1);
|
|
|
|
exit = 0xdeadbeef;
|
|
selected = 0;
|
|
while(exit == 0xdeadbeef)
|
|
{
|
|
dclear(RGB24(0x49759f));
|
|
|
|
/* Load atomically to avoid data races */
|
|
int off = menu_offset;
|
|
/* Display the current screen, and the one next to it if sliding */
|
|
int show_left = selected - (selected > 0 && off > 0);
|
|
int show_right = show_left + (off != 0);
|
|
|
|
for(int i = show_left; i <= show_right; i++)
|
|
{
|
|
int offset = off + DWIDTH * (i - selected);
|
|
|
|
if(i == 0)
|
|
menu_display_start(offset, title_blink);
|
|
if(i == 1)
|
|
menu_display_about(offset);
|
|
}
|
|
|
|
drect(0, DHEIGHT - 32, DWIDTH, DHEIGHT, C_WHITE);
|
|
drect_border(
|
|
(DWIDTH / 4) - 35 + ((DWIDTH / 2) * selected),
|
|
DHEIGHT - 27,
|
|
(DWIDTH / 4) + 35 + ((DWIDTH / 2) * selected),
|
|
DHEIGHT - 5,
|
|
C_NONE,
|
|
2, RGB24(0xca8a8a)
|
|
);
|
|
start_col = RGB24(0xca8a8a);
|
|
about_col = RGB24(0x49759f);
|
|
if (selected == 1) {
|
|
start_col = RGB24(0x49759f);
|
|
about_col = RGB24(0xca8a8a);
|
|
}
|
|
dtext_opt(
|
|
DWIDTH / 4,
|
|
DHEIGHT - 20,
|
|
start_col, C_NONE,
|
|
DTEXT_CENTER,
|
|
DTEXT_TOP,
|
|
"START"
|
|
);
|
|
dtext_opt(
|
|
(DWIDTH / 2) + (DWIDTH / 4),
|
|
DHEIGHT - 20,
|
|
about_col, C_NONE,
|
|
DTEXT_CENTER,
|
|
DTEXT_TOP,
|
|
"ABOUT"
|
|
);
|
|
|
|
dupdate();
|
|
|
|
key_event_t ev;
|
|
while((ev = pollevent()).type != KEYEV_NONE) {
|
|
if(ev.type == KEYEV_UP || ev.type == KEYEV_HOLD)
|
|
continue;
|
|
if (ev.key == KEY_SHIFT && selected == 0) exit = 0;
|
|
if (ev.key == KEY_LEFT && selected > 0) {
|
|
selected--;
|
|
menu_offset = -DWIDTH;
|
|
}
|
|
if (ev.key == KEY_RIGHT && selected < 1) {
|
|
selected++;
|
|
menu_offset = DWIDTH;
|
|
}
|
|
if (ev.key == KEY_MENU || ev.key == KEY_EXIT) exit = -1;
|
|
}
|
|
}
|
|
|
|
timer_stop(timer1);
|
|
timer_stop(timer0);
|
|
return exit;
|
|
}
|
|
|
|
|
|
int menu_select_level(int *select)
|
|
{
|
|
extern image_t img_bosonx_logo_empty;
|
|
extern image_t img_stage1;
|
|
extern image_t img_stage2;
|
|
extern image_t img_stage3;
|
|
extern image_t img_stage4;
|
|
extern image_t img_stage5;
|
|
extern image_t img_stage6;
|
|
struct {
|
|
image_t *img;
|
|
int peak;
|
|
char const * const name;
|
|
} stage[6] = {
|
|
{ .img = &img_stage1, .peak = 10, .name = "GEON" },
|
|
{ .img = &img_stage2, .peak = 56, .name = "ACCELERON"},
|
|
{ .img = &img_stage3, .peak = 34, .name = "RADION"},
|
|
{ .img = &img_stage4, .peak = 100, .name = "GRAVITON"},
|
|
{ .img = &img_stage5, .peak = 245, .name = "Y BOSON"},
|
|
{ .img = &img_stage6, .peak = -1, .name = "X BOSON"},
|
|
};
|
|
unsigned int exit;
|
|
int selected;
|
|
int color;
|
|
int colorb;
|
|
char const *text;
|
|
int x;
|
|
int y;
|
|
|
|
selected = 0;
|
|
exit = 0xdeadbeef;
|
|
while (exit == 0xdeadbeef) {
|
|
dclear(RGB24(0x49759f));
|
|
|
|
dimage(
|
|
(DWIDTH / 2) - (img_bosonx_logo_empty.width / 2),
|
|
(DHEIGHT / 4) - (img_bosonx_logo_empty.height / 2) - 6,
|
|
&img_bosonx_logo_empty
|
|
);
|
|
|
|
dtext(8, 6, C_WHITE, stage[selected].name);
|
|
dtext(8, 16, C_WHITE, "select experiment");
|
|
dline(6, 28, DWIDTH - 6, 28, C_WHITE);
|
|
|
|
for (int i = 0; i < 6; ++i)
|
|
{
|
|
x = 14 + ((i % 3) * 128);
|
|
y = 55 + ((i / 3) * 72);
|
|
|
|
if (i == selected) {
|
|
drect_border(
|
|
x - 4, y - 4, x + 121, y + 66, C_NONE,
|
|
2, RGB24(0xcc8181)
|
|
);
|
|
}
|
|
|
|
color = RGB24(0xb2ccd4);
|
|
colorb = RGB24(0x648da7);
|
|
if (stage[i].peak < 100) {
|
|
color = RGB24(0xd8d7ce);
|
|
colorb = RGB24(0x7492a4);
|
|
}
|
|
if (stage[i].peak < 0) {
|
|
color = RGB24(0x5686ad);
|
|
colorb = RGB24(0x3c79a9);
|
|
}
|
|
drect(x, y, x + 115, y + 60, color);
|
|
dline(x + 116, y + 1, x + 116, y + 61, colorb);
|
|
dline(x + 117, y + 2, x + 117, y + 62, colorb);
|
|
dline(x + 1, y + 61, x + 116, y + 61, colorb);
|
|
dline(x + 2, y + 62, x + 116, y + 62, colorb);
|
|
|
|
if (stage[i].peak < 0)
|
|
continue;
|
|
|
|
dimage(x + 4, y + 4, stage[i].img);
|
|
|
|
dline(x + 4, y + 32, x + 101, y + 32, RGB24(0x2d4e6a));
|
|
|
|
text = "DISCOVERED";
|
|
color = RGB24(0x47a2c9);
|
|
if (stage[i].peak < 100) {
|
|
color = RGB24(0xcc8181);
|
|
text = "UNDISCOVERED";
|
|
}
|
|
dtext(x + 4, y + 35, color, text);
|
|
|
|
drect(x + 4, y + 48, x + 9, y + 53, color);
|
|
dprint(
|
|
x + 14,
|
|
y + 46,
|
|
RGB24(0x2d4e6a),
|
|
"peak: %d%%",
|
|
stage[i].peak
|
|
);
|
|
}
|
|
|
|
dupdate();
|
|
|
|
key_event_t ev;
|
|
while((ev = pollevent()).type != KEYEV_NONE) {
|
|
if(ev.type == KEYEV_UP || ev.type == KEYEV_HOLD)
|
|
continue;
|
|
if (ev.key == KEY_LEFT) selected -= 1;
|
|
if (ev.key == KEY_RIGHT) selected += 1;
|
|
if (ev.key == KEY_EXIT) exit = -1;
|
|
if (ev.key == KEY_SHIFT) exit = 0;
|
|
if (ev.key == KEY_MENU) gint_osmenu();
|
|
if (ev.key == KEY_DOWN && selected < 3) selected += 3;
|
|
if (ev.key == KEY_UP && selected > 2) selected -= 3;
|
|
}
|
|
|
|
if (selected >= 6) selected = 5;
|
|
if (selected < 0) selected = 0;
|
|
while (selected > 0) {
|
|
if (stage[selected].peak >= 0)
|
|
break;
|
|
selected -= 1;
|
|
}
|
|
}
|
|
|
|
if (select != NULL)
|
|
*select = selected;
|
|
return exit;
|
|
}
|