add clock text box

This commit is contained in:
Brad Grantham 2019-02-18 08:11:22 -08:00
parent 0b61b25667
commit fd1e15a595
5 changed files with 141 additions and 13 deletions

View File

@ -1592,6 +1592,42 @@ void print_cpu_state(const CPU6502<CLK, BUS>& cpu)
printf("S:%02X (%02X %02X %02X ...) PC:%04X (%02X %02X %02X ...)\n", cpu.s, s0, s1, s2, cpu.pc, pc0, pc1, pc2);
}
template <class TYPE, unsigned int LENGTH>
struct averaged_sequence
{
int where;
TYPE sum;
TYPE list[LENGTH];
averaged_sequence() :
where(-1)
{
for(int i = 0; i < LENGTH; i++)
list[i] = 0;
sum = 0;
}
void add(TYPE value)
{
if(where == -1) {
for(int i = 0; i < LENGTH; i++)
list[i] = value;
sum = value * LENGTH;
where = 0;
} else {
sum -= list[where];
list[where] = value;
sum += list[where];
where = (where + 1) % LENGTH;
}
}
TYPE get() const
{
return sum / LENGTH;
}
};
int main(int argc, char **argv)
{
char *progname = argv[0];
@ -1734,6 +1770,9 @@ int main(int argc, char **argv)
APPLE2Einterface::start(run_fast, diskII_rom_name != NULL, floppy1_name != NULL, floppy2_name != NULL);
chrono::time_point<chrono::system_clock> then = std::chrono::system_clock::now();
chrono::time_point<chrono::system_clock> cpu_speed_then = std::chrono::system_clock::now();
clk_t cpu_previous_cycles = 0;
averaged_sequence<float, 20> cpu_speed_averaged;
while(1) {
if(!debugging) {
@ -1772,7 +1811,18 @@ int main(int argc, char **argv)
}
mainboard->sync();
APPLE2Einterface::iterate(mode_history, clk.clock_cpu);
chrono::time_point<chrono::system_clock> cpu_speed_now = std::chrono::system_clock::now();
auto cpu_elapsed_seconds = chrono::duration_cast<chrono::duration<float> >(cpu_speed_now - cpu_speed_then);
cpu_speed_then = cpu_speed_now;
clk_t cpu_elapsed_cycles = clk.clock_cpu - cpu_previous_cycles;
cpu_previous_cycles = clk.clock_cpu;
float cpu_speed = cpu_elapsed_cycles / cpu_elapsed_seconds.count();
cpu_speed_averaged.add(cpu_speed);
APPLE2Einterface::iterate(mode_history, clk.clock_cpu, cpu_speed_averaged.get() / 1000000.0f);
mode_history.clear();
chrono::time_point<chrono::system_clock> now = std::chrono::system_clock::now();
@ -1838,7 +1888,7 @@ int main(int argc, char **argv)
}
mainboard->sync();
APPLE2Einterface::iterate(mode_history, clk.clock_cpu);
APPLE2Einterface::iterate(mode_history, clk.clock_cpu, 1.023);
mode_history.clear();
}
}

View File

@ -128,19 +128,31 @@ bool CheckProgramLink(GLuint program)
return false;
}
void opengl_texture::load(int w_, int h_, unsigned char *pixels)
{
w = w_;
h = h_;
glBindTexture(GL_TEXTURE_2D, t);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);
glBindTexture(GL_TEXTURE_2D, GL_NONE);
}
opengl_texture initialize_texture(int w, int h, unsigned char *pixels)
{
GLuint tex;
glGenTextures(1, &tex);
opengl_texture t = {w, h, tex};
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
CheckOpenGL(__FILE__, __LINE__);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, pixels);
t.load(w, h, pixels);
CheckOpenGL(__FILE__, __LINE__);
return {w, h, tex};
return t;
}
GLuint GenerateProgram(const std::string& shader_name, const std::string& vertex_shader_text, const std::string& fragment_shader_text)

View File

@ -98,6 +98,7 @@ struct opengl_texture
int h;
GLuint t;
operator GLuint() const { return t; }
void load(int w, int h, unsigned char *pixels = NULL);
};
opengl_texture initialize_texture(int w, int h, unsigned char *pixels = NULL);

View File

@ -753,12 +753,9 @@ struct text_widget : public widget
float fg[4];
float bg[4];
text_widget(const string& content_) :
content(content_)
void set_content(const string& content_)
{
set(fg, 1, 1, 1, 0);
set(bg, 0, 0, 0, 0);
content = content_;
// construct string texture
unique_ptr<unsigned char> bytes(new unsigned char[content.size() + 1]);
int i = 0;
@ -773,10 +770,21 @@ struct text_widget : public widget
bytes.get()[i] = 255;
i++;
}
string_texture = initialize_texture(i, 1, bytes.get());
string_texture.load(i, 1, bytes.get());
rectangle.clear();
rectangle.push_back({make_rectangle_array_buffer(0, 0, i * 7, 8), raster_coords_attrib, 2, GL_FLOAT, GL_FALSE, 0});
}
text_widget(const string& content_) :
content(content_)
{
set(fg, 1, 1, 1, 0);
set(bg, 0, 0, 0, 0);
string_texture = initialize_texture(1, 1, NULL);
set_content(content_);
}
virtual width_height get_min_dimensions() const
{
return {content.size() * 7, 8};
@ -967,10 +975,50 @@ struct toggle : public text_widget
}
};
struct textbox : public text_widget
{
textbox(const string& content_):
text_widget(content_)
{
set(fg, 1, 1, 1, 1);
set(bg, 0, 0, 0, 1);
}
virtual width_height get_min_dimensions() const
{
float w, h;
tie(w, h) = text_widget::get_min_dimensions();
return {w + 3 * 2, h + 3 * 2};
}
virtual void draw(double now, float to_screen[9], float x, float y, float w, float h)
{
// draw lines 2 pixels around
// draw lines 1 pixels around
// blank area 0 pixels around
text_widget::draw(now, to_screen, x + 3, y + 3, w - 6, h - 6);
}
virtual bool click(double now, float x, float y)
{
return false;
}
virtual void drag(double now, float x, float y)
{
}
virtual void release(double now, float x, float y)
{
}
};
widget *ui;
widget *screen_only;
toggle *caps_toggle;
toggle *record_toggle;
textbox *speed_textbox;
void initialize_gl(void)
{
@ -1264,8 +1312,9 @@ void initialize_widgets(bool run_fast, bool add_floppies, bool floppy0_inserted,
toggle *color_toggle = new toggle("COLOR", false, [](){draw_using_color = true;}, [](){draw_using_color = false;});
toggle *pause_toggle = new toggle("PAUSE", false, [](){event_queue.push_back({PAUSE, 1});}, [](){event_queue.push_back({PAUSE, 0});});
record_toggle = new toggle("RECORD", false, [](){start_record();}, [](){stop_record();});
speed_textbox = new textbox("X.YYY MHz");
vector<widget*> controls = {reset_momentary, reboot_momentary, fast_toggle, caps_toggle, color_toggle, pause_toggle, record_toggle};
vector<widget*> controls = {reset_momentary, reboot_momentary, fast_toggle, caps_toggle, color_toggle, pause_toggle, record_toggle, speed_textbox};
if(add_floppies) {
floppy0_icon = new floppy_icon(0, floppy0_inserted);
floppy1_icon = new floppy_icon(1, floppy1_inserted);
@ -1684,8 +1733,24 @@ void map_history_to_lines(const ModeHistory& history, unsigned long long current
map_mode_to_lines(most_recent_modepoint, current_byte);
}
void iterate(const ModeHistory& history, unsigned long long current_byte)
void iterate(const ModeHistory& history, unsigned long long current_byte, float megahertz)
{
static char speed_cstr[10];
if(megahertz >= 100000.0) {
sprintf(speed_cstr, "very fast");
} else if(megahertz >= 10000.0) {
sprintf(speed_cstr, "%5.2f GHz", megahertz);
} else if(megahertz >= 1000.0) {
sprintf(speed_cstr, "%5.3f GHz", megahertz);
} else if(megahertz >= 100.0) {
sprintf(speed_cstr, "%5.1f MHz", megahertz);
} else if(megahertz >= 10.0) {
sprintf(speed_cstr, "%5.2f MHz", megahertz);
} else {
sprintf(speed_cstr, "%5.3f MHz", megahertz);
}
speed_textbox->set_content(speed_cstr);
apply_writes();
CheckOpenGL(__FILE__, __LINE__);

View File

@ -95,7 +95,7 @@ void show_floppy_activity(int number, bool activity);
void enqueue_audio_samples(char *buf, size_t sz);
void start(bool run_fast, bool add_floppies, bool floppy0_inserted, bool floppy1_inserted);
void iterate(const ModeHistory& history, unsigned long long current_byte_in_frame); // display
void iterate(const ModeHistory& history, unsigned long long current_byte_in_frame, float megahertz); // display
void shutdown();
};