Further GTK tinkering (EMU needs extra commands)
This commit is contained in:
parent
37ce16ca8a
commit
75b647f9ac
1 changed files with 83 additions and 113 deletions
196
emulator_shell.c
196
emulator_shell.c
|
@ -87,6 +87,7 @@ static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer u
|
|||
//GLOBAL VARIABLES
|
||||
uint8_t in_port;
|
||||
char which_interrupt;
|
||||
uint8_t upscaleFactor = 2;
|
||||
|
||||
//GLOBAL GRAPHICS
|
||||
uint8_t *bitmap = NULL;
|
||||
|
@ -1452,92 +1453,37 @@ typedef struct cpu_data {
|
|||
|
||||
} cpu_data;
|
||||
|
||||
void *cpu(void* arg) {
|
||||
cpu_data *cpu = (cpu_data*) arg;
|
||||
char done = cpu->done;
|
||||
State8080* state = cpu->state;
|
||||
int counter;
|
||||
|
||||
while (!done) {
|
||||
counter = emulate8080(cpu->state);
|
||||
cpu->total_cycles_count += counter;
|
||||
printf("Total cycles: %d\n", cpu->total_cycles_count);
|
||||
|
||||
//usleep(counter / 2); // EMULATION OF THE PROCESSOR ŠPEED
|
||||
if ((cpu->total_cycles_count > 16000) && (state->int_enable)) //1/60 second has elapsed
|
||||
{
|
||||
//redraw screen() will be handeled by the gtk_main() function
|
||||
if (which_interrupt == 2) {
|
||||
generateInterrupt(state, 2); //interrupt 2
|
||||
cpu->total_cycles_count = 0;
|
||||
which_interrupt = 1;
|
||||
} else {
|
||||
generateInterrupt(state, 1); //interrupt 1
|
||||
cpu->total_cycles_count = 0;
|
||||
which_interrupt = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===== GTK GRAPHICS =====
|
||||
|
||||
// static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||
// int upscaleFactor = 1;
|
||||
// uint8_t *video = malloc(sizeof(uint8_t) * 224 * 256);
|
||||
// //ROTATION ALGORITHM
|
||||
// for (int i=0; i< 224; i++)
|
||||
// {
|
||||
// for (int j = 0; j < 256; j+= 8)
|
||||
// {
|
||||
// //Read the first 1-bit pixel
|
||||
// // divide by 8 because there are 8 pixels
|
||||
// // in a byte
|
||||
// uint8_t pix = bitmap[(i*(256/8)) + j/8];
|
||||
|
||||
// //That makes 8 output vertical pixels
|
||||
// // we need to do a vertical flip
|
||||
// // so j needs to start at the last line
|
||||
// // and advance backward through the buffer
|
||||
// int offset = (255-j)*(224*4) + (i*4);
|
||||
// uint8_t *p1 = (uint8_t*)(&video[offset]);
|
||||
// for (int p=0; p<8; p++)
|
||||
// {
|
||||
// if ( 0!= (pix & (1<<p)))
|
||||
// *p1 = 1;
|
||||
// else
|
||||
// *p1 = 0;
|
||||
// p1-=224; //next line
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// for (int x = 0; x < 256; x++) {
|
||||
// for (int y = 0; y < 224; y++) {
|
||||
// if (video[y*256 + x]) {
|
||||
// cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white
|
||||
// } else {
|
||||
// cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Set color to black
|
||||
// }
|
||||
|
||||
// cairo_rectangle(cr, x * upscaleFactor, y * upscaleFactor, upscaleFactor, upscaleFactor);
|
||||
// cairo_fill(cr);
|
||||
// }
|
||||
// }
|
||||
|
||||
// free(video);
|
||||
// }
|
||||
|
||||
// static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||
// int upscaleFactor = 1;
|
||||
// uint8_t *video = malloc(sizeof(uint8_t) * 224 * 256);
|
||||
// // Clear the drawing area
|
||||
// cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
||||
// cairo_paint(cr);
|
||||
|
||||
// // Copying the bitmap to video output
|
||||
// for (int i = 0; i < 224; i++) {
|
||||
// for (int j = 0; j < 32; j++) {
|
||||
// uint8_t byte = bitmap[i*32 + j];
|
||||
// for (int p = 0; p < 8; p++) {
|
||||
// int pixel = (byte >> (7 - p)) & 1; // flip the bit order
|
||||
// int x = 255 - (j*8 + p); // flip the x-coordinate
|
||||
// int y = i;
|
||||
// video[y*256 + x] = pixel;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Rendering the graphics
|
||||
// for (int x = 0; x < 256; x++) {
|
||||
// for (int y = 0; y < 224; y++) {
|
||||
// if (video[y*256 + x]) {
|
||||
// cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); // Set color to white
|
||||
// } else {
|
||||
// cairo_set_source_rgb(cr, 0.0, 0.0, 0.0); // Set color to black
|
||||
// }
|
||||
|
||||
// cairo_rectangle(cr, x * upscaleFactor, y * upscaleFactor, upscaleFactor, upscaleFactor);
|
||||
// cairo_fill(cr);
|
||||
// }
|
||||
// }
|
||||
|
||||
// free(video);
|
||||
// }
|
||||
|
||||
static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
||||
int upscaleFactor = 2;
|
||||
uint8_t *video = malloc(sizeof(uint8_t) * 256 * 256); // Adjusted size
|
||||
// Clear the drawing area
|
||||
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
|
||||
|
@ -1575,35 +1521,16 @@ static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
|
|||
free(video);
|
||||
}
|
||||
|
||||
|
||||
void *cpu(void* arg) {
|
||||
cpu_data *cpu = (cpu_data*) arg;
|
||||
char done = cpu->done;
|
||||
State8080* state = cpu->state;
|
||||
int counter;
|
||||
|
||||
while (!done) {
|
||||
counter = emulate8080(cpu->state);
|
||||
cpu->total_cycles_count += counter;
|
||||
printf("Total cycles: %d\n", cpu->total_cycles_count);
|
||||
|
||||
//usleep(counter / 2); // EMULATION OF THE PROCESSOR ŠPEED
|
||||
if ((cpu->total_cycles_count > 16000) && (state->int_enable)) //1/60 second has elapsed
|
||||
{
|
||||
//redraw screen() will be handeled by the gtk_main() function
|
||||
if (which_interrupt == 2) {
|
||||
generateInterrupt(state, 2); //interrupt 2
|
||||
cpu->total_cycles_count = 0;
|
||||
which_interrupt = 1;
|
||||
} else {
|
||||
generateInterrupt(state, 1); //interrupt 1
|
||||
cpu->total_cycles_count = 0;
|
||||
which_interrupt = 2;
|
||||
void on_about_clicked(GtkToolButton *toolbutton, gpointer user_data) {
|
||||
GtkWidget *dialog = gtk_about_dialog_new();
|
||||
gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(dialog), "Turi's Super Duper Emulatinator");
|
||||
gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(dialog), "This is a super duper emulatinator created by Turi.");
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file("Luka.png", NULL);
|
||||
gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(dialog), pixbuf);
|
||||
g_object_unref(pixbuf);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gboolean update_ui(gpointer data) {
|
||||
// Seems like GTK is not thread safe
|
||||
|
@ -1615,6 +1542,19 @@ gboolean update_ui(gpointer data) {
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void on_size_changed(GtkComboBox *combo_box, gpointer user_data) {
|
||||
gchar *text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo_box));
|
||||
if (g_strcmp0(text, "1x") == 0) {
|
||||
upscaleFactor = 1;
|
||||
} else if (g_strcmp0(text, "2x") == 0) {
|
||||
upscaleFactor = 2;
|
||||
} else if (g_strcmp0(text, "3x") == 0) {
|
||||
upscaleFactor = 3;
|
||||
}
|
||||
g_free(text);
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
|
||||
// Emulator init
|
||||
|
@ -1638,17 +1578,47 @@ int main (int argc, char *argv[]) {
|
|||
gtk_init(&argc, &argv);
|
||||
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
|
||||
gtk_window_set_title(GTK_WINDOW(window), "Turi's Super Duper Emulatinator");
|
||||
gtk_window_set_title(GTK_WINDOW(window), "Luxulator");
|
||||
g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL);
|
||||
g_signal_connect(window, "key-release-event", G_CALLBACK(on_key_release), NULL);
|
||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||
|
||||
// Toolbar init
|
||||
GtkWidget *toolbar = gtk_toolbar_new();
|
||||
GtkCssProvider *provider = gtk_css_provider_new();
|
||||
gtk_css_provider_load_from_data(provider, "* { -GtkWidget-toolbar-style: both-horiz; }", -1, NULL);
|
||||
gtk_style_context_add_provider(gtk_widget_get_style_context(toolbar), GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
|
||||
// Size option in the toolbar
|
||||
GtkToolItem *size = gtk_tool_item_new();
|
||||
GtkWidget *combo_box = gtk_combo_box_text_new();
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), "1x");
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), "2x");
|
||||
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), "3x");
|
||||
gtk_container_add(GTK_CONTAINER(size), combo_box);
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), size, -1);
|
||||
g_signal_connect(combo_box, "changed", G_CALLBACK(on_size_changed), NULL);
|
||||
|
||||
// About option in the toolbar
|
||||
|
||||
GtkToolItem *about = gtk_tool_button_new(NULL, "About");
|
||||
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), about, -1);
|
||||
g_signal_connect(about, "clicked", G_CALLBACK(on_about_clicked), NULL);
|
||||
|
||||
// Drawing area init
|
||||
bitmap = &(state->memory[0x2400]);
|
||||
GtkWidget *drawing_area = gtk_drawing_area_new();
|
||||
gtk_widget_set_app_paintable(drawing_area, TRUE);
|
||||
gtk_container_add(GTK_CONTAINER(window), drawing_area);
|
||||
g_signal_connect(drawing_area, "draw", G_CALLBACK(draw_callback), NULL);
|
||||
|
||||
// VBox to hold toolbar and drawing area
|
||||
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0);
|
||||
gtk_container_add(GTK_CONTAINER(window), vbox);
|
||||
|
||||
|
||||
|
||||
gtk_widget_show_all(window);
|
||||
|
||||
// CPU-init
|
||||
|
|
Loading…
Reference in a new issue