From 0a91f27e71bacee11e5d7e9c3a01b17284732331 Mon Sep 17 00:00:00 2001 From: procyonsjj Date: Wed, 20 Nov 2013 01:06:34 +0000 Subject: [PATCH] SDL Voxel Engine first pass --- branches/voxel/src/drivers/sdl/config.cpp | 16 + branches/voxel/src/drivers/sdl/gui.cpp | 448 ++++++++++++++++- branches/voxel/src/drivers/sdl/input.cpp | 21 + branches/voxel/src/drivers/sdl/sdl-opengl.cpp | 2 +- branches/voxel/src/drivers/sdl/sdl-video.cpp | 22 +- branches/voxel/src/drivers/sdl/sdl-voxel.cpp | 460 ++++++++++++++++++ branches/voxel/src/drivers/sdl/sdl-voxel.h | 9 + branches/voxel/src/input/zapper.cpp | 23 +- 8 files changed, 981 insertions(+), 20 deletions(-) create mode 100644 branches/voxel/src/drivers/sdl/sdl-voxel.cpp create mode 100644 branches/voxel/src/drivers/sdl/sdl-voxel.h diff --git a/branches/voxel/src/drivers/sdl/config.cpp b/branches/voxel/src/drivers/sdl/config.cpp index 0dbb2a92..8ff718bf 100644 --- a/branches/voxel/src/drivers/sdl/config.cpp +++ b/branches/voxel/src/drivers/sdl/config.cpp @@ -182,6 +182,22 @@ InitConfig() config->addOption("SDL.SpecialFilter", 0); config->addOption("SDL.SpecialFX", 0); config->addOption("SDL.Vsync", 1); + config->addOption("voxel", "SDL.VoxelEngine", 1); + + // Voxel engine options + config->addOption("voxelXscale", "SDL.VoxelXScale", 1.0); + config->addOption("voxelYscale", "SDL.VoxelYScale", 1.0); + config->addOption("voxelZscale", "SDL.VoxelZScale", 1.0); + config->addOption("voxelTransparency", "SDL.VoxelTransparency", 1.0); + config->addOption("voxelXspace", "SDL.VoxelXSpace", 0.0); + config->addOption("voxelYspace", "SDL.VoxelYSpace", 0.0); + config->addOption("voxelBGCMethod", "SDL.VoxelBGCMethod", 0); + config->addOption("voxelXcoord", "SDL.VoxelXCoordBGC", 0); + config->addOption("voxelYcoord", "SDL.VoxelYCoordBGC", 0); + config->addOption("voxelWaves", "SDL.VoxelWaves", 0); + config->addOption("voxelWaveLength", "SDL.VoxelWavelength", 1.0); + config->addOption("voxelWaveFrequency", "SDL.VoxelWaveFrequency", 1.0); + config->addOption("voxelWaveAmplitude", "SDL.VoxelWaveAmplitude", 1.0); // network play options - netplay is broken config->addOption("server", "SDL.NetworkIsServer", 0); diff --git a/branches/voxel/src/drivers/sdl/gui.cpp b/branches/voxel/src/drivers/sdl/gui.cpp index 98d4471a..959fe1ea 100644 --- a/branches/voxel/src/drivers/sdl/gui.cpp +++ b/branches/voxel/src/drivers/sdl/gui.cpp @@ -869,6 +869,15 @@ void setDoubleBuffering(GtkWidget* w, gpointer p) g_config->setOption("SDL.DoubleBuffering", 0); g_config->save(); } + +void setVoxel(GtkWidget* w, gpointer p) +{ + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) + g_config->setOption("SDL.VoxelEngine", 1); + else + g_config->setOption("SDL.VoxelEngine", 0); + g_config->save(); +} #endif void openVideoConfig() @@ -882,6 +891,7 @@ void openVideoConfig() GtkWidget* glChk; GtkWidget* linearChk; GtkWidget* dbChk; + GtkWidget* voxelChk; GtkWidget* palChk; GtkWidget* ppuChk; GtkWidget* spriteLimitChk; @@ -951,7 +961,7 @@ void openVideoConfig() else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linearChk), 0); - // DoubleBuffering check + // DoubleBuffering check dbChk = gtk_check_button_new_with_label("Enable double buffering"); g_signal_connect(dbChk, "clicked", G_CALLBACK(setDoubleBuffering), NULL); @@ -962,6 +972,19 @@ void openVideoConfig() gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dbChk), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(dbChk), 0); + + // Voxel check + voxelChk = gtk_check_button_new_with_label("Enable voxel engine"); + g_signal_connect(voxelChk, "clicked", G_CALLBACK(setVoxel), NULL); + + // sync with config + buf = 0; + g_config->getOption("SDL.VoxelEngine", &buf); + if(buf) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(voxelChk), 1); + else + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(voxelChk), 0); + #endif @@ -1069,6 +1092,7 @@ void openVideoConfig() gtk_box_pack_start(GTK_BOX(vbox), glChk, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), linearChk, FALSE, FALSE, 5); gtk_box_pack_start(GTK_BOX(vbox), dbChk, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), voxelChk, FALSE, FALSE, 5); #endif gtk_box_pack_start(GTK_BOX(vbox), palChk, FALSE, FALSE,5); gtk_box_pack_start(GTK_BOX(vbox), ppuChk, FALSE, FALSE, 5); @@ -1088,6 +1112,377 @@ void openVideoConfig() return; } + +#ifdef OPENGL +int setVoxelXscale(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelXScale", v); + g_config->save(); + return 0; +} + +int setVoxelYscale(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelYScale", v); + g_config->save(); + return 0; +} + +int setVoxelZscale(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelZScale", v); + g_config->save(); + return 0; +} + +int setTransparency(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelTransparency", v); + g_config->save(); + return 0; +} + +int setVoxelXspace(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelXSpace", v); + g_config->save(); + return 0; +} + +int setVoxelYspace(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelYSpace", v); + g_config->save(); + return 0; +} + +int setXcoordBGC(GtkWidget* w, gpointer p) +{ + int v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelXCoordBGC", v); + g_config->save(); + return 0; +} + +int setYcoordBGC(GtkWidget* w, gpointer p) +{ + int v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelYCoordBGC", v); + g_config->save(); + return 0; +} + +void toggleSystemBGC(GtkToggleButton *t, gpointer user_data) +{ + g_config->setOption("SDL.VoxelBGCMethod", 0); + g_config->save(); +} + +void togglePrevalentBGC(GtkToggleButton *t, gpointer user_data) +{ + g_config->setOption("SDL.VoxelBGCMethod", 1); + g_config->save(); +} + +void toggleCoordBGC(GtkToggleButton *t, gpointer user_data) +{ + g_config->setOption("SDL.VoxelBGCMethod", 2); + g_config->save(); +} + +void setVoxelWaves(GtkWidget* w, gpointer p) +{ + int x = gtk_combo_box_get_active(GTK_COMBO_BOX(w)); + g_config->setOption("SDL.VoxelWaves", x); + g_config->save(); +} + +int setWavelength(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelWavelength", v); + g_config->save(); + return 0; +} + +int setAmplitude(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelWaveAmplitude", v); + g_config->save(); + return 0; +} + +int setFrequency(GtkWidget* w, gpointer p) +{ + double v = gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); + g_config->setOption("SDL.VoxelWaveFrequency", v); + g_config->save(); + return 0; +} + +void openVoxelConfig() +{ + GtkWidget* win; + GtkWidget* vbox; + GtkWidget* disclaimer; + GtkWidget* scaleLbl; + GtkWidget* scaleHbox; + GtkWidget* xscaleSpin; + GtkWidget* yscaleSpin; + GtkWidget* xscaleLbl; + GtkWidget* yscaleLbl; + GtkWidget* depthHbox; + GtkWidget* depthLbl; + GtkWidget* depthSpin; + GtkWidget* transHbox; + GtkWidget* transLbl; + GtkWidget* transSpin; + GtkWidget* spaceLbl; + GtkWidget* spaceHbox; + GtkWidget* xspaceSpin; + GtkWidget* yspaceSpin; + GtkWidget* xspaceLbl; + GtkWidget* yspaceLbl; + GSList* groupBGC; + GtkWidget* systemBGC; + GtkWidget* prevalentBGC; + GtkWidget* coordBGC; + GtkWidget* coordHbox; + GtkWidget* xcoordBGC; + GtkWidget* ycoordBGC; + GtkWidget* xcoordLbl; + GtkWidget* ycoordLbl; + GtkWidget* waveHbox; + GtkWidget* waveLbl; + GtkWidget* waveCombo; + GtkWidget* wavelengthHbox; + GtkWidget* wavelengthLbl; + GtkWidget* wavelengthSpin; + GtkWidget* amplitudeHbox; + GtkWidget* amplitudeLbl; + GtkWidget* amplitudeSpin; + GtkWidget* frequencyHbox; + GtkWidget* frequencyLbl; + GtkWidget* frequencySpin; + GtkWidget* freqNoteLbl; + + double f; + int i; + + win = gtk_dialog_new_with_buttons("Voxel Configuration", + GTK_WINDOW(MainWindow), + (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL); + gtk_window_set_icon_name(GTK_WINDOW(win), "voxels"); + + vbox = gtk_dialog_get_content_area(GTK_DIALOG(win)); + + disclaimer = gtk_label_new("Voxel engine is for experimentation\npurposes only, and will not work\nwell with every game that you try."); + + // Scale of voxels + scaleLbl = gtk_label_new("Scale of voxels"); + scaleHbox = gtk_hbox_new(FALSE, 5); + xscaleLbl = gtk_label_new("X:"); + xscaleSpin = gtk_spin_button_new_with_range(0.1, 16.0, .1); + yscaleLbl = gtk_label_new("Y:"); + yscaleSpin = gtk_spin_button_new_with_range(0.1, 16.0, .1); + + gtk_box_pack_start(GTK_BOX(scaleHbox), xscaleLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(scaleHbox), xscaleSpin, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(scaleHbox), yscaleLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(scaleHbox), yscaleSpin, FALSE, FALSE, 2); + + g_signal_connect(xscaleSpin, "value-changed", G_CALLBACK(setVoxelXscale), NULL); + g_signal_connect(yscaleSpin, "value-changed", G_CALLBACK(setVoxelYscale), NULL); + + // sync with config + g_config->getOption("SDL.VoxelXScale", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(xscaleSpin), f); + g_config->getOption("SDL.VoxelYScale", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(yscaleSpin), f); + + // Voxel depth + depthLbl = gtk_label_new("Voxel Thickness:"); + depthHbox = gtk_hbox_new(FALSE, 5); + depthSpin = gtk_spin_button_new_with_range(0.1, 16.0, .1); + + gtk_box_pack_start(GTK_BOX(depthHbox), depthLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(depthHbox), depthSpin, FALSE, FALSE, 2); + g_signal_connect(depthSpin, "value-changed", G_CALLBACK(setVoxelZscale), NULL); + + g_config->getOption("SDL.VoxelZScale", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(depthSpin), f); + + // Voxel transparency + transLbl = gtk_label_new("Transparency:"); + transHbox = gtk_hbox_new(FALSE, 5); + transSpin = gtk_spin_button_new_with_range(0.00, 1.00, .01); + + gtk_box_pack_start(GTK_BOX(transHbox), transLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(transHbox), transSpin, FALSE, FALSE, 2); + g_signal_connect(transSpin, "value-changed", G_CALLBACK(setTransparency), NULL); + + g_config->getOption("SDL.VoxelTransparency", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(transSpin), f); + + // Space between voxels + spaceLbl = gtk_label_new("Space between voxels"); + spaceHbox = gtk_hbox_new(FALSE, 5); + xspaceLbl = gtk_label_new("X:"); + xspaceSpin = gtk_spin_button_new_with_range(-10.0, 10.0, .1); + yspaceLbl = gtk_label_new("Y:"); + yspaceSpin = gtk_spin_button_new_with_range(-10.0, 10.0, .1); + + gtk_box_pack_start(GTK_BOX(spaceHbox), xspaceLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(spaceHbox), xspaceSpin, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(spaceHbox), yspaceLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(spaceHbox), yspaceSpin, FALSE, FALSE, 2); + + g_signal_connect(xspaceSpin, "value-changed", G_CALLBACK(setVoxelXspace), NULL); + g_signal_connect(yspaceSpin, "value-changed", G_CALLBACK(setVoxelYspace), NULL); + + // sync with config + g_config->getOption("SDL.VoxelXSpace", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(xspaceSpin), f); + g_config->getOption("SDL.VoxelYSpace", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(yspaceSpin), f); + + // How to get the background color + systemBGC = gtk_radio_button_new_with_mnemonic (NULL, "Use system background color, or"); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (systemBGC), groupBGC); + groupBGC = g_slist_append (groupBGC, systemBGC); + + prevalentBGC = gtk_radio_button_new_with_mnemonic (NULL, "Use frame's most prevalent color, or"); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (prevalentBGC), groupBGC); + groupBGC = g_slist_append (groupBGC, prevalentBGC); + + coordBGC = gtk_radio_button_new_with_mnemonic (NULL, "Use coordinate background color:"); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (coordBGC), groupBGC); + groupBGC = g_slist_append (groupBGC, coordBGC); + + coordHbox = gtk_hbox_new(FALSE, 5); + xcoordLbl = gtk_label_new("\tX:"); + xcoordBGC = gtk_spin_button_new_with_range(0, 255, 1); + ycoordLbl = gtk_label_new("Y:"); + ycoordBGC = gtk_spin_button_new_with_range(0, 255, 1); + + gtk_box_pack_start(GTK_BOX(coordHbox), xcoordLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(coordHbox), xcoordBGC, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(coordHbox), ycoordLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(coordHbox), ycoordBGC, FALSE, FALSE, 2); + + g_signal_connect(systemBGC, "toggled", G_CALLBACK(toggleSystemBGC), NULL); + g_signal_connect(prevalentBGC, "toggled", G_CALLBACK(togglePrevalentBGC), NULL); + g_signal_connect(coordBGC, "toggled", G_CALLBACK(toggleCoordBGC), NULL); + g_signal_connect(xcoordBGC, "value-changed", G_CALLBACK(setXcoordBGC), NULL); + g_signal_connect(ycoordBGC, "value-changed", G_CALLBACK(setYcoordBGC), NULL); + + // sync with config + g_config->getOption("SDL.VoxelBGCMethod", &i); + switch (i) + { + case 0: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (systemBGC), TRUE); + break; + case 1: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prevalentBGC), TRUE); + break; + case 2: + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (coordBGC), TRUE); + break; + } + g_config->getOption("SDL.VoxelXCoordBGC", &i); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(xcoordBGC), i); + g_config->getOption("SDL.VoxelYCoordBGC", &i); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(ycoordBGC), i); + + // wave widgets + waveHbox = gtk_hbox_new(FALSE, 3); + waveLbl = gtk_label_new("Waves: "); + waveCombo = gtk_combo_box_text_new(); + // -Wave Types Tag- + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(waveCombo), "disabled"); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(waveCombo), "Horizontal"); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(waveCombo), "Vertical"); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(waveCombo), "Diagonal \\"); + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(waveCombo), "Diagonal /"); + + // sync with cfg + g_config->getOption("SDL.VoxelWaves", &i); + gtk_combo_box_set_active(GTK_COMBO_BOX(waveCombo), i); + + g_signal_connect(waveCombo, "changed", G_CALLBACK(setVoxelWaves), NULL); + gtk_box_pack_start(GTK_BOX(waveHbox), waveLbl, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(waveHbox), waveCombo, FALSE, FALSE, 5); + + // Wave settings + wavelengthLbl = gtk_label_new("\tWavelength:"); + wavelengthHbox = gtk_hbox_new(FALSE, 5); + wavelengthSpin = gtk_spin_button_new_with_range(0.1, 10.0, .1); + + gtk_box_pack_start(GTK_BOX(wavelengthHbox), wavelengthLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(wavelengthHbox), wavelengthSpin, FALSE, FALSE, 2); + + amplitudeLbl = gtk_label_new("\tAmplitude:"); + amplitudeHbox = gtk_hbox_new(FALSE, 5); + amplitudeSpin = gtk_spin_button_new_with_range(0.1, 10.0, .1); + + gtk_box_pack_start(GTK_BOX(amplitudeHbox), amplitudeLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(amplitudeHbox), amplitudeSpin, FALSE, FALSE, 2); + + frequencyLbl = gtk_label_new("\tFrequency:"); + frequencyHbox = gtk_hbox_new(FALSE, 5); + frequencySpin = gtk_spin_button_new_with_range(-10.0, 10.0, .1); + freqNoteLbl = gtk_label_new("(Negative frequency reverses\ndirection. Zero freezes.)"); + + gtk_box_pack_start(GTK_BOX(frequencyHbox), frequencyLbl, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(frequencyHbox), frequencySpin, FALSE, FALSE, 2); + + g_signal_connect(wavelengthSpin, "value-changed", G_CALLBACK(setWavelength), NULL); + g_signal_connect(amplitudeSpin, "value-changed", G_CALLBACK(setAmplitude), NULL); + g_signal_connect(frequencySpin, "value-changed", G_CALLBACK(setFrequency), NULL); + + // sync with config + g_config->getOption("SDL.VoxelWavelength", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(wavelengthSpin), f); + g_config->getOption("SDL.VoxelWaveAmplitude", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(amplitudeSpin), f); + g_config->getOption("SDL.VoxelWaveFrequency", &f); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(frequencySpin), f); + + gtk_box_pack_start(GTK_BOX(vbox), disclaimer, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), scaleLbl, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), scaleHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), depthHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), transHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), spaceLbl, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), spaceHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), systemBGC, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), prevalentBGC, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), coordBGC, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), coordHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), waveHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), wavelengthHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), amplitudeHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), frequencyHbox, FALSE, FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), freqNoteLbl, FALSE, FALSE, 5); + + g_signal_connect(win, "delete-event", G_CALLBACK(closeVideoWin), NULL); + g_signal_connect(win, "response", G_CALLBACK(closeVideoWin), NULL); + + gtk_widget_show_all(win); + + return; +} +#endif + const char* mixerStrings[6] = {"Volume", "Triangle", "Square1", "Square2", "Noise", "PCM"}; int mixerChanged(GtkWidget* w, gpointer p) @@ -2134,7 +2529,7 @@ gint convertKeypress(GtkWidget *grab, GdkEventKey *event, gpointer user_data) sdlev.key.state = SDL_RELEASED; keystate = 0; break; - + default: fprintf(stderr, "Unhandled GDK event type: %d", event->type); return FALSE; @@ -2212,6 +2607,9 @@ static char* menuXml = " " " " " " +#ifdef OPENGL + " " +#endif " " " " " " @@ -2272,6 +2670,9 @@ static GtkActionEntry normal_entries[] = { {"VideoConfigAction", "video-display", "_Video Config", NULL, NULL, G_CALLBACK(openVideoConfig)}, {"PaletteConfigAction", GTK_STOCK_SELECT_COLOR, "_Palette Config", NULL, NULL, G_CALLBACK(openPaletteConfig)}, {"NetworkConfigAction", GTK_STOCK_NETWORK, "_Network Config", NULL, NULL, G_CALLBACK(openNetworkConfig)}, +#ifdef OPENGL + {"VoxelConfigAction", "voxels", "_Voxel Config", NULL, NULL, G_CALLBACK(openVoxelConfig)}, +#endif {"FullscreenAction", GTK_STOCK_FULLSCREEN, "_Fullscreen", "Return", NULL, G_CALLBACK(enableFullscreen)}, {"EmulationMenuAction", NULL, "_Emulation"}, {"PowerAction", NULL, "P_ower", NULL, NULL, G_CALLBACK(FCEUI_PowerNES)}, @@ -2389,7 +2790,7 @@ gint handleMouseClick(GtkWidget* widget, GdkEvent *event, gpointer callback_data if(button == 3) GtkMouseData[2] |= 0x3; } - + // this doesn't work because we poll the mouse position rather // than use events /* @@ -2409,6 +2810,36 @@ gint handleMouseClick(GtkWidget* widget, GdkEvent *event, gpointer callback_data return 0; } + +gint handleMouseMove(GtkWidget* widget, GdkEvent *event, gpointer callback_data) +{ + GtkMouseData[0] = ((GdkEventMotion*)event)->x; + GtkMouseData[1] = ((GdkEventMotion*)event)->y; + + return 0; +} + +extern float cameraZ; +gint handleMouseScroll(GtkWidget* widget, GdkEvent *event, gpointer callback_data) +{ + switch (((GdkEventScroll *)event)->direction) + { + case GDK_SCROLL_UP: + cameraZ -= 10.0f; + if (cameraZ < 100.0f) + cameraZ = 100.0f; + break; + + case GDK_SCROLL_DOWN: + cameraZ += 10.0f; + if (cameraZ > 800.0f) + cameraZ = 800.0f; + break; + } + + return 0; +} + // NES resolution = 256x240 const int NES_WIDTH=256; const int NES_HEIGHT=240; @@ -2495,6 +2926,10 @@ int InitGTKSubsystem(int argc, char** argv) // prg - Bryan Cain, you are the man! evbox = gtk_event_box_new(); + + // Absolutely necessary in order to poll data from mouse continuously: + gtk_widget_set_events(evbox, GDK_POINTER_MOTION_MASK); + gtk_box_pack_start (GTK_BOX(vbox), evbox, TRUE, TRUE, 0); double xscale, yscale; @@ -2513,9 +2948,12 @@ int InitGTKSubsystem(int argc, char** argv) gtk_key_snooper_install(convertKeypress, NULL); // pass along mouse data from GTK to SDL - g_signal_connect(G_OBJECT(evbox), "button-press-event", G_CALLBACK(handleMouseClick), NULL); - g_signal_connect(G_OBJECT(evbox), "button-release-event", G_CALLBACK(handleMouseClick), NULL); + g_signal_connect(G_OBJECT(evbox), "button-press-event", G_CALLBACK(handleMouseClick), NULL); + g_signal_connect(G_OBJECT(evbox), "button-release-event", G_CALLBACK(handleMouseClick), NULL); + // Collect mouse motion and wheel scrolls for voxel camera. + g_signal_connect(G_OBJECT(evbox), "motion-notify-event", G_CALLBACK(handleMouseMove), NULL); + g_signal_connect(G_OBJECT(evbox), "scroll-event", G_CALLBACK(handleMouseScroll), NULL); // signal handlers g_signal_connect(MainWindow, "delete-event", quit, NULL); diff --git a/branches/voxel/src/drivers/sdl/input.cpp b/branches/voxel/src/drivers/sdl/input.cpp index c371b2fe..f518105b 100644 --- a/branches/voxel/src/drivers/sdl/input.cpp +++ b/branches/voxel/src/drivers/sdl/input.cpp @@ -915,6 +915,7 @@ GetMouseData (uint32 (&d)[3]) { d[2] |= 0x2; } + // get the mouse position from the SDL video driver t = PtoV (x, y); @@ -922,8 +923,13 @@ GetMouseData (uint32 (&d)[3]) d[1] = (t >> 16) & 0xFFFF; // debug print // printf("mouse %d %d %d\n", d[0], d[1], d[2]); + + // Set these for the voxel camera. + GtkMouseData[0] = x; + GtkMouseData[1] = y; } +extern float cameraZ; /** * Handles outstanding SDL events. */ @@ -951,6 +957,21 @@ UpdatePhysicalInput () FCEU_printf ("Warning: unknown hotkey event %d\n", event.user.code); } + case SDL_MOUSEBUTTONDOWN: + // Capture mouse scroll wheel for the voxel camera. + switch(event.button.button) + { + case SDL_BUTTON_WHEELUP: + cameraZ -= 10.0f; + if (cameraZ < 100.0f) + cameraZ = 100.0f; + break; + case SDL_BUTTON_WHEELDOWN: + cameraZ += 10.0f; + if (cameraZ > 800.0f) + cameraZ = 800.0f; + break; + } default: break; } diff --git a/branches/voxel/src/drivers/sdl/sdl-opengl.cpp b/branches/voxel/src/drivers/sdl/sdl-opengl.cpp index ce8562fc..21b05df0 100644 --- a/branches/voxel/src/drivers/sdl/sdl-opengl.cpp +++ b/branches/voxel/src/drivers/sdl/sdl-opengl.cpp @@ -25,7 +25,7 @@ static GLuint textures[2]={0,0}; // Normal image, scanline overlay. static int left,right,top,bottom; // right and bottom are not inclusive. static int scanlines; -static void *HiBuffer; +void *HiBuffer; typedef void APIENTRY (*glColorTableEXT_Func)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, diff --git a/branches/voxel/src/drivers/sdl/sdl-video.cpp b/branches/voxel/src/drivers/sdl/sdl-video.cpp index 88aacd3f..265e32d1 100644 --- a/branches/voxel/src/drivers/sdl/sdl-video.cpp +++ b/branches/voxel/src/drivers/sdl/sdl-video.cpp @@ -23,6 +23,7 @@ #include "sdl.h" #include "sdl-opengl.h" +#include "sdl-voxel.h" #include "../common/vidblit.h" #include "../../fceu.h" #include "../../version.h" @@ -65,6 +66,7 @@ static int s_inited; #ifdef OPENGL static int s_useOpenGL; +static int s_voxelEngine; #endif static double s_exs, s_eys; static int s_eefx; @@ -175,6 +177,7 @@ InitVideo(FCEUGI *gi) g_config->getOption("SDL.DoubleBuffering", &doublebuf); #ifdef OPENGL g_config->getOption("SDL.OpenGL", &s_useOpenGL); + g_config->getOption("SDL.VoxelEngine", &s_voxelEngine); #endif g_config->getOption("SDL.SpecialFilter", &s_sponge); g_config->getOption("SDL.XStretch", &xstretch); @@ -486,10 +489,16 @@ InitVideo(FCEUGI *gi) #ifdef OPENGL if(s_useOpenGL) { - int openGLip; + int openGLip, voxelEngine; g_config->getOption("SDL.OpenGLip", &openGLip); - if(!InitOpenGL(NOFFSET, 256 - (s_clipSides ? 8 : 0), + if(s_voxelEngine) + { + initVoxelGL(NOFFSET, 256 - (s_clipSides ? 8 : 0), + s_srendline, s_erendline + 1, + s_screen, s_eefx); + } + else if(!InitOpenGL(NOFFSET, 256 - (s_clipSides ? 8 : 0), s_srendline, s_erendline + 1, s_exs, s_eys, s_eefx, openGLip, xstretch, ystretch, s_screen)) @@ -629,7 +638,14 @@ BlitScreen(uint8 *XBuf) #ifdef OPENGL // OpenGL is handled separately if(s_useOpenGL) { - BlitOpenGL(XBuf); + if (s_voxelEngine) + { + drawVoxelScene(XBuf); + } + else + { + BlitOpenGL(XBuf); + } return; } #endif diff --git a/branches/voxel/src/drivers/sdl/sdl-voxel.cpp b/branches/voxel/src/drivers/sdl/sdl-voxel.cpp new file mode 100644 index 00000000..80f20519 --- /dev/null +++ b/branches/voxel/src/drivers/sdl/sdl-voxel.cpp @@ -0,0 +1,460 @@ +/********************************************************** + * *** Emulation Voxel Engine *** * + * Original concept and implementation by * + * Scott Jacobi, 2013 * + * * + * The purpose of this code is to take the video output * + * buffer of an emulator, and render it in 3D using * + * voxels. To provide a greater sense of depth, one * + * color is designated as the background color. That * + * color is used to fill the screen each frame, and any * + * pixels in the buffer that match that color are * + * ignored. * + * * + * Various methods may be used to determine what the * + * background color should be. One way is to ask the * + * emulated system for its notion of a background clear * + * color, if the system supports that. Another method is * + * to poll the color of a particular coordinate on the * + * screen. * + * * + * Additional features have been implemented, including * + * the ability to render the resulting three-dimensional * + * image with ripples or waves. Various aspects of the * + * waves are under the control of the user, including the * + * direction, wavelength, amplitude, and frequency. * + * Another feature is the ability to size and space the * + * voxels according to the users wishes. * + * * + * Control over the camera is provided through the * + * manipulation of the mouse. The camera can be moved to * + * various locations in order to customize the angle and * + * perspective from which the player views the screen. * + * The mouse wheel may be used to zoom in and out from * + * the scene. * + * * + * This code is freely distributable, and may be used for * + * any non-commercial purpose. Please do not incorporate * + * this code into any product that is intended for sale * + * or profit. Collaborations to improve upon this code * + * are highly encouraged. Please share your knowledge * + * and improvements with the emulation community. * + **********************************************************/ + +#define GL_GLEXT_LEGACY + +#include "sdl.h" +#include "sdl-opengl.h" +#include "gui.h" +#include "math.h" +#include "../common/vidblit.h" +#include "../../utils/memory.h" + +#ifdef APPLEOPENGL +#include +#include +#include +#else +#include +#include +#include + +#endif +#include +#include + +#ifndef APIENTRY +#define APIENTRY +#endif + +/* Ambient Light Values ( NEW ) */ +GLfloat lmodel_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; +/* Diffuse Light Values ( NEW ) */ +GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; +/* Light Position ( NEW ) */ +GLfloat LightPosition[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + +float wave[] = {0.0f, 3.0f, 6.0f, 8.0f, 9.0f, 9.5f, 10.0f, 9.5f, 9.0f, 8.0f, 6.0f, 3.0f, + 0.0f, -3.0f, -6.0f, -8.0f, -9.0f, -9.5f, -10.0f, -9.5f, -9.0f, -8.0f, -6.0f, -3.0f }; + +static int left,right,top,bottom; // right and bottom are not inclusive. + +GLfloat vWidth = 0.5f; +GLfloat vHeight = 0.5f; +GLfloat vDepth = 0.5f; +GLfloat clearColor[4]; + +// Settings +double xScale, yScale, zScale, transparency, xSpace, ySpace; +int bgcMethod, sampleXcoord, sampleYcoord; +double waveLength, waveAmp, waveFreq; +int halfWidth, halfHeight; +float cameraZ; + +extern void *HiBuffer; +extern Config *g_config; +extern uint8 PALRAM[0x20]; + +enum waveTypes +{ + wtDisabled = 0, + wtHorizontal, + wtVertical, + wtDiagonal1, + wtDiagonal2 +}; + +waveTypes waves; + +GLuint voxel; // Storage For The Display List + +GLvoid voxelList() +{ + GLfloat voxW = vWidth * (float)xScale; + GLfloat voxH = vHeight * (float)yScale; + GLfloat voxD = vDepth * (float)zScale; + + voxel=glGenLists(1); + glNewList(voxel, GL_COMPILE); + glBegin(GL_QUADS); // Start Drawing Quads + // Bottom Face + glNormal3f( 0.0f, -1.0f, 0.0f); + glVertex3f(-voxW, -voxH, -voxD); // Top Right Of The Quad + glVertex3f( voxW, -voxH, -voxD); // Top Left Of The Quad + glVertex3f( voxW, -voxH, voxD); // Bottom Left Of The Quad + glVertex3f(-voxW, -voxH, voxD); // Bottom Right Of The Quad + // Front Face + glNormal3f( 0.0f, 0.0f, 1.0f); + glVertex3f(-voxW, -voxH, voxD); // Bottom Left Of The Quad + glVertex3f( voxW, -voxH, voxD); // Bottom Right Of The Quad + glVertex3f( voxW, voxH, voxD); // Top Right Of The Quad + glVertex3f(-voxW, voxH, voxD); // Top Left Of The Quad + // Back Face +// glNormal3f( 0.0f, 0.0f, -1.0f); +// glVertex3f(-voxW, -voxH, -voxD); // Bottom Right Of and Quad +// glVertex3f(-voxW, voxH, -voxD); // Top Right Of The Quad +// glVertex3f( voxW, voxH, -voxD); // Top Left Of The Quad +// glVertex3f( voxW, -voxH, -voxD); // Bottom Left Of The Quad + // Right face + glNormal3f( 1.0f, 0.0f, 0.0f); + glVertex3f( voxW, -voxH, -voxD); // Bottom Right Of The Quad + glVertex3f( voxW, voxH, -voxD); // Top Right Of The Quad + glVertex3f( voxW, voxH, voxD); // Top Left Of The Quad + glVertex3f( voxW, -voxH, voxD); // Bottom Left Of The Quad + // Left Face + glNormal3f(-1.0f, 0.0f, 0.0f); + glVertex3f(-voxW, -voxH, -voxD); // Bottom Left Of The Quad + glVertex3f(-voxW, -voxH, voxD); // Bottom Right Of The Quad + glVertex3f(-voxW, voxH, voxD); // Top Right Of The Quad + glVertex3f(-voxW, voxH, -voxD); // Top Left Of The Quad + // Top Face + glNormal3f( 0.0f, 1.0f, 0.0f); + glVertex3f(-voxW, voxH, -voxD); // Top Left Of The Quad + glVertex3f(-voxW, voxH, voxD); // Bottom Left Of The Quad + glVertex3f( voxW, voxH, voxD); // Bottom Right Of The Quad + glVertex3f( voxW, voxH, -voxD); // Top Right Of The Quad + glEnd(); // Done Drawing Quads + glEndList( ); +} + +int initVoxelGL(int l, + int r, + int t, + int b, + SDL_Surface *screen, + int efx) +{ + left=l; + right=r; + top=t; + bottom=b; + + HiBuffer=FCEU_malloc(4*256*256); + memset(HiBuffer,0x00,4*256*256); + #ifndef LSB_FIRST + InitBlitToHigh(4,0xFF000000,0xFF0000,0xFF00,efx&2,0,0); + #else + InitBlitToHigh(4,0xFF,0xFF00,0xFF0000,efx&2,0,0); + #endif + + g_config->getOption("SDL.VoxelXScale", &xScale); + g_config->getOption("SDL.VoxelYScale", &yScale); + g_config->getOption("SDL.VoxelZScale", &zScale); + g_config->getOption("SDL.VoxelTransparency", &transparency); + g_config->getOption("SDL.VoxelXSpace", &xSpace); + g_config->getOption("SDL.VoxelYSpace", &ySpace); + g_config->getOption("SDL.VoxelBGCMethod", &bgcMethod); + g_config->getOption("SDL.VoxelXCoordBGC", &sampleXcoord); + g_config->getOption("SDL.VoxelYCoordBGC", &sampleYcoord); + int waveType; + g_config->getOption("SDL.VoxelWaves", &waveType); + waves = (waveTypes)waveType; + g_config->getOption("SDL.VoxelWavelength", &waveLength); + g_config->getOption("SDL.VoxelWaveAmplitude", &waveAmp); + g_config->getOption("SDL.VoxelWaveFrequency", &waveFreq); + + cameraZ = 360.0f; + + /* Build our display lists */ + voxelList(); + + /* Enable Texture Mapping ( NEW ) */ + glEnable( GL_TEXTURE_2D ); + + /* Enable smooth shading */ + glShadeModel( GL_SMOOTH ); + + /* Set the background black */ + glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); + + /* Depth buffer setup */ + glClearDepth( 1.0f ); + + /* Enables Depth Testing */ + glEnable( GL_DEPTH_TEST ); + + /* The Type Of Depth Test To Do */ + glDepthFunc( GL_LEQUAL ); + + /* Alpha blending for transparency */ + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + /* Really Nice Perspective Calculations */ + glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); + + /* Material settings */ + GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat mat_shininess[] = { 50.0 }; + + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); + + /* Setup The Ambient Light */ + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); + + /* Setup The Diffuse Light */ + glLightfv( GL_LIGHT1, GL_DIFFUSE, LightDiffuse ); + + /* Position The Light */ + glLightfv( GL_LIGHT1, GL_POSITION, LightPosition ); + + /* Enable Light One */ + glEnable( GL_LIGHTING ); /* Enable Lighting */ + glEnable( GL_LIGHT1 ); + glEnable( GL_COLOR_MATERIAL ); /* Enable Material Coloring */ + + /* Height / width ration */ + GLfloat ratio; + int width = screen->w; + int height = screen->h; + halfWidth = width/2; + halfHeight = height/2; + + ratio = ( GLfloat )width / ( GLfloat )height; + + /* Setup our viewport. */ + glViewport( 0, 0, ( GLint )width, ( GLint )height ); + + /* change to the projection matrix and set our viewing volume. */ + glMatrixMode( GL_PROJECTION ); + glLoadIdentity( ); + + /* Set our perspective */ + gluPerspective( 45.0f, ratio, 0.1f, 1000.0f ); + + /* Make sure we're chaning the model view and not the projection */ + glMatrixMode( GL_MODELVIEW ); + + /* Reset The View */ + glLoadIdentity( ); + + return 1; +} + +uint16 arrayColors[256], maxColorCount; +uint8 maxColorIx; + +/* Here goes our drawing code */ +void drawVoxelScene(uint8 *Xbuf) +{ + int paletteIx; + + Blit8ToHigh(Xbuf, (uint8*)HiBuffer, 256, 240, 256*4, 1, 1); + + if (bgcMethod == 1) // Color prominence + { + maxColorIx = 0; + maxColorCount = arrayColors[0]; + for (paletteIx = 1; paletteIx < 256; paletteIx++) + { + if (arrayColors[paletteIx] > maxColorCount) + { + maxColorIx = paletteIx; + maxColorCount = arrayColors[paletteIx]; + } + } + + memset (arrayColors, 0, 256*sizeof(short)); + } + + /* These are to calculate our fps */ + static GLint T0 = 0; + static GLint Frames = 0; + static GLint totalFrames = 0; + + GLfloat Depth = cameraZ; + GLfloat Zoom = cameraZ/4.0f; + GLfloat voxelDepth; + + int length, freq, waveState; + + /* Select Our Texture */ +// glBindTexture( GL_TEXTURE_2D, texture[0] ); + + uint8* buf = (uint8*)HiBuffer; + GLfloat pixcol[4]; + + uint8 r, g, b; + switch (bgcMethod) + { + case 0: // Get the clear color from the system pallet. + FCEUD_GetPalette(0x80 | PALRAM[0], &r, &g, &b); + + pixcol[0] = (GLfloat)r / 256.0f; + pixcol[1] = (GLfloat)g / 256.0f; + pixcol[2] = (GLfloat)b / 256.0f; + break; + + case 1: // Get the clear color from the previous frame's color count + FCEUD_GetPalette(maxColorIx, &r, &g, &b); + + pixcol[0] = (GLfloat)r / 256.0f; + pixcol[1] = (GLfloat)g / 256.0f; + pixcol[2] = (GLfloat)b / 256.0f; + break; + + case 2: // Get the clear color from the sample coordinate. + pixcol[0] = (GLfloat)(buf[sampleYcoord*256*4 + sampleXcoord*4 ]) / 256.0f; + pixcol[1] = (GLfloat)(buf[sampleYcoord*256*4 + sampleXcoord*4 + 1]) / 256.0f; + pixcol[2] = (GLfloat)(buf[sampleYcoord*256*4 + sampleXcoord*4 + 2]) / 256.0f; + } + + // Voxel transparency + pixcol[3] = transparency; + + // Check if the clear color has changed since the previous frame. + if (!(clearColor[0] == pixcol[0] && + clearColor[1] == pixcol[1] && + clearColor[2] == pixcol[2] )) + { + clearColor[0] = pixcol[0]; + clearColor[1] = pixcol[1]; + clearColor[2] = pixcol[2]; + glClearColor(clearColor[0], clearColor[1], clearColor[2], 0.0f); + } + + /* Clear The Screen And The Depth Buffer */ + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + GLfloat cameraPos[3]; + + cameraPos[0] = (float)(-halfWidth + GtkMouseData[0]); + cameraPos[1] = (float)(halfHeight - GtkMouseData[1]); + cameraPos[2] = Depth - + ((fabs(cameraPos[0])/(float)halfWidth) * Zoom) - + ((fabs(cameraPos[1])/(float)halfHeight) * Zoom); + + /* Reset the view */ + glLoadIdentity( ); + gluLookAt(cameraPos[0], cameraPos[1], cameraPos[2], + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0); + + GLint xloop; /* Loop For X Axis */ + GLint yloop; /* Loop For Y Axis */ + + // Calculate the positional space that each voxel needs to be relative to one another. + float xPos = (float)xScale + (float)xSpace; + float yPos = (float)yScale + (float)ySpace; + + for ( yloop = top; yloop < bottom; yloop++ ) + { + for ( xloop = left; xloop < right; xloop++ ) + { + if (bgcMethod == 1) + arrayColors[Xbuf[yloop*256 + xloop]]++; + + pixcol[0] = (GLfloat)(buf[yloop*256*4 + xloop*4] ) / 256.0f; + pixcol[1] = (GLfloat)(buf[yloop*256*4 + xloop*4 + 1]) / 256.0f; + pixcol[2] = (GLfloat)(buf[yloop*256*4 + xloop*4 + 2]) / 256.0f; + + if (!(pixcol[0] == clearColor[0] && pixcol[1] == clearColor[1] && pixcol[2] == clearColor[2])) + { + // Determine the length of the waves across the buffer. + switch (waves) + { + case wtHorizontal: + length = (int)((float)xloop / waveLength); + break; + case wtVertical: + length = (int)((float)yloop / waveLength); + break; + case wtDiagonal1: + length = (int)((float)(yloop - xloop) / waveLength); + break; + case wtDiagonal2: + length = (int)((float)(yloop + xloop) / waveLength); + break; + } + + if (waves) + { + // Frequency of waves is driven by the number of frames. + freq = (int)((float)totalFrames * waveFreq); + waveState = (length + freq) % 24; + if (waveState < 0) + waveState += 24; + // Amplitude is determined by multiplying the result. + voxelDepth = wave[waveState] * waveAmp; + } + else + { + voxelDepth = 0; + } + + glPushMatrix(); + + /* Position The Cubes On The Screen */ + glTranslatef( (-128.0 + ( float )xloop) * xPos, + (128.0 - ( float )yloop) * yPos, + voxelDepth ); + + glColor4fv( pixcol ); /* Select A Box Color */ + glCallList( voxel ); /* Draw the box */ + + glPopMatrix(); + } + } + } + + /* Draw it to the screen */ + SDL_GL_SwapBuffers( ); + + /* Gather our frames per second */ + Frames++; + { + GLint t = SDL_GetTicks(); + if (t - T0 >= 5000) + { + GLfloat seconds = (t - T0) / 1000.0; + GLfloat fps = Frames / seconds; + printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps); + T0 = t; + Frames = 0; + } + } + totalFrames++; +} + + diff --git a/branches/voxel/src/drivers/sdl/sdl-voxel.h b/branches/voxel/src/drivers/sdl/sdl-voxel.h new file mode 100644 index 00000000..42839786 --- /dev/null +++ b/branches/voxel/src/drivers/sdl/sdl-voxel.h @@ -0,0 +1,9 @@ +int initVoxelGL(int l, + int r, + int t, + int b, + SDL_Surface *screen, + int efx); +void drawVoxelScene(uint8 *Xbuf); + + diff --git a/branches/voxel/src/input/zapper.cpp b/branches/voxel/src/input/zapper.cpp index 6635b0f8..0c3f05f7 100644 --- a/branches/voxel/src/input/zapper.cpp +++ b/branches/voxel/src/input/zapper.cpp @@ -169,25 +169,26 @@ static void UpdateZapper(int w, void *data, int arg) { uint32 *ptr=(uint32 *)data; - bool newclicked = (ptr[2]&3)!=0; - bool oldclicked = (ZD[w].lastInput)!=0; + bool newclicked = (ptr[2]&3)!=0; + bool oldclicked = (ZD[w].lastInput)!=0; if(ZD[w].bogo) - { + { ZD[w].bogo--; - } + } - ZD[w].lastInput = ptr[2]&3; + ZD[w].lastInput = ptr[2]&3; - //woah.. this looks like broken bit logic. + //woah.. this looks like broken bit logic. if(newclicked && !oldclicked) - { + { ZD[w].bogo=5; - ZD[w].mzb=ptr[2]; - ZD[w].mzx=ptr[0]; - ZD[w].mzy=ptr[1]; - } + ZD[w].mzb=ptr[2]; + } + // Keep this outside of the above if block to keep the crosshairs updated + ZD[w].mzx=ptr[0]; + ZD[w].mzy=ptr[1]; } static void LogZapper(int w, MovieRecord* mr)