/* gLife - An Artificial Life implementation using GNOME * * Copyright (C) 1999 Ali Abdin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include "glife.h" #include "drawing.h" #include "data.h" #include "simulation.h" static ArtSVP* get_line_svp (gint x1, gint y1, gint x2, gint y2) { ArtVpath vpath[3]; ArtSVP *svp; gboolean line_width; line_width = 1.0; /* 1.0 pixel for the width of the line */ vpath[0].code = ART_MOVETO_OPEN; vpath[0].x = x1; vpath[0].y = y1; vpath[1].code = ART_LINETO; vpath[1].x = x2; vpath[1].y = y2; vpath[2].code = ART_END; vpath[2].x = 0; vpath[2].y = 0; svp = art_svp_vpath_stroke (vpath, ART_PATH_STROKE_JOIN_MITER, ART_PATH_STROKE_CAP_BUTT, line_width, 4.0, 1.0); return svp; } static ArtSVP* get_circle_svp (gdouble x, gdouble y, gdouble radius) { ArtVpath *vpath; ArtSVP *svp; gdouble xcenter, ycenter; /* INTERVAL-1 because 1 is the width of the grid line */ if (radius > 14.0) radius = 14.0; xcenter = (gdouble) ((14.0 - (2.0 * radius))/2.0) + radius + (x*INTERVAL); ycenter = (gdouble) ((14.0 - (2.0 * radius))/2.0) + radius + (y*INTERVAL); vpath = art_vpath_new_circle (xcenter, ycenter, radius); svp = art_svp_from_vpath (vpath); art_free (vpath); return svp; } static void render_grid_to_buf() { gint i; /* FIXME: Would probably be more efficient to get the SVP's into an array * and then render in one big go - Might not be possible - Need to ask Raph */ for (i = 0; i <= height-1; i += INTERVAL) { ArtSVP *svp; svp = get_line_svp (i, 0, i, height-1); art_rgb_svp_alpha (svp, 0, 0, height, width, 0x000000ff, drawbuf, ROWSTRIDE, NULL); art_svp_free (svp); } for (i = 0; i <= width-1; i += INTERVAL) { ArtSVP *svp; svp = get_line_svp (0, i, width-1, i); art_rgb_svp_alpha (svp, 0, 0, height, width, 0x000000ff, drawbuf, ROWSTRIDE, NULL); art_svp_free (svp); } } static void render_terrain_to_buf() { gint row,col; for (col = 0; col <= MAXCOL; col++) for (row = 0; row <= MAXROW; row++) { if (!(terrain[col][row].foodamt <= 0)) { ArtSVP *svp; svp = get_circle_svp((gdouble) col, (gdouble) row, RADSIZE(terrain[col][row].foodamt)); art_rgb_svp_alpha (svp, 0, 0, height, width, terrcolor, drawbuf, ROWSTRIDE, NULL); art_svp_free (svp); while (gtk_events_pending()) gtk_main_iteration(); } } } static void render_animals_to_buf() { GList *tmp; tmp = animal; while (tmp) { ArtSVP *svp; AnimalType *anim; anim = (AnimalType *) tmp->data; svp = get_circle_svp ((gdouble) anim->posx-1, (gdouble) anim->posy-1, 3.0); if ((anim->sex == 'm') || (anim->sex == 'M')) art_rgb_svp_alpha (svp, 0, 0, height, width, malecolor, drawbuf, ROWSTRIDE, NULL); else art_rgb_svp_alpha (svp, 0, 0, height, width, femalecolor, drawbuf, ROWSTRIDE, NULL); tmp = tmp->next; while (gtk_events_pending()) gtk_main_iteration(); art_svp_free (svp); } } #if 0 void mini_render_terrain () { gint row,col; for (col = 0; col <= MAXCOL; col++) for (row = 0; row <= MAXROW; row++) { if (!(terrain[col][row].foodamt <= 0)) art_rgb_svp_alpha (terrain[col][row].svp, 0, 0, height, width, terrcolor, drawbuf, ROWSTRIDE, NULL); } } #endif void render() { /* Fille with white before re-rendering to the buffer */ art_rgb_fill_run ((art_u8 *)drawbuf, 255, 255, 255, width*height); if (ruleset.gridcheck) render_grid_to_buf(); if (ruleset.terraincheck) render_terrain_to_buf(); if (ruleset.animalcheck) render_animals_to_buf(); } gboolean on_darea_expose (GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { /* This function taken shamelessly from mattheiu */ guchar *rgbbuf = (guchar *) user_data; /* render(); */ gdk_draw_rgb_image (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], 0, 0, width, height, GDK_RGB_DITHER_MAX, rgbbuf, ROWSTRIDE); return TRUE; }