mirror of
https://github.com/holub/mame
synced 2025-06-01 10:31:48 +03:00
218 lines
6.3 KiB
C++
218 lines
6.3 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Aaron Giles
|
|
/***************************************************************************
|
|
|
|
rendutil.h
|
|
|
|
Core rendering utilities.
|
|
|
|
***************************************************************************/
|
|
|
|
#ifndef MAME_EMU_RENDUTIL_H
|
|
#define MAME_EMU_RENDUTIL_H
|
|
|
|
#pragma once
|
|
|
|
#include "render.h"
|
|
|
|
#include <math.h>
|
|
|
|
|
|
/* ----- image formats ----- */
|
|
|
|
enum ru_imgformat
|
|
{
|
|
RENDUTIL_IMGFORMAT_PNG,
|
|
|
|
RENDUTIL_IMGFORMAT_UNKNOWN,
|
|
RENDUTIL_IMGFORMAT_ERROR
|
|
};
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
FUNCTION PROTOTYPES
|
|
***************************************************************************/
|
|
|
|
/* ----- render utilities ----- */
|
|
|
|
void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, const render_color &color, bool force = false);
|
|
bool render_clip_line(render_bounds *bounds, const render_bounds *clip);
|
|
bool render_clip_quad(render_bounds *bounds, const render_bounds *clip, render_quad_texuv *texcoords);
|
|
void render_line_to_quad(const render_bounds *bounds, float width, float length_extension, render_bounds *bounds0, render_bounds *bounds1);
|
|
void render_load_jpeg(bitmap_argb32 &bitmap, emu_file &file, const char *dirname, const char *filename);
|
|
bool render_load_png(bitmap_argb32 &bitmap, emu_file &file, const char *dirname, const char *filename, bool load_as_alpha_to_existing = false);
|
|
ru_imgformat render_detect_image(emu_file &file, const char *dirname, const char *filename);
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
INLINE FUNCTIONS
|
|
***************************************************************************/
|
|
|
|
/*-------------------------------------------------
|
|
render_round_nearest - floating point
|
|
round-to-nearest
|
|
-------------------------------------------------*/
|
|
|
|
static inline float render_round_nearest(float f)
|
|
{
|
|
return floor(f + 0.5f);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
set_render_bounds_xy - cleaner way to set the
|
|
bounds
|
|
-------------------------------------------------*/
|
|
|
|
static inline void set_render_bounds_xy(render_bounds &bounds, float x0, float y0, float x1, float y1)
|
|
{
|
|
bounds.x0 = x0;
|
|
bounds.y0 = y0;
|
|
bounds.x1 = x1;
|
|
bounds.y1 = y1;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
set_render_bounds_wh - cleaner way to set the
|
|
bounds
|
|
-------------------------------------------------*/
|
|
|
|
static inline void set_render_bounds_wh(render_bounds &bounds, float x0, float y0, float width, float height)
|
|
{
|
|
bounds.x0 = x0;
|
|
bounds.y0 = y0;
|
|
bounds.x1 = x0 + width;
|
|
bounds.y1 = y0 + height;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
sect_render_bounds - compute the intersection
|
|
of two render_bounds
|
|
-------------------------------------------------*/
|
|
|
|
static inline void sect_render_bounds(render_bounds &dest, const render_bounds &src)
|
|
{
|
|
dest.x0 = (std::max)(dest.x0, src.x0);
|
|
dest.x1 = (std::min)(dest.x1, src.x1);
|
|
dest.y0 = (std::max)(dest.y0, src.y0);
|
|
dest.y1 = (std::min)(dest.y1, src.y1);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
union_render_bounds - compute the union of two
|
|
render_bounds
|
|
-------------------------------------------------*/
|
|
|
|
static inline void union_render_bounds(render_bounds &dest, const render_bounds &src)
|
|
{
|
|
dest.x0 = (std::min)(dest.x0, src.x0);
|
|
dest.x1 = (std::max)(dest.x1, src.x1);
|
|
dest.y0 = (std::min)(dest.y0, src.y0);
|
|
dest.y1 = (std::max)(dest.y1, src.y1);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
set_render_color - cleaner way to set a color
|
|
-------------------------------------------------*/
|
|
|
|
static inline void set_render_color(render_color *color, float a, float r, float g, float b)
|
|
{
|
|
color->a = a;
|
|
color->r = r;
|
|
color->g = g;
|
|
color->b = b;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
orientation_swap_flips - swap the X and Y
|
|
flip flags
|
|
-------------------------------------------------*/
|
|
|
|
static inline int orientation_swap_flips(int orientation)
|
|
{
|
|
return (orientation & ORIENTATION_SWAP_XY) |
|
|
((orientation & ORIENTATION_FLIP_X) ? ORIENTATION_FLIP_Y : 0) |
|
|
((orientation & ORIENTATION_FLIP_Y) ? ORIENTATION_FLIP_X : 0);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
orientation_reverse - compute the orientation
|
|
that will undo another orientation
|
|
-------------------------------------------------*/
|
|
|
|
static inline int orientation_reverse(int orientation)
|
|
{
|
|
/* if not swapping X/Y, then just apply the same transform to reverse */
|
|
if (!(orientation & ORIENTATION_SWAP_XY))
|
|
return orientation;
|
|
|
|
/* if swapping X/Y, then swap X/Y flip bits to get the reverse */
|
|
else
|
|
return orientation_swap_flips(orientation);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
orientation_add - compute effective orientation
|
|
after applying two subsequent orientations
|
|
-------------------------------------------------*/
|
|
|
|
static inline int orientation_add(int orientation1, int orientation2)
|
|
{
|
|
/* if the 2nd transform doesn't swap, just XOR together */
|
|
if (!(orientation2 & ORIENTATION_SWAP_XY))
|
|
return orientation1 ^ orientation2;
|
|
|
|
/* otherwise, we need to effectively swap the flip bits on the first transform */
|
|
else
|
|
return orientation_swap_flips(orientation1) ^ orientation2;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
apply_brightness_contrast_gamma_fp - apply
|
|
brightness, contrast, and gamma controls to
|
|
a single RGB component
|
|
-------------------------------------------------*/
|
|
|
|
static inline float apply_brightness_contrast_gamma_fp(float srcval, float brightness, float contrast, float gamma)
|
|
{
|
|
/* first apply gamma */
|
|
srcval = pow(srcval, 1.0f / gamma);
|
|
|
|
/* then contrast/brightness */
|
|
srcval = (srcval * contrast) + brightness - 1.0f;
|
|
|
|
/* clamp and return */
|
|
if (srcval < 0.0f)
|
|
srcval = 0.0f;
|
|
if (srcval > 1.0f)
|
|
srcval = 1.0f;
|
|
return srcval;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
apply_brightness_contrast_gamma - apply
|
|
brightness, contrast, and gamma controls to
|
|
a single RGB component
|
|
-------------------------------------------------*/
|
|
|
|
static inline u8 apply_brightness_contrast_gamma(u8 src, float brightness, float contrast, float gamma)
|
|
{
|
|
float srcval = (float)src * (1.0f / 255.0f);
|
|
float result = apply_brightness_contrast_gamma_fp(srcval, brightness, contrast, gamma);
|
|
return u8(result * 255.0f);
|
|
}
|
|
|
|
|
|
#endif // MAME_EMU_RENDUTIL_H
|