fully implement repeat; fixed numerous small bugs
This commit is contained in:
parent
5e52562a1c
commit
62a47e236d
2
Makefile
2
Makefile
@ -1,6 +1,6 @@
|
||||
all: xm_player.elf
|
||||
|
||||
OPT = -O1
|
||||
OPT = -O2
|
||||
|
||||
MAKEFILE_PATH := $(patsubst %/,%,$(dir $(abspath $(firstword $(MAKEFILE_LIST)))))
|
||||
LIB ?= $(MAKEFILE_PATH)/dreamcast
|
||||
|
BIN
font/icons.data
BIN
font/icons.data
Binary file not shown.
BIN
font/icons.pgm
BIN
font/icons.pgm
Binary file not shown.
@ -20,11 +20,15 @@ void framebuffer_init()
|
||||
| fb_y_clip::fb_y_clip_min(0);
|
||||
|
||||
// read
|
||||
while (spg_status::vsync(holly.SPG_STATUS));
|
||||
while (!spg_status::vsync(holly.SPG_STATUS));
|
||||
|
||||
holly.FB_R_SIZE = fb_r_size::fb_modulus(1)
|
||||
| fb_r_size::fb_y_size(y_size - 1)
|
||||
| fb_r_size::fb_x_size((x_size * bytes_per_pixel) / 4 - 1);
|
||||
|
||||
holly.FB_R_SOF1 = texture_memory_alloc.framebuffer[0].start;
|
||||
|
||||
holly.FB_R_CTRL = fb_r_ctrl::vclk_div::pclk_vclk_1
|
||||
| fb_r_ctrl::fb_depth::_565_rgb_16bit
|
||||
| fb_r_ctrl::fb_enable;
|
||||
|
@ -27,9 +27,11 @@
|
||||
#include "cursor.hpp"
|
||||
#include "ta_parameter.hpp"
|
||||
|
||||
#include "sh7091/sh7091.hpp"
|
||||
|
||||
static volatile int ta_in_use = 0;
|
||||
static volatile int core_in_use = 0;
|
||||
static volatile int next_frame = 0;
|
||||
volatile int next_frame = 0;
|
||||
static volatile int framebuffer_ix = 0;
|
||||
static volatile int next_frame_ix = 0;
|
||||
|
||||
@ -91,16 +93,51 @@ void transfer_palettes()
|
||||
holly.PT_ALPHA_REF = 0xf0;
|
||||
}
|
||||
|
||||
static inline void zeroize_ta_fifo_texture_memory_32byte(void * dst, int length)
|
||||
{
|
||||
uint32_t out_addr = (uint32_t)dst;
|
||||
sh7091.CCN.QACR0 = ((reinterpret_cast<uint32_t>(out_addr) >> 24) & 0b11100);
|
||||
sh7091.CCN.QACR1 = ((reinterpret_cast<uint32_t>(out_addr) >> 24) & 0b11100);
|
||||
|
||||
volatile uint32_t * base = &store_queue[(out_addr & 0x03ffffe0) / 4];
|
||||
|
||||
length = (length + 31) & ~31; // round up to nearest multiple of 32
|
||||
while (length > 0) {
|
||||
base[0] = 0xc5f7c5f7;
|
||||
base[1] = 0xc5f7c5f7;
|
||||
base[2] = 0xc5f7c5f7;
|
||||
base[3] = 0xc5f7c5f7;
|
||||
base[4] = 0xc5f7c5f7;
|
||||
base[5] = 0xc5f7c5f7;
|
||||
base[6] = 0xc5f7c5f7;
|
||||
base[7] = 0xc5f7c5f7;
|
||||
asm volatile ("pref @%0"
|
||||
: // output
|
||||
: "r" (&base[0]) // input
|
||||
: "memory");
|
||||
length -= 32;
|
||||
base += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void graphics_init()
|
||||
{
|
||||
holly.SOFTRESET = softreset::pipeline_soft_reset
|
||||
| softreset::ta_soft_reset;
|
||||
holly.SOFTRESET = 0;
|
||||
|
||||
system.LMMODE0 = 1; // 32-bit address space
|
||||
system.LMMODE1 = 1; // 32-bit address space
|
||||
|
||||
int length = 640 * 480 * 2;
|
||||
uint32_t offset = texture_memory_alloc.framebuffer[0].start;
|
||||
void * dst = reinterpret_cast<void *>(&ta_fifo_texture_memory[offset / 4]);
|
||||
zeroize_ta_fifo_texture_memory_32byte(dst, length);
|
||||
|
||||
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,
|
||||
@ -186,7 +223,4 @@ void graphics_event(ta_multiwriter& multi)
|
||||
ta_polygon_converter_writeback(multi.op.buf, multi.op.offset);
|
||||
ta_polygon_converter_transfer(multi.op.buf, multi.op.offset);
|
||||
}
|
||||
|
||||
while (next_frame == 0);
|
||||
next_frame = 0;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
constexpr int ta_cont_count = 1;
|
||||
|
||||
extern volatile int next_frame;
|
||||
|
||||
void graphics_interrupt(uint32_t istnrm);
|
||||
void graphics_init();
|
||||
void graphics_event(ta_multiwriter& multi);
|
||||
|
@ -8,10 +8,10 @@ namespace icons {
|
||||
constexpr float texture_height = 1.0 / 32.0;
|
||||
|
||||
const icon icons[] = {
|
||||
[ff] = icon(18, 19, 9, 7),
|
||||
[fff] = icon(14, 19, 13, 7),
|
||||
[next] = icon(45, 12, 19, 11),
|
||||
[prev] = icon(45, 0, 19, 11),
|
||||
[ff] = icon(17, 19, 9, 7),
|
||||
[fff] = icon(13, 19, 13, 7),
|
||||
[next] = icon(46, 12, 19, 11),
|
||||
[prev] = icon(44, 0, 19, 11),
|
||||
[rr] = icon(0, 19, 9, 7),
|
||||
[rrr] = icon(0, 19, 13, 7),
|
||||
[play] = icon(0, 0, 17, 17),
|
||||
|
@ -29,6 +29,7 @@ namespace icons {
|
||||
{
|
||||
uint32_t texture_size = tsp_instruction_word::texture_u_size::from_int(64)
|
||||
| tsp_instruction_word::texture_v_size::from_int(32)
|
||||
| tsp_instruction_word::clamp_uv::uv
|
||||
| tsp_instruction_word::dst_alpha_instr::inverse_src_alpha;
|
||||
|
||||
global_polygon_textured(writer,
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "interpreter.hpp"
|
||||
#include "sound.hpp"
|
||||
#include "playlist.hpp"
|
||||
|
||||
namespace interpreter {
|
||||
|
||||
@ -187,8 +188,17 @@ static inline void next_pattern()
|
||||
|
||||
if (state.pattern_order_table_index < 0)
|
||||
state.pattern_order_table_index = state.xm.song_length - 1;
|
||||
if (state.pattern_order_table_index >= state.xm.song_length)
|
||||
state.pattern_order_table_index = 0;
|
||||
if (state.pattern_order_table_index >= state.xm.song_length) {
|
||||
if (state.repeat) {
|
||||
state.pattern_order_table_index = 0;
|
||||
} else if (state.reverse) {
|
||||
playlist::prev(false);
|
||||
return;
|
||||
} else {
|
||||
playlist::next(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("pattern_order_table_index: %d\n", state.pattern_order_table_index);
|
||||
|
||||
state.pattern_index = state.xm.header->pattern_order_table[state.pattern_order_table_index];
|
||||
@ -341,8 +351,7 @@ void stop_sound()
|
||||
wait();
|
||||
bool kyonb = aica_sound.channel[ch].KYONB() != 0;
|
||||
wait(); aica_sound.channel[ch].KYONB(0);
|
||||
wait(); aica_sound.channel[ch].RR(0x1f);
|
||||
state.channel[ch].keyon = kyonb ? 255 : 0;
|
||||
//state.channel[ch].keyon = kyonb ? 255 : 0;
|
||||
}
|
||||
wait(); aica_sound.channel[0].KYONEX(1);
|
||||
}
|
||||
@ -374,8 +383,6 @@ void deferred_load(int buf)
|
||||
|
||||
state.deferred_load_tick = aica_clock_multiplier * 1000 / 2;
|
||||
|
||||
stop_sound();
|
||||
|
||||
state.sample_data_ix = xm_init(&interpreter::state.xm,
|
||||
buf,
|
||||
sample_data,
|
||||
|
@ -24,6 +24,7 @@ struct interpreter_state {
|
||||
int next_line_index; // within the current pattern
|
||||
bool paused;
|
||||
bool reverse;
|
||||
bool repeat;
|
||||
|
||||
int deferred_load_tick;
|
||||
int sample_data_ix;
|
||||
@ -39,6 +40,9 @@ void init(float clock_multiplier);
|
||||
void pause();
|
||||
void unpause();
|
||||
|
||||
void resume_sound();
|
||||
void stop_sound();
|
||||
|
||||
void deferred_load(int buf);
|
||||
void deferred_load_finish();
|
||||
}
|
||||
|
17
src/main.cpp
17
src/main.cpp
@ -24,8 +24,12 @@ void vbr400()
|
||||
interrupt_exception();
|
||||
}
|
||||
|
||||
static bool inside_interrupt = false;
|
||||
|
||||
void vbr600()
|
||||
{
|
||||
assert(inside_interrupt == false);
|
||||
inside_interrupt = true;
|
||||
uint32_t sr;
|
||||
asm volatile ("stc sr,%0" : "=r" (sr));
|
||||
sr |= sh::sr::imask(15);
|
||||
@ -52,7 +56,7 @@ void vbr600()
|
||||
} else {
|
||||
wait(); aica_sound.common.tactl_tima
|
||||
= aica::tactl_tima::TACTL(0) // increment once every sample
|
||||
| aica::tactl_tima::TIMA(0xffff) // interrupt after 1 counts
|
||||
| aica::tactl_tima::TIMA(0xfff0) // interrupt after 4 counts
|
||||
;
|
||||
}
|
||||
|
||||
@ -65,6 +69,7 @@ void vbr600()
|
||||
|
||||
sr &= ~sh::sr::imask(15);
|
||||
asm volatile ("ldc %0,sr" : : "r" (sr));
|
||||
inside_interrupt = false;
|
||||
}
|
||||
|
||||
#include "memorymap.hpp"
|
||||
@ -107,7 +112,7 @@ void main()
|
||||
//bool emulator = detect_emulator();
|
||||
//printf("emulator %d\n", emulator);
|
||||
graphics_init();
|
||||
scene::scene_init(scene::id::tracker);
|
||||
scene::scene_init(scene::id::logo);
|
||||
input::state_init();
|
||||
cursor::init();
|
||||
|
||||
@ -137,6 +142,14 @@ void main()
|
||||
|
||||
graphics_event(multi);
|
||||
|
||||
int count = 0;
|
||||
while (next_frame == 0) {
|
||||
if (count++ > 1000000) {
|
||||
printf("timeout\n");
|
||||
}
|
||||
};
|
||||
next_frame = 0;
|
||||
|
||||
scene::transition();
|
||||
}
|
||||
}
|
||||
|
@ -33,23 +33,25 @@ namespace playlist {
|
||||
|
||||
const int playlist_length = (sizeof (playlist)) / (sizeof (playlist[0]));
|
||||
|
||||
void next()
|
||||
void next(bool stop_sound)
|
||||
{
|
||||
state.playlist_ix += 1;
|
||||
if (state.playlist_ix >= playlist_length)
|
||||
state.playlist_ix = 0;
|
||||
|
||||
printf("next deferred_load playlist_ix %d\n", state.playlist_ix);
|
||||
interpreter::stop_sound();
|
||||
interpreter::deferred_load(playlist[state.playlist_ix].start);
|
||||
}
|
||||
|
||||
void prev()
|
||||
void prev(bool stop_sound)
|
||||
{
|
||||
state.playlist_ix -= 1;
|
||||
if (state.playlist_ix < 0)
|
||||
state.playlist_ix = playlist_length - 1;
|
||||
|
||||
printf("prev deferred_load playlist_ix %d\n", state.playlist_ix);
|
||||
interpreter::stop_sound();
|
||||
interpreter::deferred_load(playlist[state.playlist_ix].start);
|
||||
}
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ namespace playlist {
|
||||
int playlist_ix;
|
||||
};
|
||||
|
||||
void next();
|
||||
void prev();
|
||||
void next(bool stop_sound=true);
|
||||
void prev(bool stop_sound=true);
|
||||
|
||||
extern struct state state;
|
||||
extern const playlist_item playlist[];
|
||||
|
@ -10,7 +10,7 @@ namespace scene::emulator::sound {
|
||||
const static void * start = reinterpret_cast<void *>(&_binary_pcm_dk_adpcm_start);
|
||||
const static int size = reinterpret_cast<int>(&_binary_pcm_dk_adpcm_size);
|
||||
const static int sample_count = size * 2;
|
||||
const static int loop_length = 65528;
|
||||
const static int loop_length = 65520;
|
||||
const static int segment_count = sample_count / loop_length;
|
||||
const static int last_loop = (sample_count % loop_length) & (~0b11);
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace scene::logo::sound {
|
||||
const static void * start = reinterpret_cast<void *>(&_binary_pcm_start3_adpcm_start);
|
||||
const static int size = reinterpret_cast<int>(&_binary_pcm_start3_adpcm_size);
|
||||
const static int sample_count = size * 2;
|
||||
const static int loop_length = 65528;
|
||||
const static int loop_length = 65520;
|
||||
const static int segment_count = sample_count / loop_length;
|
||||
const static int last_loop = (sample_count % loop_length) & (~0b11);
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "scene/logo/scene.hpp"
|
||||
#include "scene/emulator/scene.hpp"
|
||||
|
||||
#include "sh7091/sh7091_bits.hpp"
|
||||
|
||||
namespace scene {
|
||||
const scene scenes[] = {
|
||||
[id::tracker] = tracker::scene,
|
||||
@ -31,7 +33,17 @@ namespace scene {
|
||||
assert(current_scene->done != nullptr);
|
||||
int scene_id = current_scene->done();
|
||||
if (scene_id >= 0) {
|
||||
printf("disable interrupt\n");
|
||||
uint32_t sr;
|
||||
asm volatile ("stc sr,%0" : "=r" (sr));
|
||||
sr |= sh::sr::imask(15);
|
||||
asm volatile ("ldc %0,sr" : : "r" (sr));
|
||||
|
||||
scene_init(scene_id);
|
||||
|
||||
printf("enable interrupt\n");
|
||||
sr &= ~sh::sr::imask(15);
|
||||
asm volatile ("ldc %0,sr" : : "r" (sr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,13 +80,21 @@ void fff_click()
|
||||
state.current_tick_rate = state.current_tick_rate / 2;
|
||||
}
|
||||
|
||||
void repeat_click()
|
||||
{
|
||||
using namespace interpreter;
|
||||
printf("repeat\n");
|
||||
state.repeat = !state.repeat;
|
||||
}
|
||||
|
||||
#define __length(c) ((sizeof (c)) / (sizeof (c[0])))
|
||||
|
||||
widget::button_icon play_button(75, 60, icons::play, play_click);
|
||||
widget::button_icon pause_button(75, 33, icons::pause, pause_click);
|
||||
|
||||
widget::button_icon prev_button(79, 30, icons::prev, prev_click);
|
||||
widget::button_icon next_button(79, 30, icons::next, next_click);
|
||||
widget::button_icon prev_button(60, 30, icons::prev, prev_click);
|
||||
widget::button_icon next_button(60, 30, icons::next, next_click);
|
||||
widget::button_icon repeat_button(37, 30, icons::repeat, repeat_click);
|
||||
|
||||
widget::button_icon rrr_button(39, 21, icons::rrr, rrr_click);
|
||||
widget::button_icon rr_button(39, 21, icons::rr, rr_click);
|
||||
@ -102,6 +110,7 @@ int play_pause_length = __length(play_pause_children);
|
||||
widget::widget * prev_next_children[] = {
|
||||
&prev_button,
|
||||
&next_button,
|
||||
&repeat_button,
|
||||
};
|
||||
int prev_next_length = __length(prev_next_children);
|
||||
|
||||
@ -186,29 +195,51 @@ namespace scene::tracker {
|
||||
|
||||
transfer_global_polygon_glyph(writer);
|
||||
|
||||
float ratio = (float)state.default_tick_rate / (float)state.current_tick_rate;
|
||||
{
|
||||
float ratio = (float)state.default_tick_rate / (float)state.current_tick_rate;
|
||||
|
||||
float x = 100;
|
||||
float y = 100;
|
||||
transfer_string(writer, "speed: . x",
|
||||
x, y, 1.0 / 10.0,
|
||||
0xa7a7a7);
|
||||
if (state.reverse)
|
||||
transfer_glyph(writer, '-',
|
||||
x + glyph::hori_advance * 7, y, 1.0 / 10.0,
|
||||
0xffffff);
|
||||
float x = 100;
|
||||
float y = 100;
|
||||
transfer_string(writer, "speed: . x",
|
||||
x, y, 1.0 / 10.0,
|
||||
0xa7a7a7);
|
||||
if (state.reverse)
|
||||
transfer_glyph(writer, '-',
|
||||
x + glyph::hori_advance * 7, y, 1.0 / 10.0,
|
||||
0xffffff);
|
||||
|
||||
transfer_integer(writer, (int)ratio,
|
||||
x + glyph::hori_advance * 8, y, 1.0 / 10.0,
|
||||
2, ' ',
|
||||
0xffffff);
|
||||
transfer_integer(writer, (int)ratio,
|
||||
x + glyph::hori_advance * 8, y, 1.0 / 10.0,
|
||||
2, ' ',
|
||||
0xffffff);
|
||||
|
||||
float ratio_fraction = (ratio - ((int)ratio)) * 100;
|
||||
float ratio_fraction = (ratio - ((int)ratio)) * 100;
|
||||
|
||||
transfer_integer(writer, (int)ratio_fraction,
|
||||
x + glyph::hori_advance * 11, y, 1.0 / 10.0,
|
||||
2, '0',
|
||||
0xffffff);
|
||||
transfer_integer(writer, (int)ratio_fraction,
|
||||
x + glyph::hori_advance * 11, y, 1.0 / 10.0,
|
||||
2, '0',
|
||||
0xffffff);
|
||||
}
|
||||
|
||||
{
|
||||
float x = 100;
|
||||
float y = 48;
|
||||
transfer_string(writer, "repeat:",
|
||||
x, y, 1.0 / 10.0,
|
||||
0xa7a7a7);
|
||||
|
||||
x += glyph::hori_advance * (7 + 2);
|
||||
|
||||
if (state.repeat) {
|
||||
transfer_string(writer, "on",
|
||||
x, y, 1.0 / 10.0,
|
||||
0xffffff);
|
||||
} else {
|
||||
transfer_string(writer, "off",
|
||||
x, y, 1.0 / 10.0,
|
||||
0xffffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void transfer(ta_multiwriter& multi)
|
||||
|
Loading…
x
Reference in New Issue
Block a user