fully implement options menu

This commit is contained in:
Zack Buhman 2025-07-04 12:49:37 -05:00
parent dbd3fdba88
commit 4f185a32c6
11 changed files with 393 additions and 25 deletions

View File

@ -17,6 +17,9 @@
namespace cursor {
float mouse_speed = 1.0;
float stick_speed = 1.0;
struct cursor state[4];
void init()
@ -41,8 +44,8 @@ namespace cursor {
auto& data = data_fields.data;
float dx = static_cast<float>(data.analog_coordinate_axis[2] - 0x80) * 0.015;
float dy = static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * 0.015;
float dx = static_cast<float>(data.analog_coordinate_axis[2] - 0x80) * stick_speed * 0.108;
float dy = static_cast<float>(data.analog_coordinate_axis[3] - 0x80) * stick_speed * 0.108;
state[port_ix].x += dx;
state[port_ix].y += dy;
@ -57,8 +60,8 @@ namespace cursor {
if ((std::byteswap(data_fields.function_type) & function_type::pointing) == 0)
continue;
auto& data = data_fields.data;
float dx = static_cast<float>(data.analog_coordinate_axis[0] - 0x200) * 0.65;
float dy = static_cast<float>(data.analog_coordinate_axis[1] - 0x200) * 0.65;
float dx = static_cast<float>(data.analog_coordinate_axis[0] - 0x200) * mouse_speed * 0.95;
float dy = static_cast<float>(data.analog_coordinate_axis[1] - 0x200) * mouse_speed * 0.95;
state[port_ix].x += dx;
state[port_ix].y += dy;
state[port_ix].a = ft9::data_transfer::digital_button::a(data.digital_button) == 0;

View File

@ -2,6 +2,9 @@
namespace cursor {
extern float mouse_speed;
extern float stick_speed;
struct cursor {
bool active;
float x;

View File

@ -5,21 +5,28 @@
#include "scene/scene.hpp"
#include "scene/options/scene.hpp"
#include "widget/button_label.hpp"
#include "widget/button_icon.hpp"
#include "widget/button_label_tl.hpp"
#include "widget/left_aligned.hpp"
#include "widget/top_aligned.hpp"
#include "widget/label.hpp"
#include "widget/label_tl.hpp"
#include "graphics_primitive.hpp"
#include "cursor.hpp"
#include "framebuffer.hpp"
#include "graphics.hpp"
#include "ta_parameter.hpp"
#include "sound.hpp"
#include "aica/aica.hpp"
#include "sh7091/sh7091_bits.hpp"
#define __length(c) ((sizeof (c)) / (sizeof (c[0])))
uint32_t alpha = 0xcf000000;
const static uint32_t alpha = 0xcf000000;
static int mvol = 0;
static int int_mouse_speed = 20;
static int int_stick_speed = 20;
void position_left()
{
@ -67,46 +74,111 @@ void position_down()
void resolution_640x480()
{
uint32_t sr;
asm volatile ("stc sr,%0" : "=r" (sr));
sr |= sh::sr::imask(15);
asm volatile ("ldc %0,sr" : : "r" (sr));
printf("640x480\n");
spg_set_mode_640x480();
framebuffer.px_width = 640;
framebuffer.px_height = 480;
framebuffer_init();
graphics_scene_init(&scene::current_scene->opb_size);
sr &= ~sh::sr::imask(15);
asm volatile ("ldc %0,sr" : : "r" (sr));
}
void resolution_720x480()
{
uint32_t sr;
asm volatile ("stc sr,%0" : "=r" (sr));
sr |= sh::sr::imask(15);
asm volatile ("ldc %0,sr" : : "r" (sr));
printf("720x480\n");
spg_set_mode_720x480();
framebuffer.px_width = 720;
framebuffer.px_height = 480;
framebuffer_init();
graphics_scene_init(&scene::current_scene->opb_size);
sr &= ~sh::sr::imask(15);
asm volatile ("ldc %0,sr" : : "r" (sr));
}
void mvol_plus()
{
mvol += 1;
if (mvol > 0xf)
mvol = 0xf;
wait(); aica_sound.common.MVOL(mvol);
}
void mvol_minus()
{
mvol -= 1;
if (mvol < 0)
mvol = 0;
wait(); aica_sound.common.MVOL(mvol);
}
void mouse_speed_plus()
{
int_mouse_speed += 1;
if (int_mouse_speed > 99)
int_mouse_speed = 99;
cursor::mouse_speed = (float)int_mouse_speed / 20.0;
}
void mouse_speed_minus()
{
int_mouse_speed -= 1;
if (int_mouse_speed < 1)
int_mouse_speed = 1;
cursor::mouse_speed = (float)int_mouse_speed / 20.0;
}
void stick_speed_plus()
{
int_stick_speed += 1;
if (int_stick_speed > 99)
int_stick_speed = 99;
cursor::stick_speed = (float)int_stick_speed / 20.0;
}
void stick_speed_minus()
{
int_stick_speed -= 1;
if (int_stick_speed < 1)
int_stick_speed = 1;
cursor::stick_speed = (float)int_stick_speed / 20.0;
}
namespace scene::options {
widget::button_label up_button(31, 0, 30, 30, "\x18", position_up);
widget::button_label down_button(31, 0, 30, 30, "\x19", position_down);
widget::button_label right_button(30, 30, "\x1a", position_right);
widget::button_label left_button(30, 30, "\x1b", position_left);
widget::button_label_tl up_button(31, 0, 30, 30, "\x18", position_up);
widget::button_label_tl down_button(31, 0, 30, 30, "\x19", position_down);
widget::button_label_tl right_button(30, 30, "\x1a", position_right);
widget::button_label_tl left_button(30, 30, "\x1b", position_left);
widget::button_label _640x480_button(100, 46, "640x480", resolution_640x480);
widget::button_label _720x480_button(100, 46, "720x480", resolution_720x480);
widget::button_label_tl _640x480_button(100, 46, "640x480", resolution_640x480);
widget::button_label_tl _720x480_button(100, 46, "720x480", resolution_720x480);
widget::button_label mouse_minus_button(30, 30, "-", nullptr);
widget::button_label mouse_plus_button(30, 30, "+", nullptr);
widget::button_label stick_minus_button(30, 30, "-", nullptr);
widget::button_label stick_plus_button(30, 30, "+", nullptr);
widget::button_label master_volume_minus_button(30, 30, "-", nullptr);
widget::button_label master_volume_plus_button(30, 30, "+", nullptr);
widget::button_label_tl mouse_minus_button(30, 30, "-", mouse_speed_minus);
widget::button_label_tl mouse_plus_button(30, 30, "+", mouse_speed_plus);
widget::button_label_tl stick_minus_button(30, 30, "-", stick_speed_minus);
widget::button_label_tl stick_plus_button(30, 30, "+", stick_speed_plus);
widget::button_label_tl master_volume_minus_button(30, 30, "-", mvol_minus);
widget::button_label_tl master_volume_plus_button(30, 30, "+", mvol_plus);
widget::widget spacer(30, 30);
widget::label position1_label(15 * glyph::hori_advance, 20, "screen position");
widget::label mouse_speed_label(11 * glyph::hori_advance, 20, "mouse speed");
widget::label stick_speed_label(11 * glyph::hori_advance, 20, "stick speed");
widget::label master_volume_label(13 * glyph::hori_advance, 20, "master volume");
widget::label_tl position1_label(15 * glyph::hori_advance, 20, "screen position");
widget::label_tl mouse_speed_label(11 * glyph::hori_advance, 20, "mouse speed");
widget::label_tl stick_speed_label(11 * glyph::hori_advance, 20, "stick speed");
widget::label_tl master_volume_label(13 * glyph::hori_advance, 20, "master volume");
widget::label_tl resolution_label(10, 0, 10 * glyph::hori_advance, 20, "resolution");
widget::widget * row1_children[] = {
//&spacer,
@ -137,7 +209,6 @@ namespace scene::options {
int position_length = __length(position_children);
widget::top_aligned position(0, 0, 1, position_children, position_length);
widget::label resolution_label(10, 0, 10 * glyph::hori_advance, 20, "resolution");
widget::widget * resolution_children[] = {
&resolution_label,
&_640x480_button,
@ -296,12 +367,36 @@ namespace scene::options {
alpha | 0x202020);
}
void draw_values(ta_parameter_writer& writer)
{
transfer_global_polygon_glyph(writer);
// mouse speed
transfer_integer(writer, int_mouse_speed,
53, 182, 10.0 / 10.0,
2, ' ',
0xffffff);
// stick speed
transfer_integer(writer, int_stick_speed,
188, 182, 10.0 / 10.0,
2, ' ',
0xffffff);
// master volume
transfer_integer(writer, mvol,
52, 254, 10.0 / 10.0,
2, ' ',
0xffffff);
}
void transfer(ta_multiwriter& multi)
{
update();
top.draw(multi);
draw_corners(multi.op);
draw_shroud(multi.op);
draw_values(multi.pt);
}
void interrupt()
@ -316,6 +411,9 @@ namespace scene::options {
holly.VO_BORDER_COL = 0x110012;
*/
top.freeze(15, 15);
wait();
mvol = 0xc;
}
int done()

View File

@ -0,0 +1,31 @@
#include "button_label_tl.hpp"
#include "graphics_primitive.hpp"
namespace widget {
const static float label_depth = 10.0 / 5.0;
const static int label_color = 0xffffff;
const static float label_shadow_depth = 10.0 / 6.0;
const static int label_shadow_color = 0x000000;
void button_label_tl::draw_label(ta_parameter_writer& writer) const
{
float y_offset = (float)(click_state != click_type::release);
float cx = x() + width / 2 - (glyph::hori_advance * label_length) / 2;
float cy = y() + height / 2 - glyph::vert_advance / 2 + y_offset;
transfer_string(writer, label, cx, cy, label_depth, label_color);
}
void button_label_tl::draw(ta_multiwriter& multi)
{
transfer_global_polygon_glyph(multi.pt);
draw_label(multi.pt);
button_tl::draw(multi);
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "holly/ta_parameter.hpp"
#include "widget/button_tl.hpp"
namespace widget {
struct button_label_tl : button_tl {
const char * const label;
const int label_length;
inline button_label_tl(float _width, float _height, const char * label, void (* const _on_click)())
: button_tl(0, 0, _width, _height, _on_click), label(label), label_length(str_length(label))
{ }
inline button_label_tl(float _x, float _y, float _width, float _height, const char * label, void (* const _on_click)())
: button_tl(_x, _y, _width, _height, _on_click), label(label), label_length(str_length(label))
{ }
void draw_label(ta_parameter_writer& writer) const;
void draw(ta_multiwriter& multi) override;
};
}

120
src/widget/button_tl.cpp Normal file
View File

@ -0,0 +1,120 @@
#include "widget/button_tl.hpp"
#include "ta_parameter.hpp"
#include "graphics_primitive.hpp"
namespace widget {
const static int alpha = 0x8000000;
const static float shadow_depth = 10.0 / 10.0;
const static int shadow_color = alpha | 0x0000000;
const static float lowlight_depth = 10.0 / 9.0;
const static int lowlight_color = alpha | 0x0c0d0d;
const static float highlight_depth = 10.0 / 8.0;
const static int highlight_color = alpha | 0x353a3a;
const static int highlight_click_color = alpha | 0x141616;
const static float background_depth = 10.0 / 7.0;
const static int background_color = 0x282c2c;
void button_tl::draw_shadow(ta_parameter_writer& writer) const
{
{
float x0 = x() + 1;
float x1 = x() + width - 1;
float y0 = y();
float y1 = y() + height;
quad_type_0(writer,
{x0, y0, shadow_depth},
{x1, y0, shadow_depth},
{x1, y1, shadow_depth},
{x0, y1, shadow_depth},
shadow_color);
}
{
float x0 = x();
float x1 = x() + width;
float y0 = y() + 1;
float y1 = y() + height - 1;
quad_type_0(writer,
{x0, y0, shadow_depth},
{x1, y0, shadow_depth},
{x1, y1, shadow_depth},
{x0, y1, shadow_depth},
shadow_color);
}
}
void button_tl::draw_lowlight(ta_parameter_writer& writer) const
{
float x0 = x() + 1;
float x1 = x() + width - 1;
float y0 = y() + 1;
float y1 = y() + height - 1;
quad_type_0(writer,
{x0, y0, lowlight_depth},
{x1, y0, lowlight_depth},
{x1, y1, lowlight_depth},
{x0, y1, lowlight_depth},
lowlight_color);
}
void button_tl::draw_highlight(ta_parameter_writer& writer) const
{
float x0 = x() + 1;
float x1 = x() + width - 2;
float y0 = y() + 1;
float y1 = y() + height - 2;
int color = (click_state == click_type::release) ? highlight_color : highlight_click_color;
quad_type_0(writer,
{x0, y0, highlight_depth},
{x1, y0, highlight_depth},
{x1, y1, highlight_depth},
{x0, y1, highlight_depth},
color);
}
void button_tl::draw_background(ta_parameter_writer& writer) const
{
float x0 = x() + 2;
float x1 = x() + width - 2;
float y0 = y() + 2;
float y1 = y() + height - 2;
quad_type_0(writer,
{x0, y0, background_depth},
{x1, y0, background_depth},
{x1, y1, background_depth},
{x0, y1, background_depth},
background_color);
}
void button_tl::draw(ta_multiwriter& multi)
{
global_polygon_untextured(multi.op,
para_control::list_type::translucent,
tsp_instruction_word::dst_alpha_instr::zero);
draw_shadow(multi.op);
draw_lowlight(multi.op);
draw_highlight(multi.op);
draw_background(multi.op);
widget::draw(multi);
}
void button_tl::click()
{
if (click_state == click_type::release && on_click != nullptr)
on_click();
widget::click();
}
}

29
src/widget/button_tl.hpp Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include "holly/ta_parameter.hpp"
#include "ta_multiwriter.hpp"
#include "widget/widget.hpp"
namespace widget {
struct button_tl : widget {
using widget::draw;
void (* const on_click)();
inline button_tl(float _width, float _height, void (* const _on_click)())
: widget(0, 0, _width, _height), on_click(_on_click)
{ }
inline button_tl(float _x, float _y, float _width, float _height, void (* const _on_click)())
: widget(_x, _y, _width, _height), on_click(_on_click)
{ }
void draw_shadow(ta_parameter_writer& writer) const;
void draw_lowlight(ta_parameter_writer& writer) const;
void draw_highlight(ta_parameter_writer& writer) const;
void draw_background(ta_parameter_writer& writer) const;
void draw(ta_multiwriter& multi) override;
void click() override;
};
}

View File

@ -19,6 +19,8 @@ namespace widget {
float cy = y() + height / 2 - glyph::vert_advance / 2 + y_offset;
transfer_string(writer, value, cx, cy, label_depth, label_color);
transfer_string(writer, value, cx + 1, cy + 1, label_shadow_depth, label_shadow_color);
}
void label::draw(ta_multiwriter& multi)

34
src/widget/label_tl.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "widget/label_tl.hpp"
#include "ta_parameter.hpp"
#include "graphics_primitive.hpp"
namespace widget {
const static float label_depth = 10.0 / 5.0;
const static int label_color = 0xa7a7a7;
const static float label_shadow_depth = 10.0 / 6.0;
const static int label_shadow_color = 0x000000;
void label_tl::draw_label(ta_parameter_writer& writer) const
{
float y_offset = 0;
float cx = x() + width / 2 - (glyph::hori_advance * value_length) / 2;
float cy = y() + height / 2 - glyph::vert_advance / 2 + y_offset;
transfer_string(writer, value, cx, cy, label_depth, label_color);
transfer_string(writer, value, cx + 1, cy + 1, label_shadow_depth, label_shadow_color);
}
void label_tl::draw(ta_multiwriter& multi)
{
transfer_global_polygon_glyph(multi.pt);
draw_label(multi.pt);
widget::draw(multi);
}
}

23
src/widget/label_tl.hpp Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include "holly/ta_parameter.hpp"
#include "ta_multiwriter.hpp"
#include "widget/widget.hpp"
namespace widget {
struct label_tl : widget {
const char * const value;
const int value_length;
inline label_tl(float _width, float _height, const char * value)
: widget(0, 0, _width, _height), value(value), value_length(str_length(value))
{ }
inline label_tl(float _x, float _y, float _width, float _height, const char * value)
: widget(_x, _y, _width, _height), value(value), value_length(str_length(value))
{ }
void draw_label(ta_parameter_writer& writer) const;
void draw(ta_multiwriter& multi) override;
};
}

View File

@ -60,6 +60,9 @@ XM_PLAYER_OBJ = \
src/widget/button_label.o \
src/widget/button_icon.o \
src/widget/label.o \
src/widget/button_tl.o \
src/widget/button_label_tl.o \
src/widget/label_tl.o \
src/xm.o
xm_player.elf: LDSCRIPT = $(LIB)/main.lds