From fd1e15a595fe738e897a68b936e4e2f0fe53fe83 Mon Sep 17 00:00:00 2001 From: Brad Grantham Date: Mon, 18 Feb 2019 08:11:22 -0800 Subject: [PATCH] add clock text box --- apple2e.cpp | 54 +++++++++++++++++++++++++++++++-- gl_utility.cpp | 16 ++++++++-- gl_utility.h | 1 + interface.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++++----- interface.h | 2 +- 5 files changed, 141 insertions(+), 13 deletions(-) diff --git a/apple2e.cpp b/apple2e.cpp index f15234a..07407f3 100644 --- a/apple2e.cpp +++ b/apple2e.cpp @@ -1592,6 +1592,42 @@ void print_cpu_state(const CPU6502& cpu) printf("S:%02X (%02X %02X %02X ...) PC:%04X (%02X %02X %02X ...)\n", cpu.s, s0, s1, s2, cpu.pc, pc0, pc1, pc2); } +template +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 then = std::chrono::system_clock::now(); + chrono::time_point cpu_speed_then = std::chrono::system_clock::now(); + clk_t cpu_previous_cycles = 0; + averaged_sequence 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 cpu_speed_now = std::chrono::system_clock::now(); + + auto cpu_elapsed_seconds = chrono::duration_cast >(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 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(); } } diff --git a/gl_utility.cpp b/gl_utility.cpp index 9e5e622..fe0690c 100644 --- a/gl_utility.cpp +++ b/gl_utility.cpp @@ -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) diff --git a/gl_utility.h b/gl_utility.h index 9cae34a..9d78b1e 100644 --- a/gl_utility.h +++ b/gl_utility.h @@ -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); diff --git a/interface.cpp b/interface.cpp index f40c22a..c6ffd53 100644 --- a/interface.cpp +++ b/interface.cpp @@ -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 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 controls = {reset_momentary, reboot_momentary, fast_toggle, caps_toggle, color_toggle, pause_toggle, record_toggle}; + vector 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__); diff --git a/interface.h b/interface.h index bd5b9d2..9367bcc 100644 --- a/interface.h +++ b/interface.h @@ -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(); };