svn commit: r245235 - user/adrian/ath_radar_stuff/src/spectral_fft
Adrian Chadd
adrian at FreeBSD.org
Wed Jan 9 20:01:10 UTC 2013
Author: adrian
Date: Wed Jan 9 20:01:08 2013
New Revision: 245235
URL: http://svnweb.freebsd.org/changeset/base/245235
Log:
Break out the display specific code into a separate file and begin the
process of turning it into a (kind of) stand-alone class.
Added:
user/adrian/ath_radar_stuff/src/spectral_fft/fft_display.c
- copied, changed from r245197, user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c
user/adrian/ath_radar_stuff/src/spectral_fft/fft_display.h
Modified:
user/adrian/ath_radar_stuff/src/spectral_fft/Makefile
user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c
Modified: user/adrian/ath_radar_stuff/src/spectral_fft/Makefile
==============================================================================
--- user/adrian/ath_radar_stuff/src/spectral_fft/Makefile Wed Jan 9 19:49:35 2013 (r245234)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/Makefile Wed Jan 9 20:01:08 2013 (r245235)
@@ -1,6 +1,6 @@
PROG= fft_eval
-SRCS= fft_eval.c fft_freebsd.c fft_histogram.c
+SRCS= fft_eval.c fft_freebsd.c fft_histogram.c fft_display.c
CFLAGS+= -I/usr/local/include -L/usr/local/lib -I../../lib/ -L../../lib/libradarpkt -pthread
Copied and modified: user/adrian/ath_radar_stuff/src/spectral_fft/fft_display.c (from r245197, user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c)
==============================================================================
--- user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c Wed Jan 9 00:01:26 2013 (r245197, copy source)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/fft_display.c Wed Jan 9 20:01:08 2013 (r245235)
@@ -26,16 +26,17 @@
#include <errno.h>
#include <stdio.h>
-#include <math.h>
#include <pcap.h>
#include <pthread.h>
#include <unistd.h>
+#include <err.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include "fft_eval.h"
+#if 1
#include "net80211/ieee80211.h"
#include "net80211/ieee80211_radiotap.h"
@@ -43,11 +44,12 @@
#include "libradarpkt/ar5212_radar.h"
#include "libradarpkt/ar5416_radar.h"
#include "libradarpkt/ar9280_radar.h"
+#endif
-#include "fft_eval.h"
-#include "fft_freebsd.h"
#include "fft_histogram.h"
+#include "fft_display.h"
+
#define WIDTH 1600
#define HEIGHT 650
#define BPP 32
@@ -64,62 +66,9 @@
#define AMASK 0xff000000
/* XXX ew globals */
-pthread_mutex_t mtx_histogram;
-int g_do_update = 0;
-
-SDL_Surface *screen = NULL;
-TTF_Font *font = NULL;
-
-int graphics_init_sdl(void)
-{
- SDL_VideoInfo *VideoInfo;
- int SDLFlags;
-
- SDLFlags = SDL_HWPALETTE | SDL_RESIZABLE;
-
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) {
- fprintf(stderr, "Initializing SDL failed\n");
- return -1;
- }
-
- if ((VideoInfo = (SDL_VideoInfo *) SDL_GetVideoInfo()) == NULL) {
- fprintf(stderr, "Getting SDL Video Info failed\n");
- return -1;
- }
-
- else {
- if (VideoInfo->hw_available) {
- SDLFlags |= SDL_HWSURFACE;
- } else {
- SDLFlags |= SDL_SWSURFACE;
- }
- if (VideoInfo->blit_hw)
- SDLFlags |= SDL_HWACCEL;
- }
- SDL_WM_SetCaption("FFT eval", "FFT eval");
- screen = SDL_SetVideoMode(WIDTH, HEIGHT, BPP, SDLFlags);
-
- if (TTF_Init() < 0) {
- fprintf(stderr, "Initializing SDL TTF failed\n");
- return -1;
- }
-
- font = TTF_OpenFont("font/LiberationSans-Regular.ttf", 14);
- if (!font) {
- fprintf(stderr, "Opening font failed\n");
- return -1;
- }
-
- return 0;
-}
-
-void graphics_quit_sdl(void)
-{
- SDL_Quit();
-}
-
-int pixel(Uint32 *pixels, int x, int y, Uint32 color)
+static int
+pixel(Uint32 *pixels, int x, int y, Uint32 color)
{
if (x < 0 || x >= WIDTH)
return -1;
@@ -145,7 +94,8 @@ is_in_viewport(int x, int y)
/* this function blends a 2*SIZE x 2*SIZE blob at the given position with
* the defined opacity. */
-int bigpixel(Uint32 *pixels, int x, int y, Uint32 color, uint8_t opacity)
+static int
+bigpixel(Uint32 *pixels, int x, int y, Uint32 color, uint8_t opacity)
{
int x1, y1;
@@ -174,7 +124,12 @@ int bigpixel(Uint32 *pixels, int x, int
return 0;
}
-int bighotpixel(Uint32 *pixels, int x, int y, Uint32 color, uint8_t opacity)
+/*
+ * Like bigpixel, but blending blue (the "data average" colour) to
+ * green if the blue is saturated. A total hack, but a pretty one.
+ */
+static int
+bighotpixel(Uint32 *pixels, int x, int y, Uint32 color, uint8_t opacity)
{
int x1, y1;
@@ -212,7 +167,9 @@ int bighotpixel(Uint32 *pixels, int x, i
return 0;
}
-int render_text(SDL_Surface *surface, char *text, int x, int y)
+static int
+render_text(struct fft_display *fdisp, SDL_Surface *surface,
+ char *text, int x, int y)
{
SDL_Surface *text_surface;
SDL_Color fontcolor = {255, 255, 255, 255};
@@ -221,7 +178,7 @@ int render_text(SDL_Surface *surface, ch
fontdest.x = x;
fontdest.y = y;
- text_surface = TTF_RenderText_Solid(font, text, fontcolor);
+ text_surface = TTF_RenderText_Solid(fdisp->font, text, fontcolor);
if (!text_surface)
return -1;
@@ -231,6 +188,28 @@ int render_text(SDL_Surface *surface, ch
return 0;
}
+struct fft_display *
+fft_display_create(SDL_Surface *screen, TTF_Font *font)
+{
+ struct fft_display *fdisp;
+
+ fdisp = calloc(1, sizeof(*fdisp));
+ if (fdisp == NULL) {
+ warn("%s: malloc", __func__);
+ return (NULL);
+ }
+ fdisp->screen = screen;
+ fdisp->font = font;
+ return (fdisp);
+}
+
+void
+fft_display_destroy(struct fft_display *fdisp)
+{
+
+ free(fdisp);
+}
+
/*
* draw_picture - draws the current screen.
*
@@ -238,7 +217,9 @@ int render_text(SDL_Surface *surface, ch
*
* returns the center frequency of the currently highlighted dataset
*/
-int draw_picture(int highlight, int startfreq)
+int
+fft_display_draw_picture(struct fft_display *fdisp, int highlight,
+ int startfreq)
{
Uint32 *pixels, color, opacity;
int x, y, i, rnum, j;
@@ -264,7 +245,7 @@ int draw_picture(int highlight, int star
pixels[x + y * WIDTH] = 0x40404040 | AMASK;
snprintf(text, sizeof(text), "%d MHz", i);
- render_text(surface, text, x - 30, HEIGHT - 20);
+ render_text(fdisp, surface, text, x - 30, HEIGHT - 20);
}
/* horizontal lines (dBm) */
@@ -275,7 +256,7 @@ int draw_picture(int highlight, int star
pixels[x + y * WIDTH] = 0x40404040 | AMASK;
snprintf(text, sizeof(text), "-%d dBm", (150 - i));
- render_text(surface, text, 5, y - 15);
+ render_text(fdisp, surface, text, 5, y - 15);
}
/* Render 2300 -> 6000 in 1MHz increments, but using KHz math */
@@ -317,180 +298,9 @@ int draw_picture(int highlight, int star
continue;
}
- SDL_BlitSurface(surface, NULL, screen, NULL);
+ SDL_BlitSurface(surface, NULL, fdisp->screen, NULL);
SDL_FreeSurface(surface);
- SDL_Flip(screen);
+ SDL_Flip(fdisp->screen);
return highlight_freq;
}
-
-/*
- * graphics_main - sets up the data and holds the mainloop.
- *
- */
-void graphics_main(void)
-{
- SDL_Event event;
- int quit = 0;
- int highlight = 0;
- int change = 1, scroll = 0;
- int startfreq = 2350, accel = 0;
- int highlight_freq = startfreq;
-
- if (graphics_init_sdl() < 0) {
- fprintf(stderr, "Failed to initialize graphics.\n");
- return;
- }
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
- while (!quit) {
- pthread_mutex_lock(&mtx_histogram);
- if (g_do_update == 1) {
- change = 1; /* XXX always render */
- g_do_update = 0;
- }
- pthread_mutex_unlock(&mtx_histogram);
-
- if (change) {
- highlight_freq = draw_picture(highlight, startfreq);
- change = 0;
- }
-
- if (!scroll) {
- /* move to highlighted object */
- if (highlight_freq - 20 < startfreq)
- accel = -10;
- if (highlight_freq > (startfreq + WIDTH/X_SCALE))
- accel = 10;
-
- /* if we are "far off", move a little bit faster */
- if (highlight_freq + 300 < startfreq)
- accel = -100;
-
- if (highlight_freq - 300 > (startfreq + WIDTH/X_SCALE))
- accel = 100;
- }
-
-// if (accel)
- SDL_PollEvent(&event);
-// else
-// SDL_WaitEvent(&event);
-
- switch (event.type) {
- case SDL_QUIT:
- quit = 1;
- break;
- case SDL_KEYDOWN:
- switch (event.key.keysym.sym) {
-#if 0
- case SDLK_LEFT:
- if (highlight > 0) {
- highlight--;
- scroll = 0;
- change = 1;
- }
- break;
- case SDLK_RIGHT:
- if (highlight < scanresults_n - 1){
- highlight++;
- scroll = 0;
- change = 1;
- }
- break;
-#endif
- case SDLK_PAGEUP:
- accel-= 2;
- scroll = 1;
- break;
- case SDLK_PAGEDOWN:
- accel+= 2;
- scroll = 1;
- break;
- case SDLK_HOME:
- startfreq = 2300;
- accel = 0;
- break;
- case SDLK_END:
- startfreq = 5100;
- accel = 0;
- break;
- default:
- break;
- }
- break;
- }
- if (accel) {
- startfreq += accel;
- if (accel > 0) accel--;
- if (accel < 0) accel++;
- change = 1;
- }
- if (startfreq < 2300) startfreq = 2300;
- if (startfreq > 6000) startfreq = 6000;
- if (accel < -20) accel = -20;
- if (accel > 20) accel = 20;
- }
-
- graphics_quit_sdl();
-}
-
-void usage(int argc, char *argv[])
-{
- fprintf(stderr, "Usage: %s [scanfile]\n", argv[0]);
- fprintf(stderr, "\n");
- fprintf(stderr, "scanfile is generated by the spectral analyzer feature\n");
- fprintf(stderr, "of your wifi card. If you have a AR92xx or AR93xx based\n");
- fprintf(stderr, "card, try:\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "ifconfig wlan0 up\n");
- fprintf(stderr, "iw dev wlan0 scan spec-scan\n");
- fprintf(stderr, "cat /sys/kernel/debug/ieee80211/phy0/ath9k/spectral_scan > /tmp/fft_results\n");
- fprintf(stderr, "%s /tmp/fft_results\n", argv[0]);
- fprintf(stderr, "\n");
- fprintf(stderr, "(NOTE: maybe debugfs must be mounted first: mount -t debugfs none /sys/kernel/debug/ )\n");
- fprintf(stderr, "\n");
-
-}
-
-static void
-fft_eval_cb(struct radar_entry *re, void *cbdata)
-{
- struct radar_fft_entry *fe;
- int i;
-
- pthread_mutex_lock(&mtx_histogram);
- for (i = 0; i < re->re_num_spectral_entries; i++) {
- fft_add_sample(re, &re->re_spectral_entries[i]);
- }
- g_do_update = 1;
- pthread_mutex_unlock(&mtx_histogram);
-
-}
-
-int main(int argc, char *argv[])
-{
- int ret;
-
- if (argc < 2) {
- usage(argc, argv);
- return -1;
- }
-
- fprintf(stderr, "WARNING: Experimental Software! Don't trust anything you see. :)\n");
- fprintf(stderr, "\n");
-
- /* Setup radar entry callback */
- pthread_mutex_init(&mtx_histogram, NULL);
- set_scandata_callback(fft_eval_cb, NULL);
-
- /* Fetch data */
- ret = read_scandata_freebsd(argv[1], NULL);
-
- if (ret < 0) {
- fprintf(stderr, "Couldn't read scanfile ...\n");
- usage(argc, argv);
- return -1;
- }
- graphics_main();
-
- return 0;
-}
Added: user/adrian/ath_radar_stuff/src/spectral_fft/fft_display.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/fft_display.h Wed Jan 9 20:01:08 2013 (r245235)
@@ -0,0 +1,15 @@
+#ifndef __FFT_DISPLAY_H__
+#define __FFT_DISPLAY_H__
+
+struct fft_display {
+ SDL_Surface *screen;
+ TTF_Font *font;
+};
+
+extern struct fft_display * fft_display_create(SDL_Surface *screen,
+ TTF_Font *font);
+extern void fft_display_destroy(struct fft_display *disp);
+extern int fft_display_draw_picture(struct fft_display *fdisp,
+ int highlight, int startfreq);
+
+#endif /* __FFT_DISPLAY_H__ */
Modified: user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c
==============================================================================
--- user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c Wed Jan 9 19:49:35 2013 (r245234)
+++ user/adrian/ath_radar_stuff/src/spectral_fft/fft_eval.c Wed Jan 9 20:01:08 2013 (r245235)
@@ -47,6 +47,7 @@
#include "fft_eval.h"
#include "fft_freebsd.h"
#include "fft_histogram.h"
+#include "fft_display.h"
#define WIDTH 1600
#define HEIGHT 650
@@ -66,7 +67,6 @@
/* XXX ew globals */
pthread_mutex_t mtx_histogram;
int g_do_update = 0;
-
SDL_Surface *screen = NULL;
TTF_Font *font = NULL;
@@ -119,216 +119,11 @@ void graphics_quit_sdl(void)
SDL_Quit();
}
-int pixel(Uint32 *pixels, int x, int y, Uint32 color)
-{
- if (x < 0 || x >= WIDTH)
- return -1;
- if (y < 0 || y >= HEIGHT)
- return -1;
-
- pixels[x + y * WIDTH] |= color;
- return 0;
-}
-
-#define SIZE 2
-
-/* Is this pixel in the viewport? */
-static int
-is_in_viewport(int x, int y)
-{
- if (x - SIZE < 0 || x + SIZE >= WIDTH)
- return 0;
- if (y - SIZE < 0 || y + SIZE >= HEIGHT)
- return 0;
- return (1);
-}
-
-/* this function blends a 2*SIZE x 2*SIZE blob at the given position with
- * the defined opacity. */
-int bigpixel(Uint32 *pixels, int x, int y, Uint32 color, uint8_t opacity)
-{
- int x1, y1;
-
- if (! is_in_viewport(x, y))
- return -1;
-
- for (x1 = x - SIZE; x1 < x + SIZE; x1++)
- for (y1 = y - SIZE; y1 < y + SIZE; y1++) {
- Uint32 r, g, b;
-
- r = ((pixels[x1 + y1 * WIDTH] & RMASK) >> RBITS) +
- ((((color & RMASK) >> RBITS) * opacity) / 255);
- if (r > 255) r = 255;
-
- g = ((pixels[x1 + y1 * WIDTH] & GMASK) >> GBITS) +
- ((((color & GMASK) >> GBITS) * opacity) / 255);
- if (g > 255) g = 255;
-
- b = ((pixels[x1 + y1 * WIDTH] & BMASK) >> BBITS) +
- ((((color & BMASK) >> BBITS) * opacity) / 255);
- if (b > 255) b = 255;
-
- pixels[x1 + y1 * WIDTH] = r << RBITS |
- g << GBITS | b << BBITS | (color & AMASK);
- }
- return 0;
-}
-
-int bighotpixel(Uint32 *pixels, int x, int y, Uint32 color, uint8_t opacity)
-{
- int x1, y1;
-
- if (! is_in_viewport(x, y))
- return -1;
-
- for (x1 = x - SIZE; x1 < x + SIZE; x1++)
- for (y1 = y - SIZE; y1 < y + SIZE; y1++) {
- Uint32 r, g, b;
-
- r = ((pixels[x1 + y1 * WIDTH] & RMASK) >> RBITS) +
- ((((color & RMASK) >> RBITS) * opacity) / 255);
- if (r > 255) r = 255;
-
- g = ((pixels[x1 + y1 * WIDTH] & GMASK) >> GBITS) +
- ((((color & GMASK) >> GBITS) * opacity) / 255);
- if (g > 255) g = 255;
-
- /* If we've capped out blue, increment red */
- b = ((pixels[x1 + y1 * WIDTH] & BMASK) >> BBITS);
- if (b > 248) {
- /* green bumped by bluemask */
- g = ((pixels[x1 + y1 * WIDTH] & GMASK) >> GBITS) +
- ((((color & BMASK) >> BBITS) * (opacity/2)) / 255);
- if (g > 255) g = 255;
- } else {
- b = ((pixels[x1 + y1 * WIDTH] & BMASK) >> BBITS) +
- ((((color & BMASK) >> BBITS) * opacity) / 255);
- if (b > 255) b = 255;
- }
-
- pixels[x1 + y1 * WIDTH] = r << RBITS |
- g << GBITS | b << BBITS | (color & AMASK);
- }
- return 0;
-}
-
-int render_text(SDL_Surface *surface, char *text, int x, int y)
-{
- SDL_Surface *text_surface;
- SDL_Color fontcolor = {255, 255, 255, 255};
- SDL_Rect fontdest = {0, 0, 0, 0};
-
- fontdest.x = x;
- fontdest.y = y;
-
- text_surface = TTF_RenderText_Solid(font, text, fontcolor);
- if (!text_surface)
- return -1;
-
- SDL_BlitSurface(text_surface, NULL, surface, &fontdest);
- SDL_FreeSurface(text_surface);
-
- return 0;
-}
-
-/*
- * draw_picture - draws the current screen.
- *
- * @highlight: the index of the dataset to be highlighted
- *
- * returns the center frequency of the currently highlighted dataset
- */
-int draw_picture(int highlight, int startfreq)
-{
- Uint32 *pixels, color, opacity;
- int x, y, i, rnum, j;
- int highlight_freq = startfreq + 20;
- char text[1024];
- struct scanresult *result;
- SDL_Surface *surface;
-
- surface = SDL_CreateRGBSurface(SDL_SWSURFACE, WIDTH, HEIGHT, BPP, RMASK, GMASK, BMASK, AMASK);
- pixels = (Uint32 *) surface->pixels;
- for (y = 0; y < HEIGHT; y++)
- for (x = 0; x < WIDTH; x++)
- pixels[x + y * WIDTH] = AMASK;
-
- /* vertical lines (frequency) */
- for (i = 2300; i < 6000; i += 20) {
- x = (X_SCALE * (i - startfreq));
-
- if (x < 0 || x > WIDTH)
- continue;
-
- for (y = 0; y < HEIGHT - 20; y++)
- pixels[x + y * WIDTH] = 0x40404040 | AMASK;
-
- snprintf(text, sizeof(text), "%d MHz", i);
- render_text(surface, text, x - 30, HEIGHT - 20);
- }
-
- /* horizontal lines (dBm) */
- for (i = 0; i < 150; i += 10) {
- y = 600 - Y_SCALE * i;
-
- for (x = 0; x < WIDTH; x++)
- pixels[x + y * WIDTH] = 0x40404040 | AMASK;
-
- snprintf(text, sizeof(text), "-%d dBm", (150 - i));
- render_text(surface, text, 5, y - 15);
- }
-
- /* Render 2300 -> 6000 in 1MHz increments, but using KHz math */
- /* .. as right now the canvas is .. quite large. */
- /* XXX should just do it based on the current viewport! */
- for (i = 2300*1000; i < 6000*1000; i+= 250) {
- float signal;
- int freqKhz = i;
- int16_t *s;
-
- x = X_SCALE * (freqKhz - (startfreq * 1000)) / 1000;
-
- if (x < 0 || x > WIDTH)
- continue;
-
- /* Fetch dBm value at the given frequency in KHz */
- s = fft_fetch_freq_avg(freqKhz);
- if (s == NULL)
- continue;
-
- for (j = 0; j < FFT_HISTOGRAM_HISTORY_DEPTH; j++) {
- if (s[j] == 0)
- continue;
- signal = (float) s[j];
- color = BMASK | AMASK;
- opacity = 64;
- y = 400 - (400.0 + Y_SCALE * signal);
- if (bighotpixel(pixels, x, y, color, opacity) < 0)
- continue;
- }
-
-
- /* .. and the max */
- signal = (float) fft_fetch_freq_max(freqKhz);
- color = RMASK | AMASK;
- opacity = 128;
- y = 400 - (400.0 + Y_SCALE * signal);
- if (bigpixel(pixels, x, y, color, opacity) < 0)
- continue;
- }
-
- SDL_BlitSurface(surface, NULL, screen, NULL);
- SDL_FreeSurface(surface);
- SDL_Flip(screen);
-
- return highlight_freq;
-}
-
/*
* graphics_main - sets up the data and holds the mainloop.
*
*/
-void graphics_main(void)
+void graphics_main(struct fft_display *fdisp)
{
SDL_Event event;
int quit = 0;
@@ -337,11 +132,6 @@ void graphics_main(void)
int startfreq = 2350, accel = 0;
int highlight_freq = startfreq;
- if (graphics_init_sdl() < 0) {
- fprintf(stderr, "Failed to initialize graphics.\n");
- return;
- }
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
while (!quit) {
pthread_mutex_lock(&mtx_histogram);
if (g_do_update == 1) {
@@ -351,7 +141,8 @@ void graphics_main(void)
pthread_mutex_unlock(&mtx_histogram);
if (change) {
- highlight_freq = draw_picture(highlight, startfreq);
+ highlight_freq = fft_display_draw_picture(fdisp,
+ highlight, startfreq);
change = 0;
}
@@ -429,8 +220,6 @@ void graphics_main(void)
if (accel < -20) accel = -20;
if (accel > 20) accel = 20;
}
-
- graphics_quit_sdl();
}
void usage(int argc, char *argv[])
@@ -469,6 +258,7 @@ fft_eval_cb(struct radar_entry *re, void
int main(int argc, char *argv[])
{
int ret;
+ struct fft_display *fdisp;
if (argc < 2) {
usage(argc, argv);
@@ -482,6 +272,19 @@ int main(int argc, char *argv[])
pthread_mutex_init(&mtx_histogram, NULL);
set_scandata_callback(fft_eval_cb, NULL);
+ /* Setup graphics */
+ if (graphics_init_sdl() < 0) {
+ fprintf(stderr, "Failed to initialize graphics.\n");
+ exit(127);
+ }
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+
+ /* Setup fft display */
+
+ fdisp = fft_display_create(screen, font);
+ if (fdisp == NULL)
+ exit(127);
+
/* Fetch data */
ret = read_scandata_freebsd(argv[1], NULL);
@@ -490,7 +293,9 @@ int main(int argc, char *argv[])
usage(argc, argv);
return -1;
}
- graphics_main();
+ graphics_main(fdisp);
+
+ graphics_quit_sdl();
return 0;
}
More information about the svn-src-user
mailing list