353 lines
10 KiB
C
353 lines
10 KiB
C
/****************************************************************************
|
|
* apps/graphics/traveler/tools/libwld/wld_loadpaltable.c
|
|
* This file contains the logic that creates the range palette table that is
|
|
* used to modify the palette with range to hit
|
|
*
|
|
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in
|
|
* the documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name NuttX nor the names of its contributors may be
|
|
* used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
****************************************************************************/
|
|
|
|
/*************************************************************************
|
|
* Included files
|
|
*************************************************************************/
|
|
|
|
/* If the following switch is false, then the whole g_pal_table is loaded from
|
|
* the file. Otherwise, the g_pal_table will be calculated from a range
|
|
* table
|
|
*/
|
|
|
|
#define USE_PAL_RANGES true
|
|
|
|
#include "trv_types.h"
|
|
#include "wld_world.h"
|
|
#include "wld_paltable.h"
|
|
#if (!MSWINDOWS)
|
|
# include "wld_bitmaps.h"
|
|
# include "wld_color.h"
|
|
#endif
|
|
#include "wld_mem.h"
|
|
#include "wld_utils.h"
|
|
|
|
/*************************************************************************
|
|
* Pre-processor Definitions
|
|
*************************************************************************/
|
|
|
|
/* This indicates the maximum number of palette ranges which may be
|
|
* specified in the file
|
|
*/
|
|
|
|
#if USE_PAL_RANGES
|
|
# define MAX_PAL_RANGES 64
|
|
#endif
|
|
|
|
/*************************************************************************
|
|
* Private Type Definitions
|
|
************************************************************************/
|
|
|
|
#if USE_PAL_RANGES
|
|
typedef struct
|
|
{
|
|
uint8_t firstColor;
|
|
int8_t colorRange;
|
|
uint8_t clipColor;
|
|
} pal_range_t;
|
|
#endif
|
|
|
|
/*************************************************************************
|
|
* Public Data
|
|
*************************************************************************/
|
|
|
|
/* This is the palette table which is used to adjust the texture values
|
|
* with distance
|
|
*/
|
|
|
|
wld_pixel_t *g_pal_table[NUM_ZONES];
|
|
|
|
/*************************************************************************
|
|
* Private Functions
|
|
*************************************************************************/
|
|
|
|
/*************************************************************************
|
|
* Name: wld_allocate_paltable
|
|
* Description:
|
|
************************************************************************/
|
|
|
|
static void wld_allocate_paltable(uint32_t palTabEntrySize)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < NUM_ZONES; i++)
|
|
{
|
|
g_pal_table[i] =
|
|
(wld_pixel_t *) wld_malloc(palTabEntrySize * sizeof(wld_pixel_t));
|
|
}
|
|
}
|
|
|
|
/*************************************************************************
|
|
* Public Functions
|
|
*************************************************************************/
|
|
|
|
/*************************************************************************
|
|
* Name: wld_load_paltable
|
|
* Description:
|
|
* This function loads the g_pal_table from the specified file
|
|
************************************************************************/
|
|
|
|
uint8_t wld_load_paltable(char *file)
|
|
{
|
|
#if (!MSWINDOWS)
|
|
wld_pixel_t *palptr;
|
|
color_lum_t lum;
|
|
int16_t zone;
|
|
float scale;
|
|
int pixel;
|
|
|
|
/* Allocate memory to hold the palette range mapping data */
|
|
|
|
wld_allocate_paltable(TRV_PIXEL_MAX + 1);
|
|
|
|
/* The first zone is just the identity transformation */
|
|
|
|
palptr = g_pal_table[0];
|
|
for (pixel = 0; pixel <= TRV_PIXEL_MAX; pixel++)
|
|
{
|
|
*palptr++ = pixel;
|
|
}
|
|
|
|
/* Process each remaining distance zone */
|
|
|
|
for (zone = 1; zone < NUM_ZONES; zone++)
|
|
{
|
|
/* Point to the palette mapping data for this zone */
|
|
|
|
palptr = g_pal_table[zone];
|
|
|
|
/* Calculate the luminance scaling factor to use for this zone */
|
|
|
|
scale = (float)(NUM_ZONES - zone) / (float)NUM_ZONES;
|
|
|
|
/* Scale each element of the palette */
|
|
|
|
for (pixel = 0; pixel <= TRV_PIXEL_MAX; pixel++)
|
|
{
|
|
/* Get the unit vector + luminance representation of the pixel */
|
|
|
|
wld_pixel2lum(pixel, &lum);
|
|
|
|
/* Re-scale the luminance component by range scale factor */
|
|
|
|
lum.luminance *= scale;
|
|
|
|
/* Then save the pixel associated with this scaled value in the range
|
|
* palette table */
|
|
|
|
*palptr++ = wld_lum2pixel(&lum);
|
|
}
|
|
}
|
|
|
|
return WORLD_SUCCESS;
|
|
|
|
#else
|
|
# if USE_PAL_RANGES
|
|
FILE *fp, *fopen();
|
|
int16_t i;
|
|
int16_t nranges;
|
|
int16_t zone;
|
|
int16_t palndx;
|
|
wld_pixel_t plotcolor;
|
|
wld_pixel_t *palptr;
|
|
pal_range_t ranges[MAX_PAL_RANGES];
|
|
|
|
/* Open the file which contains the palette table */
|
|
|
|
fp = fopen(file, "r");
|
|
if (!fp)
|
|
{
|
|
return PALR_FILE_OPEN_ERROR;
|
|
}
|
|
|
|
/* Read the number of ranges from the file */
|
|
|
|
nranges = wld_read_decimal(fp);
|
|
if (nranges > MAX_PAL_RANGES)
|
|
{
|
|
fclose(fp);
|
|
return PALR_TOO_MANY_RANGES;
|
|
}
|
|
|
|
/* Then read all of the palette range data from the file */
|
|
|
|
for (i = 0; i < nranges; i++)
|
|
{
|
|
ranges[i].firstColor = wld_read_decimal(fp);
|
|
ranges[i].colorRange = wld_read_decimal(fp);
|
|
ranges[i].clipColor = wld_read_decimal(fp);
|
|
}
|
|
|
|
/* We are now done with the input file */
|
|
|
|
fclose(fp);
|
|
|
|
/* Allocate memory to hold the palette range mapping data */
|
|
|
|
wld_allocate_paltable(PALETTE_SIZE);
|
|
|
|
/* Process each distance zone */
|
|
|
|
for (zone = 0; zone < NUM_ZONES; zone++)
|
|
{
|
|
/* Point to the palette mapping data for this zone */
|
|
|
|
palptr = g_pal_table[zone];
|
|
|
|
/* Process each possible palette index within the zone */
|
|
|
|
for (palndx = 0; palndx < PALETTE_SIZE; palndx++)
|
|
{
|
|
/* Assume that the range will not be found. In this case, we will
|
|
* perform the 1-to-1 mapping */
|
|
|
|
plotcolor = palndx;
|
|
|
|
/* Find the range the color is in. */
|
|
|
|
for (i = 0; i < nranges; i++)
|
|
{
|
|
/* Check if the color range is ascending or descending */
|
|
|
|
if (ranges[i].colorRange < 0)
|
|
{
|
|
/* The colors are descending */
|
|
if ((palndx <= ranges[i].firstColor) &&
|
|
(palndx > (ranges[i].firstColor + ranges[i].colorRange)))
|
|
{
|
|
/* Found it, set the new plotcolor */
|
|
|
|
if (plotcolor > zone)
|
|
{
|
|
/* Offset the color by the zone we are processing */
|
|
|
|
plotcolor -= zone;
|
|
|
|
/* Check if we have exceeded the range of this color.
|
|
* If so, then set the color to the clipColor */
|
|
|
|
if (plotcolor <=
|
|
ranges[i].firstColor + ranges[i].colorRange)
|
|
{
|
|
plotcolor = ranges[i].clipColor;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
plotcolor = ranges[i].clipColor;
|
|
}
|
|
|
|
/* Now break out of the loop */
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* The colors are ascending */
|
|
|
|
else if ((palndx >= ranges[i].firstColor) &&
|
|
(palndx < (ranges[i].firstColor + ranges[i].colorRange)))
|
|
{
|
|
/* Found it, set the new plotcolor */
|
|
|
|
plotcolor += zone;
|
|
|
|
/* Check if we have exceeded the range of this color. If so,
|
|
* then set the color to black */
|
|
|
|
if (plotcolor >= ranges[i].firstColor + ranges[i].colorRange)
|
|
{
|
|
plotcolor = ranges[i].clipColor;
|
|
}
|
|
|
|
/* Now break out of the loop */
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Save the plotcolor in the g_pal_table */
|
|
|
|
palptr[palndx] = plotcolor;
|
|
|
|
}
|
|
}
|
|
|
|
return WORLD_SUCCESS;
|
|
# else
|
|
FILE *fp;
|
|
int16_t zone;
|
|
int16_t palndx;
|
|
uint8_t plotcolor;
|
|
uint8_t *palptr;
|
|
|
|
/* Allocate memory to hold the palette range mapping data */
|
|
|
|
wld_allocate_paltable();
|
|
|
|
/* Open the file which contains the palette table */
|
|
|
|
fp = fopen(file, "r");
|
|
if (!fp)
|
|
{
|
|
return PALR_FILE_OPEN_ERROR;
|
|
}
|
|
|
|
/* Process each distance zone */
|
|
|
|
for (zone = 0; zone < NUM_ZONES; zone++)
|
|
{
|
|
/* Point to the palette mapping data for this zone */
|
|
|
|
palptr = GET_PALPTR(zone);
|
|
|
|
/* Process each possible palette index within the zone */
|
|
|
|
for (palndx = 0; palndx < PALETTE_SIZE; palndx++)
|
|
{
|
|
/* Read the data into g_pal_table */
|
|
|
|
palptr[palndx] = wld_read_decimal(fp);
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
return WORLD_SUCCESS;
|
|
# endif /* USE_PAL_RANGES */
|
|
#endif /* !MSWINDOWS */
|
|
}
|