Graphics Ansatz (DOESN'T WORK)

This commit is contained in:
Luxdragon 2024-01-15 14:06:04 +01:00
parent 8d6beee1fd
commit 2b343e6dca

View file

@ -7,6 +7,9 @@
// gcc emulator_shell.c `pkg-config --cflags --libs gtk+-3.0` -o emulator
#define FREQUENCY 500
#define WIDTH 224
#define HEIGHT 256
void keyDown(uint8_t key);
void keyUp(uint8_t key);
@ -81,13 +84,14 @@ static gboolean on_key_release(GtkWidget *widget, GdkEventKey *event, gpointer u
//===== EMULATOR SETUP =====
uint8_t in_port; //GLOBAL VAR
char which_interrupt = 1; //GLOBAL VAR
//GLOBAL VARIABLES
uint8_t in_port;
char which_interrupt;
//GLOBAL GRAPHICS
uint8_t *bitmap = NULL;
int bitmap_width = 224;
int bitmap_height = 256;
typedef struct ConditionCodes {
//bitfields for condition codes
@ -992,65 +996,58 @@ void simulateNanoseconds(unsigned int numNanoseconds)
nanosleep(&sleepTime, NULL);
}
typedef struct cpu_data {
char done;
int total_cycles_count;
GtkWidget* drawing_area;
State8080 *state;
} cpu_data;
// ===== 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);
static void draw_callback(GtkWidget *widget, cairo_t *cr, gpointer user_data) {
int x, y;
for (y = 0; y < HEIGHT; y++) {
for (x = 0; x < WIDTH; x++) {
if (bitmap[y * WIDTH + x]) {
cairo_rectangle(cr, x, y, 1, 1);
cairo_fill(cr);
}
}
}
}
return FALSE;
static gboolean cpu(gpointer user_data) {
cpu_data *cpu = user_data;
char done = cpu->done;
State8080* state = cpu->state;
int counter;
while (!done) {
counter = emulate8080(cpu->state);
cpu->total_cycles_count += counter;
simulateNanoseconds(FREQUENCY * counter); // EMULATION OF THE PROCESSOR ŠPEED
if ((cpu->total_cycles_count > 16000000) && (state->int_enable)) //1/60 second has elapsed
{
gtk_widget_queue_draw(user_data);
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;
}
}
}
}
int main (int argc, char *argv[]) {
// GTK INIT
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);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// EMULATOR INIT
State8080 *state = (State8080*) calloc(1, sizeof(State8080)); //memset obsolte with calloc
@ -1067,9 +1064,17 @@ int main (int argc, char *argv[]) {
read_Space_Invaders_ROM(state, "ROM/invaders.f", 0x1000);
read_Space_Invaders_ROM(state, "ROM/invaders.e", 0x1800);
// DRAWING AREA INIT
// GTK INIT
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);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// DRAWING AREA INIT
bitmap = &(state->memory[0x2400]);
GtkWidget *drawing_area = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), drawing_area);
@ -1078,36 +1083,20 @@ int main (int argc, char *argv[]) {
// CPU INIT
cpu_data *cpu_eco = malloc(sizeof(cpu_data));
cpu_eco->state = state;
cpu_eco->drawing_area = drawing_area;
cpu_eco->done = 0;
cpu_eco->total_cycles_count = 0;
g_idle_add(cpu, cpu_eco);
int i = 0;
char done = 0;
int counter;
int total_count = 0;
while (!done) {
counter = emulate8080(state);
total_count += counter;
i++;
simulateNanoseconds(FREQUENCY * counter); // EMULATION OF THE PROCESSOR ŠPEED
if ((total_count > 16000000) && (state->int_enable)) //1/60 second has elapsed
{
gtk_widget_queue_draw(drawing_area);
if (which_interrupt == 2) {
generateInterrupt(state, 2); //interrupt 2
total_count = 0;
which_interrupt = 1;
} else {
generateInterrupt(state, 1); //interrupt 0
total_count = 0;
which_interrupt = 2;
}
}
}
//MAIN LOOP & TERMINATION
gtk_main();
free(state->memory);
free(state);
free(cpu_eco);
return 0;
}