nuclear@1: /* nuclear@1: 256-color 3D graphics hack for real-mode DOS. nuclear@1: Copyright (C) 2011 John Tsiombikas nuclear@1: nuclear@1: This program is free software: you can redistribute it and/or modify nuclear@1: it under the terms of the GNU General Public License as published by nuclear@1: the Free Software Foundation, either version 3 of the License, or nuclear@1: (at your option) any later version. nuclear@1: nuclear@1: This program is distributed in the hope that it will be useful, nuclear@1: but WITHOUT ANY WARRANTY; without even the implied warranty of nuclear@1: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the nuclear@1: GNU General Public License for more details. nuclear@1: nuclear@1: You should have received a copy of the GNU General Public License nuclear@1: along with this program. If not, see . nuclear@1: */ nuclear@1: nuclear@1: #include nuclear@1: #include "palman.h" nuclear@1: nuclear@1: #define MAX_COLORS 256 nuclear@1: static struct palm_color colors[MAX_COLORS]; nuclear@1: static int base_index[MAX_COLORS]; nuclear@1: nuclear@1: static struct palm_color pal[MAX_COLORS]; nuclear@1: static unsigned int ncol, pcol; nuclear@1: static int range; nuclear@1: nuclear@1: void palm_clear(void) nuclear@1: { nuclear@1: ncol = 0; nuclear@1: } nuclear@1: nuclear@1: int palm_add_color(unsigned char r, unsigned char g, unsigned char b) nuclear@1: { nuclear@1: if(ncol >= MAX_COLORS) { nuclear@1: return -1; nuclear@1: } nuclear@1: colors[ncol].r = r; nuclear@1: colors[ncol].g = g; nuclear@1: colors[ncol].b = b; nuclear@1: ncol++; nuclear@1: return 0; nuclear@1: } nuclear@1: nuclear@4: int palm_color_index(unsigned char r, unsigned char g, unsigned char b) nuclear@4: { nuclear@4: int i; nuclear@4: nuclear@35: for(i=0; i<(int)ncol; i++) { nuclear@4: if(colors[i].r == r && colors[i].g == g && colors[i].b == b) { nuclear@4: return i; nuclear@4: } nuclear@4: } nuclear@4: return -1; nuclear@4: } nuclear@4: nuclear@1: /* TODO: build an octree */ nuclear@1: int palm_build(void) nuclear@1: { nuclear@1: int i, j; nuclear@1: nuclear@8: if(!ncol) { nuclear@8: return -1; nuclear@8: } nuclear@8: nuclear@1: /* gradient range for each color */ nuclear@1: range = MAX_COLORS / ncol; nuclear@1: nuclear@8: if(range <= 1) { nuclear@1: memcpy(pal, colors, ncol * sizeof *pal); nuclear@1: return 0; nuclear@1: } nuclear@1: pcol = 0; nuclear@1: nuclear@35: for(i=0; i<(int)ncol; i++) { nuclear@6: unsigned short r, g, b, dr, dg, db; nuclear@1: nuclear@1: base_index[i] = pcol; nuclear@1: nuclear@6: dr = ((unsigned short)colors[i].r << 8) / (range - 1); nuclear@6: dg = ((unsigned short)colors[i].g << 8) / (range - 1); nuclear@6: db = ((unsigned short)colors[i].b << 8) / (range - 1); nuclear@1: nuclear@1: r = g = b = 0; nuclear@1: for(j=0; j> 8); nuclear@1: pal[pcol].g = (unsigned char)(g >> 8); nuclear@1: pal[pcol].b = (unsigned char)(b >> 8); nuclear@1: pcol++; nuclear@1: r += dr; nuclear@1: g += dg; nuclear@1: b += db; nuclear@1: } nuclear@1: } nuclear@1: return pcol; nuclear@1: } nuclear@1: nuclear@1: struct palm_color *palm_palette(void) nuclear@1: { nuclear@1: return pal; nuclear@1: } nuclear@1: nuclear@1: int palm_palette_size(void) nuclear@1: { nuclear@1: return pcol; nuclear@1: } nuclear@1: nuclear@1: nuclear@1: int palm_color_base(unsigned char r, unsigned char g, unsigned char b) nuclear@1: { nuclear@4: int c; nuclear@1: nuclear@4: if((c = palm_color_index(r, g, b)) == -1) { nuclear@4: return -1; nuclear@1: } nuclear@4: return base_index[c]; nuclear@1: } nuclear@1: nuclear@1: int palm_color_range(void) nuclear@1: { nuclear@1: return range; nuclear@1: }