diff src/rovascope/paranormal.c @ 408:290588854a9d trunk

[svn] - rovascope -- a variant of the paranormal visualization engine that is uses random data instead of presets.
author nenolod
date Sat, 06 Jan 2007 01:57:34 -0800
parents src/paranormal/paranormal.c@b185ed2f8fa2
children f305ebcc8136
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/rovascope/paranormal.c	Sat Jan 06 01:57:34 2007 -0800
@@ -0,0 +1,234 @@
+/* FIXME: add fullscreen / screenshots */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <SDL.h>
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include "paranormal.h"
+#include "actuators.h"
+
+/* SDL stuffs */
+SDL_Surface *screen;
+
+/* Globals */
+struct pn_rc         *pn_rc;
+struct pn_image_data *pn_image_data;
+struct pn_sound_data *pn_sound_data;
+
+/* Trig Pre-Computes */
+float sin_val[360];
+float cos_val[360];
+
+gboolean pn_new_beat;
+
+extern SDL_mutex *config_mutex;
+
+/* **************** drawing doodads **************** */
+
+static void
+blit_to_screen (void)
+{
+  int j;
+
+  SDL_LockSurface (screen);
+
+  /* FIXME: add scaling support */
+
+  SDL_SetPalette (screen, SDL_LOGPAL|SDL_PHYSPAL,
+		  (SDL_Color*)pn_image_data->cmap, 0, 256);
+  SDL_SetAlpha (screen, 0, 255);
+
+  for (j=0; j<pn_image_data->height; j++)
+      memcpy (screen->pixels + j*screen->pitch,
+	      pn_image_data->surface[0] + j*pn_image_data->width,
+	      pn_image_data->width);
+
+
+  SDL_UnlockSurface (screen);
+
+  SDL_UpdateRect (screen, 0, 0, 0, 0);
+}
+
+static void
+resize_video (guint w, guint h)
+{
+  pn_image_data->width = w;
+  pn_image_data->height = h;
+
+  if (pn_image_data->surface[0])
+    g_free (pn_image_data->surface[0]);
+  if (pn_image_data->surface[1])
+    g_free (pn_image_data->surface[1]);
+
+  pn_image_data->surface[0] = g_malloc0 (w * h);
+  pn_image_data->surface[1] = g_malloc0 (w * h);
+
+  screen = SDL_SetVideoMode (w, h, 8, SDL_HWSURFACE |
+			     SDL_HWPALETTE | SDL_RESIZABLE);
+  if (! screen)
+    pn_fatal_error ("Unable to create a new SDL window: %s",
+		    SDL_GetError ());
+}
+
+static void
+take_screenshot (void)
+{
+  char fname[32];
+  struct stat buf;
+  int i=0;
+
+  do
+    sprintf (fname, "pn_%05d.bmp", ++i);
+  while (stat (fname, &buf) == 0);
+
+  SDL_SaveBMP (screen, fname);
+}
+
+/* FIXME: This should resize the video to a user-set
+   fullscreen res */
+static void
+toggle_fullscreen (void)
+{
+  SDL_WM_ToggleFullScreen (screen);  
+  if (SDL_ShowCursor (SDL_QUERY) == SDL_ENABLE)
+    SDL_ShowCursor (SDL_DISABLE);
+  else
+    SDL_ShowCursor (SDL_ENABLE);
+}
+
+/* **************** basic renderer management **************** */
+void
+pn_init (void)
+{
+  int i;
+#ifdef FULLSCREEN_HACK
+  char SDL_windowhack[32];
+  GdkScreen *screen;
+#endif
+
+  pn_sound_data = g_new0 (struct pn_sound_data, 1);
+  pn_image_data = g_new0 (struct pn_image_data, 1);
+
+#ifdef FULLSCREEN_HACK
+  screen = gdk_screen_get_default();
+  sprintf(SDL_windowhack,"SDL_WINDOWID=%d",
+          GDK_WINDOW_XWINDOW(gdk_screen_get_root_window(screen)));
+          putenv(SDL_windowhack);
+#endif
+
+  if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_NOPARACHUTE) < 0)
+    pn_fatal_error ("Unable to initialize SDL: %s", SDL_GetError ());
+
+#ifndef FULLSCREEN_HACK
+  resize_video (640, 360);
+#else
+  resize_video (1280, 1024);
+#endif
+
+  SDL_WM_SetCaption ("Rovascope " VERSION, PACKAGE);
+
+  for(i=0; i<360; i++)
+    {
+      sin_val[i] = sin(i*(M_PI/180.0));
+      cos_val[i] = cos(i*(M_PI/180.0));
+    }
+}
+
+void
+pn_cleanup (void)
+{
+  SDL_FreeSurface (screen);
+  SDL_Quit ();
+
+
+  if (pn_image_data)
+    {
+      if (pn_image_data->surface[0])
+	g_free (pn_image_data->surface[0]);
+      if (pn_image_data->surface[1])
+	g_free (pn_image_data->surface[1]);
+      g_free (pn_image_data);
+    }
+  if (pn_sound_data)
+    g_free (pn_sound_data);
+}
+
+/* Renders one frame and handles the SDL window */
+void
+pn_render (void)
+{
+  SDL_Event event;
+
+  /* Handle window events */
+  while (SDL_PollEvent (&event))
+    {
+      switch (event.type)
+	{
+	case SDL_QUIT:
+	  pn_quit ();
+	  g_assert_not_reached ();
+	case SDL_KEYDOWN:
+	  switch (event.key.keysym.sym)
+	    {
+	    case SDLK_ESCAPE:
+	      pn_quit ();
+	      g_assert_not_reached ();
+	    case SDLK_RETURN:
+	      if (event.key.keysym.mod & (KMOD_ALT | KMOD_META))
+		toggle_fullscreen ();
+	      break;
+	    case SDLK_BACKQUOTE:
+	      take_screenshot ();
+	      break;
+	    default:
+              break;
+	    }
+	  break;
+	case SDL_VIDEORESIZE:
+	  resize_video (event.resize.w, event.resize.h);	  
+	  break;
+	}
+    }
+
+  pn_new_beat = pn_is_new_beat();
+
+  if (pn_rc->actuator)
+    {
+      exec_actuator (pn_rc->actuator);
+      blit_to_screen ();
+    }
+
+  if (pn_new_beat && (rand() % 4 == 0))
+    {
+      struct pn_actuator *a;
+      GSList *list = *(GSList **)pn_rc->actuator->data;
+
+      container_remove_actuator (pn_rc->actuator, list->data);
+
+      SDL_mutexP(config_mutex);
+      a = rovascope_get_random_actuator();
+      container_add_actuator (pn_rc->actuator, a);
+      SDL_mutexV(config_mutex);
+    }
+}
+
+/* this MUST be called if a builtin's output is to surface[1]
+   (by the builtin, after it is done) */
+void
+pn_swap_surfaces (void)
+{
+  guchar *tmp = pn_image_data->surface[0];
+  pn_image_data->surface[0] = pn_image_data->surface[1];
+  pn_image_data->surface[1] = tmp;
+}