/* * Copyright (C) 1999 Peter Amstutz * * 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 "sky.h" #include "gfx.h" ggi_pixel *sky_current; static const skygen_t skies[] = { {skyGenOriginal, 0}, /* normal */ {skyGenOriginal, 1}, /* random */ }; void skyInit() { sky_current = (ggi_pixel *) malloc(gfx_xmax * gfx_ymax * sizeof(ggi_pixel)); } void skyGen(int type) { (skies[type].func) (gfx_xmax, gfx_ymax, sky_current, skies[type].arg); } #define CLIP(var, check, set) if(var check) { var = set; /* printf("clipped " #var " to " #set "\n"); */ } void skyDraw(int sx, int sy, int w, int h) { unsigned y; assert(sy >= 0 && sx >= 0); CLIP(sx, <0, 0); CLIP(sx, >=gfx_xmax, gfx_xmax - 1); CLIP(sy, <0, 0); CLIP(sy, >=gfx_ymax, gfx_ymax - 1); CLIP(w, <0, 0); CLIP(w, +sx > gfx_xmax, gfx_xmax - sx); CLIP(h, <0, 0); CLIP(h, +sy > gfx_ymax, gfx_ymax - sy); if(w == 0) return; for(y = sy; y < sy + h; y++) { /* ggiPutHLine(gfx_vis, sx, y, w, &sky_current[y * gfx_xmax + sx]); */ register unsigned i; for(i = sx; i < sx + w; i++) ggiPutPixel(gfx_vis, i, y, sky_current[y * gfx_xmax + i]); } } unsigned char ditherOrdered(int x, int y) { const static unsigned char d8[8][8] = { {0, 32, 8, 40, 2, 34, 10, 42}, {48, 16, 56, 24, 50, 18, 58, 26}, {12, 44, 4, 36, 14, 46, 6, 38}, {60, 28, 52, 20, 62, 30, 54, 22}, {3, 35, 11, 43, 1, 33, 9, 41}, {51, 19, 59, 27, 49, 17, 57, 25}, {15, 47, 7, 39, 13, 45, 5, 37}, {63, 31, 55, 23, 61, 29, 53, 21} }; return d8[x % 8][y % 8] << 2; } unsigned char ditherRandom(int x, int y) { return rand() & 0xff; } void skyGenOriginal(int xsize, int ysize, ggi_pixel * page, int arg) { switch (arg) { case 0: if(gfx_visualdepth == GT_32BIT || gfx_visualdepth == GT_24BIT) skyGenOriginalFlat(xsize, ysize, page, arg); else skyGenOriginalDither(xsize, ysize, page, arg); break; case 1: skyGenOriginalDither(xsize, ysize, page, arg); break; } } void skyGenOriginalFlat(int xsize, int ysize, ggi_pixel * page, int arg) { unsigned y; register unsigned x; ggi_color c; ggi_pixel p; for(y = 0; y < ysize; y++) { c.r = 0x24 << 8; c.g = 0x24 << 8; c.b = ((y * 0xFF) / ysize) << 8; c.a = 0xFF << 8; p = ggiMapColor(gfx_vis, &c); for(x = 0; x < gfx_xmax; x++) { page[y * xsize + x] = p; } } } void skyGenOriginalDither(int xsize, int ysize, ggi_pixel * page, int arg) { int x, y; unsigned char (*dither) (int x, int y); ggi_color sc[] = { {CMAX >> 3, CMAX >> 3, 0, 0}, {CMAX >> 3, CMAX >> 3, 1 * CMAX / 5, CMAX}, {CMAX >> 3, CMAX >> 3, 2 * CMAX / 5, CMAX}, {CMAX >> 3, CMAX >> 3, 3 * CMAX / 5, CMAX}, {CMAX >> 3, CMAX >> 3, 4 * CMAX / 5, CMAX}, {CMAX >> 3, CMAX >> 3, CMAX, CMAX} }; ggi_pixel sky1, sky2; int num = sizeof(sc) / sizeof(ggi_color) - 1; int len = ysize / num; switch (arg) { case 0: dither = ditherOrdered; break; case 1: dither = ditherRandom; break; default: dither = ditherOrdered; break; } for(y = 0; y < ysize; y++) { int off = y - y / len * len; sky1 = ggiMapColor(gfx_vis, &sc[y / len]); sky2 = ggiMapColor(gfx_vis, &sc[y / len + 1]); for(x = 0; x < xsize; x++) { if(off * 256 / len < dither(x, y)) page[y * xsize + x] = sky1; else page[y * xsize + x] = sky2; } } }