partially implement options scene

This commit is contained in:
Zack Buhman 2025-07-03 22:08:32 -05:00
parent 12bd750d73
commit b2f5e09465
12 changed files with 484 additions and 47 deletions

View File

@ -48,6 +48,7 @@ namespace cursor {
state[port_ix].a = ft0::data_transfer::digital_button::a(data.digital_button) == 0;
state[port_ix].b = ft0::data_transfer::digital_button::b(data.digital_button) == 0;
state[port_ix].start = ft0::data_transfer::digital_button::start(data.digital_button) == 0;
state[port_ix].active = true;
} else if ((port.function_type & function_type::pointing) != 0 && port.host_response_data_transfer_ft9 != nullptr) {
@ -62,6 +63,7 @@ namespace cursor {
state[port_ix].y += dy;
state[port_ix].a = ft9::data_transfer::digital_button::a(data.digital_button) == 0;
state[port_ix].b = ft9::data_transfer::digital_button::b(data.digital_button) == 0;
state[port_ix].start = ft9::data_transfer::digital_button::w(data.digital_button) == 0;
state[port_ix].active = true;
}

View File

@ -8,6 +8,7 @@ namespace cursor {
float y;
bool a;
bool b;
bool start;
};
extern struct cursor state[4];

View File

@ -35,6 +35,9 @@ volatile int next_frame = 0;
static volatile int framebuffer_ix = 0;
static volatile int next_frame_ix = 0;
static void * pt_buf = nullptr;
static int pt_offset = 0;
static void * op_buf = nullptr;
static int op_offset = 0;
@ -59,6 +62,16 @@ void graphics_interrupt(uint32_t istnrm)
core_in_use = 0;
}
if (istnrm & istnrm::end_of_transferring_translucent_list) {
system.ISTNRM = istnrm::end_of_transferring_translucent_list;
assert(pt_buf != nullptr);
assert(pt_offset > 0);
ta_polygon_converter_writeback(pt_buf, pt_offset);
ta_polygon_converter_transfer(pt_buf, pt_offset);
}
if (istnrm & istnrm::end_of_transferring_punch_through_list) {
system.ISTNRM = istnrm::end_of_transferring_punch_through_list;
@ -137,7 +150,7 @@ void graphics_init()
scaler_init();
core_init();
core_param_init();
//spg_set_mode_640x480();
spg_set_mode_640x480();
framebuffer_init();
background_parameter2(texture_memory_alloc.background[1].start,
@ -181,8 +194,9 @@ void graphics_event(ta_multiwriter& multi)
{
multi.op.offset = 0;
multi.pt.offset = 0;
multi.tl.offset = 0;
if (scene::current_scene == &scene::scenes[scene::id::tracker]) {
if (scene::current_scene == &scene::scenes[scene::id::tracker] || scene::current_scene == &scene::scenes[scene::id::options]) {
graphics_cursor(multi);
}
assert(scene::current_scene->transfer != nullptr);
@ -210,7 +224,21 @@ void graphics_event(ta_multiwriter& multi)
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
}
if (multi.pt.offset != 0) {
if (multi.tl.offset != 0) {
multi.tl.append<ta_global_parameter::end_of_list>() =
ta_global_parameter::end_of_list(para_control::para_type::end_of_list);
}
if (multi.tl.offset != 0) {
pt_buf = multi.pt.buf;
pt_offset = multi.pt.offset;
op_buf = multi.op.buf;
op_offset = multi.op.offset;
ta_polygon_converter_writeback(multi.tl.buf, multi.tl.offset);
ta_polygon_converter_transfer(multi.tl.buf, multi.tl.offset);
} else if (multi.pt.offset != 0) {
op_buf = multi.op.buf;
op_offset = multi.op.offset;

View File

@ -104,15 +104,17 @@ void test_pattern()
void main()
{
printf("main\n");
serial::init(0);
printf("main\n");
sound::init();
//bool emulator = detect_emulator();
//printf("emulator %d\n", emulator);
printf("graphics_init\n");
graphics_init();
scene::scene_init(scene::id::logo);
//scene::scene_init(scene::id::logo);
printf("scene_init\n");
scene::scene_init(scene::id::tracker);
printf("state_init\n");
input::state_init();
cursor::init();
@ -122,6 +124,7 @@ void main()
system.IML6NRM = istnrm::end_of_render_tsp
| istnrm::v_blank_in
| istnrm::end_of_transferring_translucent_list
| istnrm::end_of_transferring_punch_through_list
| istnrm::end_of_transferring_opaque_list;
@ -129,8 +132,10 @@ void main()
static uint8_t op_buf[1024 * 1024] __attribute__((aligned(32)));
static uint8_t pt_buf[1024 * 1024] __attribute__((aligned(32)));
static uint8_t tl_buf[1024 * 1024 / 2] __attribute__((aligned(32)));
ta_multiwriter multi(ta_parameter_writer(op_buf, (sizeof (op_buf))),
ta_parameter_writer(pt_buf, (sizeof (pt_buf))));
ta_parameter_writer(pt_buf, (sizeof (pt_buf))),
ta_parameter_writer(tl_buf, (sizeof (tl_buf))));
static uint8_t send_buf[1024] __attribute__((aligned(32)));
static uint8_t recv_buf[1024] __attribute__((aligned(32)));

325
src/scene/options/scene.cpp Normal file
View File

@ -0,0 +1,325 @@
#include "holly/ta_bits.hpp"
#include "holly/background.hpp"
#include "holly/holly.hpp"
#include "scene/scene.hpp"
#include "scene/options/scene.hpp"
#include "widget/button_label.hpp"
#include "widget/button_icon.hpp"
#include "widget/left_aligned.hpp"
#include "widget/top_aligned.hpp"
#include "widget/label.hpp"
#include "graphics_primitive.hpp"
#include "cursor.hpp"
#include "framebuffer.hpp"
#include "graphics.hpp"
#define __length(c) ((sizeof (c)) / (sizeof (c[0])))
uint32_t alpha = 0xcf000000;
void position_left()
{
printf("left\n");
int startx = holly.VO_STARTX & 0x3ff;
int hbend = (holly.SPG_HBLANK >> 16) & 0x3ff;
if (startx > hbend) {
holly.VO_STARTX = startx - 1;
}
}
void position_right()
{
printf("right\n");
int startx = holly.VO_STARTX & 0x3ff;
int hbstart = (holly.SPG_HBLANK >> 0) & 0x3ff;
if (startx < hbstart) {
holly.VO_STARTX = startx + 1;
}
}
void position_up()
{
printf("up\n");
int starty = holly.VO_STARTY & 0x3ff;
int vbend = (holly.SPG_VBLANK >> 16) & 0x3ff;
if (starty > vbend) {
holly.VO_STARTY = starty - 1;
}
}
void position_down()
{
printf("down\n");
int starty = holly.VO_STARTY & 0x3ff;
int vbstart = (holly.SPG_VBLANK >> 0) & 0x3ff;
if (starty < vbstart) {
holly.VO_STARTY = starty + 1;
}
}
void resolution_640x480()
{
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);
}
void resolution_720x480()
{
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);
}
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 _640x480_button(100, 46, "640x480", resolution_640x480);
widget::button_label _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::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::widget * row1_children[] = {
//&spacer,
&up_button,
};
int row1_length = __length(row1_children);
widget::widget * row2_children[] = {
&left_button,
&spacer,
&right_button,
};
int row2_length = __length(row2_children);
widget::widget * row3_children[] = {
// &spacer,
&down_button,
};
int row3_length = __length(row3_children);
widget::left_aligned row1(15, 0, 1, row1_children, row1_length);
widget::left_aligned row2(15, 0, 1, row2_children, row2_length);
widget::left_aligned row3(15, 0, 1, row3_children, row3_length);
widget::widget * position_children[] = {
&position1_label,
&row1,
&row2,
&row3,
};
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,
&_720x480_button,
};
int resolution_length = __length(resolution_children);
widget::top_aligned resolution(0, 0, 1, resolution_children, resolution_length);
widget::widget * video_children[] = {
&resolution,
&position,
};
int video_length = __length(video_children);
widget::left_aligned video(0, 0, 20, video_children, video_length);
widget::widget * mouse_speed_row1_children[] = {
&mouse_minus_button,
&mouse_plus_button,
};
int mouse_speed_row1_length = __length(mouse_speed_row1_children);
widget::left_aligned mouse_speed_row1(0, 0, 30, mouse_speed_row1_children, mouse_speed_row1_length);
widget::widget * mouse_speed_children[] = {
&mouse_speed_label,
&mouse_speed_row1,
};
int mouse_speed_length = __length(mouse_speed_children);
widget::top_aligned mouse_speed(0, 0, 1, mouse_speed_children, mouse_speed_length);
widget::widget * stick_speed_row1_children[] = {
&stick_minus_button,
&stick_plus_button,
};
int stick_speed_row1_length = __length(stick_speed_row1_children);
widget::left_aligned stick_speed_row1(0, 0, 30, stick_speed_row1_children, stick_speed_row1_length);
widget::widget * stick_speed_children[] = {
&stick_speed_label,
&stick_speed_row1,
};
int stick_speed_length = __length(stick_speed_children);
widget::top_aligned stick_speed(0, 0, 1, stick_speed_children, stick_speed_length);
widget::widget * master_volume_row1_children[] = {
&master_volume_minus_button,
&master_volume_plus_button,
};
int master_volume_row1_length = __length(master_volume_row1_children);
widget::left_aligned master_volume_row1(0, 0, 30, master_volume_row1_children, master_volume_row1_length);
widget::widget * master_volume_children[] = {
&master_volume_label,
&master_volume_row1,
};
int master_volume_length = __length(master_volume_children);
widget::top_aligned master_volume(0, 0, 1, master_volume_children, master_volume_length);
widget::widget * controls_children[] = {
&mouse_speed,
&stick_speed,
};
int controls_length = __length(controls_children);
widget::left_aligned controls(0, 0, 15, controls_children, controls_length);
widget::widget * top_children[] = {
&video,
&controls,
&master_volume,
};
int top_length = __length(top_children);
widget::top_aligned top(0, 0, 20, top_children, top_length);
const struct scene::scene scene = {
.ta_alloc = ta_alloc_ctrl::pt_opb::_32x4byte
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::_32x4byte
| ta_alloc_ctrl::om_opb::no_list
| ta_alloc_ctrl::o_opb::_32x4byte,
.opb_size = {
.opaque = 32 * 4,
.opaque_modifier = 0,
.translucent = 32 * 4,
.translucent_modifier = 0,
.punch_through = 32 * 4
},
.transfer = transfer,
.interrupt = interrupt,
.init = init,
.done = done
};
void update()
{
for (int i = 0; i < 4; i++) {
cursor::cursor& c = cursor::state[i];
if (c.active && c.a) {
widget::widget * w = top.pick(c.x, c.y);
if (w != nullptr) {
w->click();
}
}
}
}
void draw_corners(ta_parameter_writer& writer)
{
global_polygon_translucent(writer);
quad_type_0(writer,
{0, 0, 0.5},
{10, 0, 0.5},
{10, 10, 0.5},
{0, 10, 0.5},
alpha | 0xff0000);
float x = framebuffer.px_width - 10;
float y = framebuffer.px_height - 10;
quad_type_0(writer,
{0 + x, 0, 0.5},
{10 + x, 0, 0.5},
{10 + x, 10, 0.5},
{0 + x, 10, 0.5},
alpha | 0x00ff00);
quad_type_0(writer,
{0, 0 + y, 0.5},
{10, 0 + y, 0.5},
{10, 10 + y, 0.5},
{0, 10 + y, 0.5},
alpha | 0x0000ff);
quad_type_0(writer,
{0 + x, 0 + y, 0.5},
{10 + x, 0 + y, 0.5},
{10 + x, 10 + y, 0.5},
{0 + x, 10 + y, 0.5},
alpha | 0xffffff);
}
void draw_shroud(ta_parameter_writer& writer)
{
global_polygon_translucent(writer);
quad_type_0(writer,
{0, 0, 0.5},
{(float)framebuffer.px_width, 0, 0.5},
{(float)framebuffer.px_width, (float)framebuffer.px_height, 0.5},
{0, (float)framebuffer.px_height, 0.5},
alpha | 0x202020);
}
void transfer(ta_multiwriter& multi)
{
update();
top.draw(multi);
draw_corners(multi.tl);
draw_shroud(multi.tl);
}
void interrupt()
{
}
void init()
{
/*
background_parameter2(texture_memory_alloc.background[1].start,
0x110012);
holly.VO_BORDER_COL = 0x110012;
*/
top.freeze(15, 15);
}
int done()
{
return -1;
}
}

View File

@ -0,0 +1,12 @@
namespace scene::options {
extern const struct scene::scene scene;
void transfer(ta_multiwriter& multi);
void interrupt();
void init();
int done();
}

View File

@ -4,6 +4,7 @@
#include "scene/tracker/scene.hpp"
#include "scene/logo/scene.hpp"
#include "scene/emulator/scene.hpp"
#include "scene/options/scene.hpp"
#include "sh7091/sh7091_bits.hpp"
@ -12,6 +13,7 @@ namespace scene {
[id::tracker] = tracker::scene,
[id::logo] = logo::scene,
[id::emulator] = emulator::scene,
[id::options] = options::scene,
};
const scene * current_scene = nullptr;

View File

@ -8,7 +8,8 @@ namespace scene {
enum scene_type {
tracker,
logo,
emulator
emulator,
options
};
}

View File

@ -21,9 +21,11 @@
#include "tracklist.hpp"
#include "cover.hpp"
#include "scene/options/scene.hpp"
#include "cursor.hpp"
void play_click()
static void play_click()
{
using namespace interpreter;
printf("play\n");
@ -32,25 +34,25 @@ void play_click()
interpreter::unpause();
}
void pause_click()
static void pause_click()
{
printf("pause\n");
interpreter::pause();
}
void prev_click()
static void prev_click()
{
printf("prev\n");
playlist::prev();
}
void next_click()
static void next_click()
{
printf("next\n");
playlist::next();
}
void rrr_click()
static void rrr_click()
{
using namespace interpreter;
printf("rr\n");
@ -59,28 +61,28 @@ void rrr_click()
state.reverse = true;
}
void rr_click()
static void rr_click()
{
using namespace interpreter;
printf("rr\n");
state.current_tick_rate = state.current_tick_rate * 23 / 22;
}
void ff_click()
static void ff_click()
{
using namespace interpreter;
printf("ff\n");
state.current_tick_rate = state.current_tick_rate * 22 / 23;
}
void fff_click()
static void fff_click()
{
using namespace interpreter;
printf("fff\n");
state.current_tick_rate = state.current_tick_rate / 2;
}
void repeat_click()
static void repeat_click()
{
using namespace interpreter;
printf("repeat\n");
@ -146,16 +148,19 @@ widget::left_aligned top(0, 0, 20, top_children, top_length);
namespace scene::tracker {
static bool options = false;
static bool last_start[4] = {};
const struct scene::scene scene = {
.ta_alloc = ta_alloc_ctrl::pt_opb::_32x4byte
| ta_alloc_ctrl::tm_opb::no_list
| ta_alloc_ctrl::t_opb::no_list
| ta_alloc_ctrl::t_opb::_32x4byte
| ta_alloc_ctrl::om_opb::no_list
| ta_alloc_ctrl::o_opb::_32x4byte,
.opb_size = {
.opaque = 32 * 4,
.opaque_modifier = 0,
.translucent = 0,
.translucent = 32 * 4,
.translucent_modifier = 0,
.punch_through = 32 * 4
},
@ -171,6 +176,8 @@ namespace scene::tracker {
0x110012);
holly.VO_BORDER_COL = 0x110012;
::scene::options::init();
float y = 8 + ((glyph::vert_advance + 5) * 2) + 8;
top.freeze(5, y);
playlist::next();
@ -189,6 +196,18 @@ namespace scene::tracker {
}
}
void update_start()
{
for (int i = 0; i < 4; i++) {
cursor::cursor& c = cursor::state[i];
if (c.active) {
if (c.start && c.start != last_start[i])
options = !options;
last_start[i] = c.start;
}
}
}
void draw_button_labels(ta_parameter_writer& writer)
{
using namespace interpreter;
@ -242,27 +261,41 @@ namespace scene::tracker {
}
}
void draw_dummy_tl(ta_parameter_writer& writer)
{
global_polygon_untextured(writer,
para_control::list_type::translucent,
tsp_instruction_word::dst_alpha_instr::zero);
quad_type_0(writer,
{0, 0, 0.1},
{0, 0, 0.1},
{0, 0, 0.1},
{0, 0, 0.1},
0x0);
}
void transfer(ta_multiwriter& multi)
{
update();
update_start();
metadata::draw(multi, 5, 8);
top.draw(multi);
draw_button_labels(multi.pt);
tracklist::draw(multi, top.width + 5, 5);
float y = top.y() + top.height + 5;
channel_status::draw(multi, 5, y);
cover::draw(multi, 480, 8);
y += channel_status::height + 10;
notes::draw(multi, 5, y);
if (options) {
::scene::options::transfer(multi);
} else {
draw_dummy_tl(multi.tl);
update();
}
}
int done()

View File

@ -5,4 +5,5 @@
struct ta_multiwriter {
ta_parameter_writer op;
ta_parameter_writer pt;
ta_parameter_writer tl;
};

View File

@ -93,14 +93,37 @@ static inline void global_polygon_untextured(ta_parameter_writer& writer, uint32
const uint32_t tsp_instruction_word = tsp_instruction_word::texture_shading_instruction::modulate
| tsp_instruction_word::src_alpha_instr::one
| dst_alpha
| tsp_instruction_word::fog_control::no_fog
| tsp_instruction_word::texture_u_size::from_int(128)
| tsp_instruction_word::texture_v_size::from_int(256);
| tsp_instruction_word::fog_control::no_fog;
const uint32_t texture_address = texture_memory_alloc.texture.start;
const uint32_t texture_control_word = texture_control_word::pixel_format::_4bpp_palette
| texture_control_word::scan_order::twiddled
| texture_control_word::texture_address(texture_address / 8);
const uint32_t texture_control_word = 0;
writer.append<ta_global_parameter::polygon_type_0>() =
ta_global_parameter::polygon_type_0(parameter_control_word,
isp_tsp_instruction_word,
tsp_instruction_word,
texture_control_word,
0, // data_size_for_sort_dma
0 // next_address_for_sort_dma
);
}
static inline void global_polygon_translucent(ta_parameter_writer& writer)
{
const uint32_t parameter_control_word = para_control::para_type::polygon_or_modifier_volume
| para_control::list_type::translucent
| obj_control::col_type::packed_color
;
const uint32_t isp_tsp_instruction_word = isp_tsp_instruction_word::depth_compare_mode::greater_or_equal
| isp_tsp_instruction_word::culling_mode::no_culling;
const uint32_t tsp_instruction_word = tsp_instruction_word::texture_shading_instruction::modulate_alpha
| tsp_instruction_word::src_alpha_instr::src_alpha
| tsp_instruction_word::dst_alpha_instr::inverse_src_alpha
| tsp_instruction_word::use_alpha
| tsp_instruction_word::fog_control::no_fog;
const uint32_t texture_control_word = 0;
writer.append<ta_global_parameter::polygon_type_0>() =
ta_global_parameter::polygon_type_0(parameter_control_word,

View File

@ -16,6 +16,20 @@ PCM_OBJ = \
pcm/start3.adpcm.o \
pcm/dk.adpcm.o
SCENE_OBJ = \
src/scene/logo/scene.o \
src/scene/logo/sound.o \
src/scene/emulator/scene.o \
src/scene/emulator/sound.o \
src/scene/scene.o \
src/scene/tracker/channel_status.o \
src/scene/tracker/cover.o \
src/scene/tracker/notes.o \
src/scene/tracker/scene.o \
src/scene/tracker/metadata.o \
src/scene/tracker/tracklist.o \
src/scene/options/scene.o
XM_PLAYER_OBJ = \
$(LIB)/holly/core.o \
$(LIB)/holly/region_array.o \
@ -40,23 +54,13 @@ XM_PLAYER_OBJ = \
src/main.o \
src/malloc.o \
src/playlist.o \
src/scene/logo/scene.o \
src/scene/logo/sound.o \
src/scene/emulator/scene.o \
src/scene/emulator/sound.o \
src/scene/scene.o \
src/scene/tracker/channel_status.o \
src/scene/tracker/cover.o \
src/scene/tracker/notes.o \
src/scene/tracker/scene.o \
src/scene/tracker/metadata.o \
src/scene/tracker/tracklist.o \
src/sound.o \
src/texture.o \
src/widget/button.o \
src/widget/button_label.o \
src/widget/button_icon.o \
src/widget/label.o \
src/xm.o
xm_player.elf: LDSCRIPT = $(LIB)/main.lds
xm_player.elf: $(START_OBJ) $(XM_PLAYER_OBJ) $(TEXTURE_OBJ) $(XM_OBJ) $(PCM_OBJ) $(LIBGCC)
xm_player.elf: $(START_OBJ) $(XM_PLAYER_OBJ) $(SCENE_OBJ) $(TEXTURE_OBJ) $(XM_OBJ) $(PCM_OBJ) $(LIBGCC)