Rename GP_Context -> GP_Pixmap
[gfxprim.git] / demos / bogoman / bogoman_render.c
blobc045b541935b8ee39356b8fbd6bd37f4b1783994
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2015 Cyril Hrubis <metan@ucw.cz> *
20 * *
21 *****************************************************************************/
23 #include <GP.h>
25 #include "bogoman_map.h"
26 #include "bogoman_debug.h"
28 #include "bogoman_render.h"
30 struct render_colors {
31 /* global background */
32 GP_Pixel bg;
34 /* player color */
35 GP_Pixel player;
37 /* frames around things */
38 GP_Pixel frames;
40 /* diamod color */
41 GP_Pixel diamond;
43 /* wall color */
44 GP_Pixel wall;
46 /* moveable color */
47 GP_Pixel moveable;
49 /* edible color */
50 GP_Pixel edible;
52 /* particle colors */
53 GP_Pixel particle;
54 GP_Pixel particle_dir;
57 static struct render_colors colors;
59 static void init_colors(GP_Pixmap *pixmap, struct render_colors *colors)
61 colors->bg = GP_RGBToPixmapPixel(0xee, 0xee, 0xee, pixmap);
62 colors->player = GP_RGBToPixmapPixel(0x00, 0xee, 0x00, pixmap);
63 colors->frames = GP_RGBToPixmapPixel(0x00, 0x00, 0x00, pixmap);
64 colors->diamond = GP_RGBToPixmapPixel(0x00, 0x00, 0xee, pixmap);
65 colors->wall = GP_RGBToPixmapPixel(0x66, 0x66, 0x66, pixmap);
66 colors->moveable = GP_RGBToPixmapPixel(0xff, 0xff, 0x60, pixmap);
67 colors->edible = GP_RGBToPixmapPixel(0xff, 0x7f, 0x50, pixmap);
68 colors->particle = GP_RGBToPixmapPixel(0xff, 0xff, 0x00, pixmap);
69 colors->particle_dir = GP_RGBToPixmapPixel(0xff, 0x44, 0x00, pixmap);
72 static void render_none(struct bogoman_render *render,
73 unsigned int x, unsigned int y,
74 struct bogoman_map_elem *elem)
76 unsigned int w = render->map_elem_size;
78 (void) elem;
80 GP_FillRectXYWH(render->pixmap, x, y, w, w, colors.bg);
83 static void render_player(struct bogoman_render *render,
84 unsigned int x, unsigned int y,
85 struct bogoman_map_elem *elem)
87 unsigned int w = render->map_elem_size;
89 (void) elem;
91 GP_FillRectXYWH(render->pixmap, x, y, w, w, colors.bg);
93 GP_FillCircle(render->pixmap, x + w/2, y + w/2, w/2 - 1, colors.player);
94 GP_FillRing(render->pixmap, x + w/2, y + w/2, w/2 - 1, w/2 - 2, colors.frames);
97 static void render_wall(struct bogoman_render *render,
98 unsigned int x, unsigned int y,
99 struct bogoman_map_elem *elem)
101 unsigned int w = render->map_elem_size;
103 GP_FillRectXYWH(render->pixmap, x, y, w, w, colors.wall);
105 if (!(elem->flags & BOGOMAN_LEFT)) {
106 GP_VLineXYH(render->pixmap, x, y, w, colors.frames);
107 GP_VLineXYH(render->pixmap, x+1, y, w, colors.frames);
110 if (!(elem->flags & BOGOMAN_RIGHT)) {
111 GP_VLineXYH(render->pixmap, x + w - 1, y, w, colors.frames);
112 GP_VLineXYH(render->pixmap, x + w - 2, y, w, colors.frames);
115 if (!(elem->flags & BOGOMAN_UP)) {
116 GP_HLineXYW(render->pixmap, x, y, w, colors.frames);
117 GP_HLineXYW(render->pixmap, x, y+1, w, colors.frames);
120 if (!(elem->flags & BOGOMAN_DOWN)) {
121 GP_HLineXYW(render->pixmap, x, y + w - 1, w, colors.frames);
122 GP_HLineXYW(render->pixmap, x, y + w - 2, w, colors.frames);
126 static void render_diamond(struct bogoman_render *render,
127 unsigned int x, unsigned int y,
128 struct bogoman_map_elem *elem)
130 unsigned int w = render->map_elem_size;
132 GP_FillRectXYWH(render->pixmap, x, y, w, w, colors.bg);
134 (void) elem;
136 GP_FillTetragon(render->pixmap, x + w/2, y, x + w - 1, y + w/2,
137 x + w/2, y + w - 1, x, y + w/2, colors.diamond);
139 GP_Tetragon(render->pixmap, x + w/2, y, x + w - 1, y + w/2,
140 x + w/2, y + w - 1, x, y + w/2, colors.frames);
141 GP_Tetragon(render->pixmap, x + w/2, y+1, x + w - 2, y + w/2,
142 x + w/2, y + w - 2, x+1, y + w/2, colors.frames);
145 static void render_moveable(struct bogoman_render *render,
146 unsigned int x, unsigned int y,
147 struct bogoman_map_elem *elem)
149 unsigned int w = render->map_elem_size;
151 (void) elem;
153 GP_FillRectXYWH(render->pixmap, x, y, w, w, colors.bg);
155 GP_FillRectXYWH(render->pixmap, x + 1, y + 1, w - 2, w - 2, colors.moveable);
156 GP_RectXYWH(render->pixmap, x + 1, y + 1, w - 2, w - 2, colors.frames);
157 GP_RectXYWH(render->pixmap, x + 2, y + 2, w - 4, w - 4, colors.frames);
160 static void render_edible(struct bogoman_render *render,
161 unsigned int x, unsigned int y,
162 struct bogoman_map_elem *elem)
164 unsigned int w = render->map_elem_size;
166 (void) elem;
168 GP_FillRectXYWH(render->pixmap, x, y, w, w, colors.bg);
170 GP_FillRectXYWH(render->pixmap, x + 1, y + 1, w - 2, w - 2, colors.edible);
173 static void render_particle(struct bogoman_render *render,
174 unsigned int x, unsigned int y,
175 struct bogoman_map_elem *elem)
177 unsigned int w = render->map_elem_size;
178 int dir = elem->flags & BOGOMAN_DIRECTION_MASK;
180 GP_FillRectXYWH(render->pixmap, x, y, w, w, colors.bg);
182 switch (elem->flags & ~BOGOMAN_DIRECTION_MASK) {
183 case BOGOMAN_PARTICLE_ROUND:
184 GP_FillCircle(render->pixmap, x + w/2, y + w/2, w/2-1, colors.particle);
185 GP_FillRing(render->pixmap, x + w/2, y + w/2, w/2 - 1, w/2 - 2, colors.frames);
186 break;
187 case BOGOMAN_PARTICLE_SQUARE:
188 GP_FillRectXYWH(render->pixmap, x+1, y+1, w-2, w-2, colors.particle);
189 GP_RectXYWH(render->pixmap, x+1, y+1, w-2, w-2, colors.frames);
190 GP_RectXYWH(render->pixmap, x+2, y+2, w-4, w-4, colors.frames);
191 break;
194 switch (dir) {
195 case BOGOMAN_LEFT:
196 GP_FillTriangle(render->pixmap, x + w/4, y + w/2,
197 x + 5*w/8, y + w/4, x + 5*w/8, y + 3*w/4, colors.particle_dir);
198 GP_Triangle(render->pixmap, x + w/4, y + w/2,
199 x + 5*w/8, y + w/4, x + 5*w/8, y + 3*w/4, colors.frames);
200 break;
201 case BOGOMAN_RIGHT:
202 GP_FillTriangle(render->pixmap, x + 3*w/4, y + w/2,
203 x + 3*w/8, y + w/4, x + 3*w/8, y + 3*w/4, colors.particle_dir);
204 GP_Triangle(render->pixmap, x + 3*w/4, y + w/2,
205 x + 3*w/8, y + w/4, x + 3*w/8, y + 3*w/4, colors.frames);
206 break;
207 case BOGOMAN_UP:
208 GP_FillTriangle(render->pixmap, x + w/2, y + w/4,
209 x + w/4, y + 5*w/8, x + 3*w/4, y + 5*w/8, colors.particle_dir);
210 GP_Triangle(render->pixmap, x + w/2, y + w/4,
211 x + w/4, y + 5*w/8, x + 3*w/4, y + 5*w/8, colors.frames);
212 break;
213 case BOGOMAN_DOWN:
214 GP_FillTriangle(render->pixmap, x + w/2, y + 3*w/4,
215 x + w/4, y + 3*w/8, x + 3*w/4, y + 3*w/8, colors.particle_dir);
216 GP_Triangle(render->pixmap, x + w/2, y + 3*w/4,
217 x + w/4, y + 3*w/8, x + 3*w/4, y + 3*w/8, colors.frames);
218 break;
222 static void (*renders[])(struct bogoman_render *render,
223 unsigned int x, unsigned int y,
224 struct bogoman_map_elem *elem) =
226 render_none,
227 render_player,
228 render_wall,
229 render_diamond,
230 render_moveable,
231 render_edible,
232 render_particle,
235 static void render_elem(struct bogoman_render *render,
236 unsigned int x, unsigned int y,
237 int flags)
239 struct bogoman_map_elem *elem;
240 unsigned int cx, cy;
242 elem = bogoman_get_map_elem(render->map, x, y);
244 if (elem->dirty) {
245 elem->dirty = 0;
246 } else {
247 if (flags & BOGOMAN_RENDER_DIRTY)
248 return;
251 cx = (x - render->map_x_offset) * render->map_elem_size;
252 cy = (y - render->map_y_offset) * render->map_elem_size;
254 if (elem->id > BOGOMAN_MAX)
255 WARN("Invalid elem ID %u at %ux%u\n", elem->id, x, y);
256 else
257 renders[elem->id](render, cx, cy, elem);
259 if (flags & BOGOMAN_RENDER_DIRTY && render->backend) {
260 GP_BackendUpdateRect(render->backend, cx, cy,
261 cx + render->map_elem_size,
262 cy + render->map_elem_size);
266 void bogoman_render(struct bogoman_render *render, int flags)
268 unsigned int x, y;
270 //TODO: Hack
271 init_colors(render->pixmap, &colors);
273 if (flags & BOGOMAN_RENDER_ALL)
274 GP_Fill(render->pixmap, colors.bg);
276 for (y = render->map_x_offset; y < render->map->h; y++) {
277 for (x = render->map_x_offset; x < render->map->w; x++)
278 render_elem(render, x, y, flags);
281 if (flags & BOGOMAN_RENDER_ALL && render->backend)
282 GP_BackendFlip(render->backend);