Edge enhancement support
This commit is contained in:
parent
8941504863
commit
2d06599a85
@ -1,5 +1,37 @@
|
||||
#include "camera.h"
|
||||
|
||||
/* This is not a completely emulation of the camera chip. Only the features used by the GameBoy Camera ROMs are supported. */
|
||||
|
||||
|
||||
static long get_processed_color(GB_gameboy_t *gb, uint8_t x, uint8_t y)
|
||||
{
|
||||
if (x >= 128) {
|
||||
x = 0;
|
||||
}
|
||||
if (y >= 112) {
|
||||
y = 0;
|
||||
}
|
||||
|
||||
long color = gb->camera_get_pixel_callback? gb->camera_get_pixel_callback(gb, x, y) : (rand() & 0xFF);
|
||||
|
||||
static const double gain_values[] = {0.8809390, 0.9149149, 0.9457498, 0.9739758,
|
||||
1.0000000, 1.0241412, 1.0466537, 1.0677433,
|
||||
1.0875793, 1.1240310, 1.1568911, 1.1868043,
|
||||
1.2142561, 1.2396208, 1.2743837, 1.3157323,
|
||||
1.3525190, 1.3856512, 1.4157897, 1.4434309,
|
||||
1.4689574, 1.4926697, 1.5148087, 1.5355703,
|
||||
1.5551159, 1.5735801, 1.5910762, 1.6077008,
|
||||
1.6235366, 1.6386550, 1.6531183, 1.6669808};
|
||||
/* Multiply color by gain value */
|
||||
color *= gain_values[gb->camera_registers[GB_CAMERA_GAIN_AND_EDGE_ENHACEMENT_FLAGS] & 0x1F];
|
||||
|
||||
|
||||
/* Color is multiplied by the exposure register to simulate exposure. */
|
||||
color = color * ((gb->camera_registers[GB_CAMERA_EXPOSURE_HIGH] << 8) + gb->camera_registers[GB_CAMERA_EXPOSURE_LOW]) / 0x1000;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
uint8_t GB_camera_read_image(GB_gameboy_t *gb, uint16_t addr)
|
||||
{
|
||||
if (gb->camera_registers[GB_CAMERA_SHOOT_AND_1D_FLAGS] & 1) {
|
||||
@ -14,25 +46,24 @@ uint8_t GB_camera_read_image(GB_gameboy_t *gb, uint16_t addr)
|
||||
|
||||
uint8_t ret = 0;
|
||||
|
||||
/* This is not a complete emulation of the chip's image proccessing algorithm, it only emulates the features used by
|
||||
the actual GameBoy Camera ROM. */
|
||||
|
||||
for (uint8_t x = tile_x * 8; x < tile_x * 8 + 8; x++) {
|
||||
|
||||
long color = gb->camera_get_pixel_callback? gb->camera_get_pixel_callback(gb, x,y) : (rand() & 0xFF);
|
||||
long color = get_processed_color(gb, x, y);
|
||||
|
||||
static const double gain_values[] = {0.8809390, 0.9149149, 0.9457498, 0.9739758,
|
||||
1.0000000, 1.0241412, 1.0466537, 1.0677433,
|
||||
1.0875793, 1.1240310, 1.1568911, 1.1868043,
|
||||
1.2142561, 1.2396208, 1.2743837, 1.3157323,
|
||||
1.3525190, 1.3856512, 1.4157897, 1.4434309,
|
||||
1.4689574, 1.4926697, 1.5148087, 1.5355703,
|
||||
1.5551159, 1.5735801, 1.5910762, 1.6077008,
|
||||
1.6235366, 1.6386550, 1.6531183, 1.6669808};
|
||||
/* Multiply color by gain value */
|
||||
color *= gain_values[gb->camera_registers[GB_CAMERA_GAIN_AND_EDGE_ENCHANCEMENT_FLAGS] & 0x1F];
|
||||
static const double edge_enhancement_ratios[] = {0.5, 0.75, 1, 1.25, 2, 3, 4, 5};
|
||||
double edge_enhancement_ratio = edge_enhancement_ratios[(gb->camera_registers[GB_CAMERA_EDGE_ENHANCEMENT_INVERT_AND_VOLTAGE] >> 4) & 0x7];
|
||||
if ((gb->camera_registers[GB_CAMERA_GAIN_AND_EDGE_ENHACEMENT_FLAGS] & 0xE0) == 0xE0) {
|
||||
color += (color * 4) * edge_enhancement_ratio;
|
||||
color -= get_processed_color(gb, x - 1, y) * edge_enhancement_ratio;
|
||||
color -= get_processed_color(gb, x + 1, y) * edge_enhancement_ratio;
|
||||
color -= get_processed_color(gb, x, y - 1) * edge_enhancement_ratio;
|
||||
color -= get_processed_color(gb, x, y + 1) * edge_enhancement_ratio;
|
||||
}
|
||||
|
||||
|
||||
/* Color is multiplied by the exposure register to simulate exposure. */
|
||||
color = color * ((gb->camera_registers[GB_CAMERA_EXPOSURE_HIGH] << 8) + gb->camera_registers[GB_CAMERA_EXPOSURE_LOW]) / 0x1000;
|
||||
|
||||
/* The camera's registers are used as a threshold pattern, which defines the dithering */
|
||||
uint8_t pattern_base = ((x & 3) + (y & 3) * 4) * 3 + GB_CAMERA_DITHERING_PATTERN_START;
|
||||
|
||||
|
@ -4,9 +4,10 @@
|
||||
|
||||
enum {
|
||||
GB_CAMERA_SHOOT_AND_1D_FLAGS = 0,
|
||||
GB_CAMERA_GAIN_AND_EDGE_ENCHANCEMENT_FLAGS = 1,
|
||||
GB_CAMERA_GAIN_AND_EDGE_ENHACEMENT_FLAGS = 1,
|
||||
GB_CAMERA_EXPOSURE_HIGH = 2,
|
||||
GB_CAMERA_EXPOSURE_LOW = 3,
|
||||
GB_CAMERA_EDGE_ENHANCEMENT_INVERT_AND_VOLTAGE = 4,
|
||||
GB_CAMERA_DITHERING_PATTERN_START = 6,
|
||||
GB_CAMERA_DITHERING_PATTERN_END = 0x35,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user