From 8fec9395a77eaddf7dc70bceefae2b190f7108c4 Mon Sep 17 00:00:00 2001 From: Luxdragon Date: Sun, 14 Jan 2024 22:35:01 +0100 Subject: [PATCH] Graphics skeleton implemented --- emulator_shell.c | 78 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/emulator_shell.c b/emulator_shell.c index a77617f..50c4625 100644 --- a/emulator_shell.c +++ b/emulator_shell.c @@ -81,8 +81,13 @@ static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer u //===== EMULATOR SETUP ===== -uint8_t in_port; //GLOBALLY DECLARED -char which_interrupt = 1; //GLOBALLY DECLARED +uint8_t in_port; //GLOBAL VAR +char which_interrupt = 1; //GLOBAL VAR + +//GLOBAL GRAPHICS +unsigned char *bitmap = NULL; +int bitmap_width = 224; +int bitmap_height = 256; typedef struct ConditionCodes { //bitfields for condition codes @@ -987,6 +992,52 @@ void simulateNanoseconds(unsigned int numNanoseconds) nanosleep(&sleepTime, NULL); } +// ===== GTK GRAPHICS ===== + +// Callback function to handle the "draw" signal of the Drawing Area +gboolean draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) +{ + // Check if the bitmap image data is available + if (bitmap != NULL && bitmap_width > 0 && bitmap_height > 0) + { + // Get the width and height of the drawing area + int width, height; + gtk_widget_get_size_request(widget, &width, &height); + + // Calculate the width and height of each pixel + int pixel_width = width / bitmap_width; + int pixel_height = height / bitmap_height; + + // Iterate over each pixel in the bitmap image + for (int y = 0; y < bitmap_height; y++) + { + for (int x = 0; x < bitmap_width; x++) + { + // Determine the color of the pixel + unsigned char pixel = bitmap[y * bitmap_width + x]; + + // Set the color based on the pixel value + if (pixel == 0) + { + // Black pixel + cairo_set_source_rgb(cr, 0, 0, 0); + } + else + { + // White pixel + cairo_set_source_rgb(cr, 1, 1, 1); + } + + // Draw the pixel + cairo_rectangle(cr, x * pixel_width, y * pixel_height, pixel_width, pixel_height); + cairo_fill(cr); + } + } + } + + return FALSE; +} + int main (int argc, char *argv[]) { @@ -994,9 +1045,15 @@ int main (int argc, char *argv[]) { gtk_init(&argc, &argv); GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_print("Test\n"); + gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); + gtk_window_set_title(GTK_WINDOW(window), "Lux8080-Emulator"); 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); - gtk_widget_show(window); + g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); + g_signal_connect(drawing_area, "draw", G_CALLBACK(draw_callback), NULL); + + + // EMULATOR INIT @@ -1014,7 +1071,15 @@ int main (int argc, char *argv[]) { read_Space_Invaders_ROM(state, "ROM/invaders.g", 0x800); read_Space_Invaders_ROM(state, "ROM/invaders.f", 0x1000); read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800); - gtk_main(); + + + // DRAWING AREA INIT + + bitmap = state->memory[0x2400]; + GtkWidget *drawing_area = gtk_drawing_area_new(); + gtk_container_add(GTK_CONTAINER(window), drawing_area); + gtk_widget_show_all(window); + @@ -1031,7 +1096,7 @@ int main (int argc, char *argv[]) { simulateNanoseconds(FREQUENCY * counter); // EMULATION OF THE PROCESSOR ŠPEED if ((total_count > 16000000) && (state->int_enable)) //1/60 second has elapsed { - // draw_screen(state); + gtk_widget_queue_draw(drawing_area); if (which_interrupt == 2) { generateInterrupt(state, 2); //interrupt 2 total_count = 0; @@ -1043,7 +1108,8 @@ int main (int argc, char *argv[]) { } } } - + + gtk_main(); free(state->memory); free(state); return 0;