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); 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) int main(int argc, char **argv)
{ {
char *progname = argv[0]; 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); 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> 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) { while(1) {
if(!debugging) { if(!debugging) {
@ -1772,7 +1811,18 @@ int main(int argc, char **argv)
} }
mainboard->sync(); 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(); mode_history.clear();
chrono::time_point<chrono::system_clock> now = std::chrono::system_clock::now(); chrono::time_point<chrono::system_clock> now = std::chrono::system_clock::now();
@ -1838,7 +1888,7 @@ int main(int argc, char **argv)
} }
mainboard->sync(); mainboard->sync();
APPLE2Einterface::iterate(mode_history, clk.clock_cpu); APPLE2Einterface::iterate(mode_history, clk.clock_cpu, 1.023);
mode_history.clear(); mode_history.clear();
} }
} }

View File

@ -128,19 +128,31 @@ bool CheckProgramLink(GLuint program)
return false; 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) opengl_texture initialize_texture(int w, int h, unsigned char *pixels)
{ {
GLuint tex; GLuint tex;
glGenTextures(1, &tex); glGenTextures(1, &tex);
opengl_texture t = {w, h, tex};
glBindTexture(GL_TEXTURE_2D, tex); glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
CheckOpenGL(__FILE__, __LINE__); 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__); 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) 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; int h;
GLuint t; GLuint t;
operator GLuint() const { return 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); 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 fg[4];
float bg[4]; float bg[4];
text_widget(const string& content_) : void set_content(const string& content_)
content(content_)
{ {
set(fg, 1, 1, 1, 0); content = content_;
set(bg, 0, 0, 0, 0);
// construct string texture // construct string texture
unique_ptr<unsigned char> bytes(new unsigned char[content.size() + 1]); unique_ptr<unsigned char> bytes(new unsigned char[content.size() + 1]);
int i = 0; int i = 0;
@ -773,10 +770,21 @@ struct text_widget : public widget
bytes.get()[i] = 255; bytes.get()[i] = 255;
i++; 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}); 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 virtual width_height get_min_dimensions() const
{ {
return {content.size() * 7, 8}; 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 *ui;
widget *screen_only; widget *screen_only;
toggle *caps_toggle; toggle *caps_toggle;
toggle *record_toggle; toggle *record_toggle;
textbox *speed_textbox;
void initialize_gl(void) 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 *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});}); 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();}); 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) { if(add_floppies) {
floppy0_icon = new floppy_icon(0, floppy0_inserted); floppy0_icon = new floppy_icon(0, floppy0_inserted);
floppy1_icon = new floppy_icon(1, floppy1_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); 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(); apply_writes();
CheckOpenGL(__FILE__, __LINE__); 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 enqueue_audio_samples(char *buf, size_t sz);
void start(bool run_fast, bool add_floppies, bool floppy0_inserted, bool floppy1_inserted); 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(); void shutdown();
}; };