mirror of
https://github.com/dyne/frei0r.git
synced 2025-12-05 14:19:59 +01:00
Merge branch 'master' into master
This commit is contained in:
@@ -557,6 +557,10 @@ position pointOnBezier(double t, position points[4])
|
||||
return pos;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define strtok_r strtok_s
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Splits given string into sub-strings at given delimiter.
|
||||
* \param string input string
|
||||
@@ -569,11 +573,11 @@ int tokenise(char *string, const char *delimiter, char ***tokens)
|
||||
int count = 0;
|
||||
char *input = strdup(string);
|
||||
char *result = NULL;
|
||||
result = strtok(input, delimiter);
|
||||
result = strtok_r(string, delimiter, &input);
|
||||
while (result != NULL) {
|
||||
*tokens = realloc(*tokens, (count + 1) * sizeof(char *));
|
||||
(*tokens)[count++] = strdup(result);
|
||||
result = strtok(NULL, delimiter);
|
||||
result = strtok_r(NULL, delimiter, &input);
|
||||
}
|
||||
free(input);
|
||||
return count;
|
||||
|
||||
@@ -38,7 +38,7 @@ Copyright (C) 2010 Marko Cebokli http://lea.hamradio.si/~s57uuu
|
||||
double PI=3.14159265358979;
|
||||
|
||||
//---------------------------------------------------------------
|
||||
void draw_rectangle(float_rgba *s, int w, int h, float x, float y, float wr, float hr, float_rgba c)
|
||||
static inline void draw_rectangle(float_rgba *s, int w, int h, float x, float y, float wr, float hr, float_rgba c)
|
||||
{
|
||||
int i,j;
|
||||
int zx,kx,zy,ky;
|
||||
@@ -139,7 +139,7 @@ draw_rectangle(s, w, h, x1, y1+1, v, 1, black);
|
||||
//justified
|
||||
//p=0 one decimal place p=1 three decimal places
|
||||
//m=1 always show sign
|
||||
void forstr(float a, int p, int m, char *s)
|
||||
inline static void forstr(float a, int p, int m, char *s)
|
||||
{
|
||||
float b;
|
||||
char *p3=" %5.3f";
|
||||
@@ -192,14 +192,14 @@ if (mm==1)
|
||||
forstr(s.rms,1-u,0,rs);
|
||||
forstr(s.min,1-u,m,ns);
|
||||
forstr(s.max,1-u,m,xs);
|
||||
sprintf(fs,"%s%s%s %s%s", lab, as, rs, ns, xs);
|
||||
snprintf(fs,255,"%s%s%s %s%s", lab, as, rs, ns, xs);
|
||||
sprintf(str,fs,s.avg,s.rms,s.min,s.max);
|
||||
}
|
||||
else
|
||||
{
|
||||
forstr(s.avg,1-u,m,as);
|
||||
forstr(s.rms,1-u,0,rs);
|
||||
sprintf(fs,"%s%s%s", lab, as, rs);
|
||||
snprintf(fs,255,"%s%s%s", lab, as, rs);
|
||||
sprintf(str,fs,s.avg,s.rms);
|
||||
}
|
||||
}
|
||||
@@ -745,4 +745,3 @@ crosshair(in->sl, in->w, in->h, in->x, in->y, 2*in->sx+1, 2*in->sy+1, 15);
|
||||
|
||||
floatrgba2color(in->sl, outframe, in->w , in->h);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ while (c[i]!=0)
|
||||
//justified
|
||||
//p=0 one decimal place p=1 three decimal places
|
||||
//m=1 always show sign
|
||||
void forstr(float a, int p, int m, char *s)
|
||||
inline static void forstr(float a, int p, int m, char *s)
|
||||
{
|
||||
float b;
|
||||
char *p3=" %5.3f";
|
||||
@@ -320,7 +320,7 @@ if ((dit&0x00000001)!=0) //marker 1 value
|
||||
if (m1>0)
|
||||
{
|
||||
forstr(data[0],1-u,0,frs);
|
||||
sprintf(fs,"%%s Mk1=%s", frs);
|
||||
snprintf(fs,255,"%%s Mk1=%s", frs);
|
||||
sprintf(str,fs,str,data[0]);
|
||||
}
|
||||
else
|
||||
@@ -331,7 +331,7 @@ if ((dit&0x00000004)!=0) //marker 2 value
|
||||
if (m2>0)
|
||||
{
|
||||
forstr(data[1],1-u,0,frs);
|
||||
sprintf(fs,"%%s Mk2=%s", frs);
|
||||
snprintf(fs,255,"%%s Mk2=%s", frs);
|
||||
sprintf(str,fs,str,data[1]);
|
||||
}
|
||||
else
|
||||
@@ -342,7 +342,7 @@ if ((dit&0x00000010)!=0) //difference marker2-marker1
|
||||
if ((m2>0)&&(m1>0))
|
||||
{
|
||||
forstr(data[2],1-u,0,frs);
|
||||
sprintf(fs,"%%s D=%s", frs);
|
||||
snprintf(fs,255,"%%s D=%s", frs);
|
||||
sprintf(str,fs,str,data[2]);
|
||||
}
|
||||
else
|
||||
@@ -351,25 +351,25 @@ if ((dit&0x00000010)!=0) //difference marker2-marker1
|
||||
if ((dit&0x00000020)!=0) //average of profile
|
||||
{
|
||||
forstr(data[3],1-u,0,frs);
|
||||
sprintf(fs,"%%s Avg=%s", frs);
|
||||
snprintf(fs,255,"%%s Avg=%s", frs);
|
||||
sprintf(str,fs,str,data[3]);
|
||||
}
|
||||
if ((dit&0x00000040)!=0) //RMS of profile
|
||||
{
|
||||
forstr(data[4],1-u,0,frs);
|
||||
sprintf(fs,"%%s RMS=%s", frs);
|
||||
snprintf(fs,255,"%%s RMS=%s", frs);
|
||||
sprintf(str,fs,str,data[4]);
|
||||
}
|
||||
if ((dit&0x00000080)!=0) //MIN of profile
|
||||
{
|
||||
forstr(data[5],1-u,0,frs);
|
||||
sprintf(fs,"%%s Min=%s", frs);
|
||||
snprintf(fs,255,"%%s Min=%s", frs);
|
||||
sprintf(str,fs,str,data[5]);
|
||||
}
|
||||
if ((dit&0x00000100)!=0) //MAX of profile
|
||||
{
|
||||
forstr(data[6],1-u,0,frs);
|
||||
sprintf(fs,"%%s Max=%s", frs);
|
||||
snprintf(fs,255,"%%s Max=%s", frs);
|
||||
sprintf(str,fs,str,data[6]);
|
||||
}
|
||||
}
|
||||
@@ -1035,4 +1035,3 @@ prof(in->sl, in->w, in->h, &in->poz, in->x, in->y, in->tilt, in->len, 1, in->mer
|
||||
|
||||
floatrgba2color(in->sl, outframe, in->w , in->h);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,23 @@ crt_sincos14(int *s, int *c, int n)
|
||||
}
|
||||
}
|
||||
|
||||
extern int
|
||||
crt_bpp4fmt(int format)
|
||||
{
|
||||
switch (format) {
|
||||
case CRT_PIX_FORMAT_RGB:
|
||||
case CRT_PIX_FORMAT_BGR:
|
||||
return 3;
|
||||
case CRT_PIX_FORMAT_ARGB:
|
||||
case CRT_PIX_FORMAT_RGBA:
|
||||
case CRT_PIX_FORMAT_ABGR:
|
||||
case CRT_PIX_FORMAT_BGRA:
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/********************************* FILTERS ***********************************/
|
||||
/*****************************************************************************/
|
||||
@@ -222,10 +239,11 @@ eqf(struct EQF *f, int s)
|
||||
/*****************************************************************************/
|
||||
|
||||
extern void
|
||||
crt_resize(struct CRT *v, int w, int h, unsigned char *out)
|
||||
crt_resize(struct CRT *v, int w, int h, int f, unsigned char *out)
|
||||
{
|
||||
v->outw = w;
|
||||
v->outh = h;
|
||||
v->out_format = f;
|
||||
v->out = out;
|
||||
}
|
||||
|
||||
@@ -240,21 +258,13 @@ crt_reset(struct CRT *v)
|
||||
v->white_point = 100;
|
||||
v->hsync = 0;
|
||||
v->vsync = 0;
|
||||
|
||||
v->scanlines = 0; /* leave gaps between lines if necessary */
|
||||
v->blend = 0; /* blend new field onto previous image */
|
||||
|
||||
// these options were previously #defined in crt_core.h
|
||||
v->crt_do_vsync = 1;
|
||||
v->crt_do_hsync = 1;
|
||||
v->do_vhs_noise = 0;
|
||||
}
|
||||
|
||||
extern void
|
||||
crt_init(struct CRT *v, int w, int h, unsigned char *out)
|
||||
crt_init(struct CRT *v, int w, int h, int f, unsigned char *out)
|
||||
{
|
||||
memset(v, 0, sizeof(struct CRT));
|
||||
crt_resize(v, w, h, out);
|
||||
crt_resize(v, w, h, f, out);
|
||||
crt_reset(v);
|
||||
v->rn = 194;
|
||||
|
||||
@@ -293,17 +303,24 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
int huesn, huecs;
|
||||
int xnudge = -3, ynudge = 3;
|
||||
int bright = v->brightness - (BLACK_LEVEL + v->black_point);
|
||||
int pitch;
|
||||
int bpp, pitch;
|
||||
#if CRT_DO_BLOOM
|
||||
int prev_e; /* filtered beam energy per scan line */
|
||||
int max_e; /* approx maximum energy in a scan line */
|
||||
#endif
|
||||
|
||||
pitch = v->outw * BPP;
|
||||
bpp = crt_bpp4fmt(v->out_format);
|
||||
if (bpp == 0) {
|
||||
return;
|
||||
}
|
||||
pitch = v->outw * bpp;
|
||||
|
||||
crt_sincos14(&huesn, &huecs, ((v->hue % 360) + 33) * 8192 / 180);
|
||||
huesn >>= 11; /* make 4-bit */
|
||||
huecs >>= 11;
|
||||
|
||||
rn = v->rn;
|
||||
if(!v->crt_do_vsync)
|
||||
{
|
||||
#if !CRT_DO_VSYNC
|
||||
/* determine field before we add noise,
|
||||
* otherwise it's not reliably recoverable
|
||||
*/
|
||||
@@ -322,15 +339,13 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
/* if vsync signal was in second half of line, odd field */
|
||||
field = (j > (CRT_HRES / 2));
|
||||
v->vsync = -3;
|
||||
}
|
||||
if(v->do_vhs_noise)
|
||||
{
|
||||
#endif
|
||||
#if ((CRT_SYSTEM == CRT_SYSTEM_NTSCVHS) && CRT_VHS_NOISE)
|
||||
line = ((rand() % 8) - 4) + 14;
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i < CRT_INPUT_SIZE; i++) {
|
||||
int nn = noise;
|
||||
if(v->do_vhs_noise)
|
||||
{
|
||||
#if ((CRT_SYSTEM == CRT_SYSTEM_NTSCVHS) && CRT_VHS_NOISE)
|
||||
rn = rand();
|
||||
if (i > (CRT_INPUT_SIZE - CRT_HRES * (16 + ((rand() % 20) - 10))) &&
|
||||
i < (CRT_INPUT_SIZE - CRT_HRES * (5 + ((rand() % 8) - 4)))) {
|
||||
@@ -340,11 +355,9 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
crt_sincos14(&sn, &cs, ln * 8192 / 180);
|
||||
nn = cs >> 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#else
|
||||
rn = (214019 * rn + 140327895);
|
||||
}
|
||||
#endif
|
||||
/* signal + noise */
|
||||
s = v->analog[i] + (((((rn >> 16) & 0xff) - 0x7f) * nn) >> 8);
|
||||
if (s > 127) { s = 127; }
|
||||
@@ -353,8 +366,7 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
}
|
||||
v->rn = rn;
|
||||
|
||||
if(v->crt_do_vsync)
|
||||
{
|
||||
#if CRT_DO_VSYNC
|
||||
/* Look for vertical sync.
|
||||
*
|
||||
* This is done by integrating the signal and
|
||||
@@ -382,8 +394,12 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
v->vsync = line; /* vsync found (or gave up) at this line */
|
||||
/* if vsync signal was in second half of line, odd field */
|
||||
field = (j > (CRT_HRES / 2));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CRT_DO_BLOOM
|
||||
max_e = (128 + (noise / 2)) * AV_LEN;
|
||||
prev_e = (16384 / 8);
|
||||
#endif
|
||||
/* ratio of output height to active video lines in the signal */
|
||||
ratio = (v->outh << 16) / CRT_LINES;
|
||||
ratio = (ratio + 32768) >> 16;
|
||||
@@ -405,6 +421,9 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
int xpos, ypos;
|
||||
int beg, end;
|
||||
int phasealign;
|
||||
#if CRT_DO_BLOOM
|
||||
int line_w;
|
||||
#endif
|
||||
|
||||
beg = (line - CRT_TOP + 0) * (v->outh + v->v_fac) / CRT_LINES + field;
|
||||
end = (line - CRT_TOP + 1) * (v->outh + v->v_fac) / CRT_LINES + field;
|
||||
@@ -424,14 +443,11 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(v->crt_do_hsync)
|
||||
{
|
||||
#if CRT_DO_HSYNC
|
||||
v->hsync = POSMOD(i + v->hsync, CRT_HRES);
|
||||
}
|
||||
else
|
||||
{
|
||||
#else
|
||||
v->hsync = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
xpos = POSMOD(AV_BEG + v->hsync + xnudge, CRT_HRES);
|
||||
ypos = POSMOD(line + v->vsync + ynudge, CRT_VRES);
|
||||
@@ -493,13 +509,28 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
}
|
||||
#endif
|
||||
sig = v->inp + pos;
|
||||
#if CRT_DO_BLOOM
|
||||
s = 0;
|
||||
for (i = 0; i < AV_LEN; i++) {
|
||||
s += sig[i]; /* sum up the scan line */
|
||||
}
|
||||
/* bloom emulation */
|
||||
prev_e = (prev_e * 123 / 128) + ((((max_e >> 1) - s) << 10) / max_e);
|
||||
line_w = (AV_LEN * 112 / 128) + (prev_e >> 9);
|
||||
|
||||
dx = (line_w << 12) / v->outw;
|
||||
scanL = ((AV_LEN / 2) - (line_w >> 1) + 8) << 12;
|
||||
scanR = (AV_LEN - 1) << 12;
|
||||
|
||||
L = (scanL >> 12);
|
||||
R = (scanR >> 12);
|
||||
#else
|
||||
dx = ((AV_LEN - 1) << 12) / v->outw;
|
||||
scanL = 0;
|
||||
scanR = (AV_LEN - 1) << 12;
|
||||
L = 0;
|
||||
R = AV_LEN;
|
||||
|
||||
#endif
|
||||
reset_eq(&eqY);
|
||||
reset_eq(&eqI);
|
||||
reset_eq(&eqQ);
|
||||
@@ -552,8 +583,26 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
|
||||
if (v->blend) {
|
||||
aa = (r << 16 | g << 8 | b);
|
||||
bb = cL[0] << 16 | cL[1] << 8 | cL[2];
|
||||
|
||||
switch (v->out_format) {
|
||||
case CRT_PIX_FORMAT_RGB:
|
||||
case CRT_PIX_FORMAT_RGBA:
|
||||
bb = cL[0] << 16 | cL[1] << 8 | cL[2];
|
||||
break;
|
||||
case CRT_PIX_FORMAT_BGR:
|
||||
case CRT_PIX_FORMAT_BGRA:
|
||||
bb = cL[2] << 16 | cL[1] << 8 | cL[0];
|
||||
break;
|
||||
case CRT_PIX_FORMAT_ARGB:
|
||||
bb = cL[1] << 16 | cL[2] << 8 | cL[3];
|
||||
break;
|
||||
case CRT_PIX_FORMAT_ABGR:
|
||||
bb = cL[3] << 16 | cL[2] << 8 | cL[1];
|
||||
break;
|
||||
default:
|
||||
bb = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* blend with previous color there */
|
||||
bb = (((aa & 0xfefeff) >> 1) + ((bb & 0xfefeff) >> 1));
|
||||
@@ -561,12 +610,52 @@ crt_demodulate(struct CRT *v, int noise)
|
||||
bb = (r << 16 | g << 8 | b);
|
||||
}
|
||||
|
||||
switch (v->out_format) {
|
||||
case CRT_PIX_FORMAT_RGB:
|
||||
cL[0] = bb >> 16 & 0xff;
|
||||
cL[1] = bb >> 8 & 0xff;
|
||||
cL[2] = bb >> 0 & 0xff;
|
||||
break;
|
||||
|
||||
case CRT_PIX_FORMAT_RGBA:
|
||||
cL[0] = bb >> 16 & 0xff;
|
||||
cL[1] = bb >> 8 & 0xff;
|
||||
cL[2] = bb >> 0 & 0xff;
|
||||
cL[3] = 0xff;
|
||||
break;
|
||||
|
||||
cL += BPP;
|
||||
case CRT_PIX_FORMAT_BGR:
|
||||
cL[0] = bb >> 0 & 0xff;
|
||||
cL[1] = bb >> 8 & 0xff;
|
||||
cL[2] = bb >> 16 & 0xff;
|
||||
break;
|
||||
|
||||
case CRT_PIX_FORMAT_BGRA:
|
||||
cL[0] = bb >> 0 & 0xff;
|
||||
cL[1] = bb >> 8 & 0xff;
|
||||
cL[2] = bb >> 16 & 0xff;
|
||||
cL[3] = 0xff;
|
||||
break;
|
||||
|
||||
case CRT_PIX_FORMAT_ARGB:
|
||||
cL[0] = 0xff;
|
||||
cL[1] = bb >> 16 & 0xff;
|
||||
cL[2] = bb >> 8 & 0xff;
|
||||
cL[3] = bb >> 0 & 0xff;
|
||||
break;
|
||||
|
||||
case CRT_PIX_FORMAT_ABGR:
|
||||
cL[0] = 0xff;
|
||||
cL[1] = bb >> 0 & 0xff;
|
||||
cL[2] = bb >> 8 & 0xff;
|
||||
cL[3] = bb >> 16 & 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cL += bpp;
|
||||
}
|
||||
|
||||
/* duplicate extra lines */
|
||||
|
||||
@@ -26,16 +26,57 @@ extern "C" {
|
||||
#define CRT_MINOR 3
|
||||
#define CRT_PATCH 2
|
||||
|
||||
#include "crt_ntsc.h"
|
||||
|
||||
// frei0r always uses 4 bits per pixel so it is pointless for there to be any other possibilities
|
||||
#define BPP 4
|
||||
#define CRT_SYSTEM_NTSC 0 /* standard NTSC */
|
||||
#define CRT_SYSTEM_NES 1 /* decode 6 or 9-bit NES pixels */
|
||||
#define CRT_SYSTEM_PV1K 2 /* Casio PV-1000 */
|
||||
#define CRT_SYSTEM_SNES 3 /* SNES - uses RGB */
|
||||
#define CRT_SYSTEM_TEMP 4 /* template implementation */
|
||||
#define CRT_SYSTEM_NTSCVHS 5 /* standard NTSC VHS */
|
||||
#define CRT_SYSTEM_NESRGB 6 /* encode RGB image with NES artifacts */
|
||||
|
||||
/* the system to be compiled */
|
||||
#ifndef CRT_SYSTEM
|
||||
#define CRT_SYSTEM CRT_SYSTEM_NTSC
|
||||
#endif
|
||||
|
||||
#if (CRT_SYSTEM == CRT_SYSTEM_NES)
|
||||
#include "crt_nes.h"
|
||||
#elif (CRT_SYSTEM == CRT_SYSTEM_SNES)
|
||||
#include "crt_snes.h"
|
||||
#elif (CRT_SYSTEM == CRT_SYSTEM_NTSC)
|
||||
#include "crt_ntsc.h"
|
||||
#elif (CRT_SYSTEM == CRT_SYSTEM_PV1K)
|
||||
#include "crt_pv1k.h"
|
||||
#elif (CRT_SYSTEM == CRT_SYSTEM_TEMP)
|
||||
#include "crt_template.h"
|
||||
#elif (CRT_SYSTEM == CRT_SYSTEM_NTSCVHS)
|
||||
#include "crt_ntscvhs.h"
|
||||
#elif (CRT_SYSTEM == CRT_SYSTEM_NESRGB)
|
||||
#include "crt_nesrgb.h"
|
||||
#else
|
||||
#error No system defined
|
||||
#endif
|
||||
|
||||
/* NOTE: this library does not use the alpha channel at all */
|
||||
#define CRT_PIX_FORMAT_RGB 0 /* 3 bytes per pixel [R,G,B,R,G,B,R,G,B...] */
|
||||
#define CRT_PIX_FORMAT_BGR 1 /* 3 bytes per pixel [B,G,R,B,G,R,B,G,R...] */
|
||||
#define CRT_PIX_FORMAT_ARGB 2 /* 4 bytes per pixel [A,R,G,B,A,R,G,B...] */
|
||||
#define CRT_PIX_FORMAT_RGBA 3 /* 4 bytes per pixel [R,G,B,A,R,G,B,A...] */
|
||||
#define CRT_PIX_FORMAT_ABGR 4 /* 4 bytes per pixel [A,B,G,R,A,B,G,R...] */
|
||||
#define CRT_PIX_FORMAT_BGRA 5 /* 4 bytes per pixel [B,G,R,A,B,G,R,A...] */
|
||||
|
||||
/* do bloom emulation (side effect: makes screen have black borders) */
|
||||
#define CRT_DO_BLOOM 0 /* does not work for NES */
|
||||
#define CRT_DO_VSYNC 1 /* look for VSYNC */
|
||||
#define CRT_DO_HSYNC 1 /* look for HSYNC */
|
||||
|
||||
struct CRT {
|
||||
signed char analog[CRT_INPUT_SIZE];
|
||||
signed char inp[CRT_INPUT_SIZE]; /* CRT input, can be noisy */
|
||||
|
||||
int outw, outh; /* output width/height */
|
||||
int out_format; /* output pixel format (one of the CRT_PIX_FORMATs) */
|
||||
unsigned char *out; /* output image */
|
||||
|
||||
int hue, brightness, contrast, saturation; /* common monitor settings */
|
||||
@@ -44,11 +85,6 @@ struct CRT {
|
||||
int blend; /* blend new field onto previous image */
|
||||
unsigned v_fac; /* factor to stretch img vertically onto the output img */
|
||||
|
||||
// these options were previously #defined in crt_core.h
|
||||
int crt_do_vsync;
|
||||
int crt_do_hsync;
|
||||
int do_vhs_noise; /* 0 = no additional vhs noise, 1 = with additional vhs noise */
|
||||
|
||||
/* internal data */
|
||||
int ccf[CRT_CC_VPER][CRT_CC_SAMPLES]; /* faster color carrier convergence */
|
||||
int hsync, vsync; /* keep track of sync over frames */
|
||||
@@ -61,7 +97,7 @@ struct CRT {
|
||||
* f - format of the output image
|
||||
* out - pointer to output image data
|
||||
*/
|
||||
extern void crt_init(struct CRT *v, int w, int h, unsigned char *out);
|
||||
extern void crt_init(struct CRT *v, int w, int h, int f, unsigned char *out);
|
||||
|
||||
/* Updates the output image parameters
|
||||
* w - width of the output image
|
||||
@@ -69,7 +105,7 @@ extern void crt_init(struct CRT *v, int w, int h, unsigned char *out);
|
||||
* f - format of the output image
|
||||
* out - pointer to output image data
|
||||
*/
|
||||
extern void crt_resize(struct CRT *v, int w, int h, unsigned char *out);
|
||||
extern void crt_resize(struct CRT *v, int w, int h, int f, unsigned char *out);
|
||||
|
||||
/* Resets the CRT settings back to their defaults */
|
||||
extern void crt_reset(struct CRT *v);
|
||||
@@ -84,6 +120,14 @@ extern void crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s);
|
||||
*/
|
||||
extern void crt_demodulate(struct CRT *v, int noise);
|
||||
|
||||
/* Get the bytes per pixel for a certain CRT_PIX_FORMAT_
|
||||
*
|
||||
* format - the format to get the bytes per pixel for
|
||||
*
|
||||
* returns 0 if the specified format does not exist
|
||||
*/
|
||||
extern int crt_bpp4fmt(int format);
|
||||
|
||||
/*****************************************************************************/
|
||||
/*************************** FIXED POINT SIN/COS *****************************/
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "crt_core.h"
|
||||
|
||||
#if (CRT_SYSTEM == CRT_SYSTEM_NTSCVHS)
|
||||
#if (CRT_SYSTEM == CRT_SYSTEM_NTSC)
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -137,41 +137,29 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
int ccburst[CRT_CC_SAMPLES]; /* color phase for burst */
|
||||
int sn, cs, n, ph;
|
||||
int inv_phase = 0;
|
||||
int aberration = 0;
|
||||
int bpp;
|
||||
|
||||
if (!s->iirs_initialized) {
|
||||
int y_freq = Y_FREQ_OFF;
|
||||
int i_freq = I_FREQ_OFF;
|
||||
int q_freq = Q_FREQ_OFF;
|
||||
|
||||
switch(s->vhs_mode)
|
||||
{
|
||||
case VHS_OFF:
|
||||
break;
|
||||
case VHS_SP:
|
||||
y_freq = Y_FREQ_SP;
|
||||
i_freq = I_FREQ_SP;
|
||||
q_freq = Q_FREQ_SP;
|
||||
break;
|
||||
case VHS_LP:
|
||||
y_freq = Y_FREQ_LP;
|
||||
i_freq = I_FREQ_LP;
|
||||
q_freq = Q_FREQ_LP;
|
||||
break;
|
||||
case VHS_EP:
|
||||
y_freq = Y_FREQ_EP;
|
||||
i_freq = I_FREQ_EP;
|
||||
q_freq = Q_FREQ_EP;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
init_iir(&iirY, L_FREQ, y_freq);
|
||||
init_iir(&iirI, L_FREQ, i_freq);
|
||||
init_iir(&iirQ, L_FREQ, q_freq);
|
||||
init_iir(&iirY, L_FREQ, Y_FREQ);
|
||||
init_iir(&iirI, L_FREQ, I_FREQ);
|
||||
init_iir(&iirQ, L_FREQ, Q_FREQ);
|
||||
s->iirs_initialized = 1;
|
||||
}
|
||||
#if CRT_DO_BLOOM
|
||||
if (s->raw) {
|
||||
destw = s->w;
|
||||
desth = s->h;
|
||||
if (destw > ((AV_LEN * 55500) >> 16)) {
|
||||
destw = ((AV_LEN * 55500) >> 16);
|
||||
}
|
||||
if (desth > ((CRT_LINES * 63500) >> 16)) {
|
||||
desth = ((CRT_LINES * 63500) >> 16);
|
||||
}
|
||||
} else {
|
||||
destw = (AV_LEN * 55500) >> 16;
|
||||
desth = (CRT_LINES * 63500) >> 16;
|
||||
}
|
||||
#else
|
||||
if (s->raw) {
|
||||
destw = s->w;
|
||||
desth = s->h;
|
||||
@@ -182,7 +170,7 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
desth = ((CRT_LINES * 64500) >> 16);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
if (s->as_color) {
|
||||
for (x = 0; x < CRT_CC_SAMPLES; x++) {
|
||||
n = s->hue + x * (360 / CRT_CC_SAMPLES);
|
||||
@@ -199,6 +187,10 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
memset(ccmodQ, 0, sizeof(ccmodQ));
|
||||
}
|
||||
|
||||
bpp = crt_bpp4fmt(s->format);
|
||||
if (bpp == 0) {
|
||||
return; /* just to be safe */
|
||||
}
|
||||
xo = AV_BEG + s->xoffset + (AV_LEN - destw) / 2;
|
||||
yo = CRT_TOP + s->yoffset + (CRT_LINES - desth) / 2;
|
||||
|
||||
@@ -209,9 +201,7 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
|
||||
/* align signal */
|
||||
xo = (xo & ~3);
|
||||
if (s->do_aberration) {
|
||||
aberration = ((rand() % 12) - 8) + 14;
|
||||
}
|
||||
|
||||
for (n = 0; n < CRT_VRES; n++) {
|
||||
int t; /* time */
|
||||
signed char *line = &v->analog[n * CRT_HRES];
|
||||
@@ -238,13 +228,11 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
while (t < (offs[3] * CRT_HRES / 100)) line[t++] = BLANK_LEVEL;
|
||||
} else {
|
||||
int cb;
|
||||
if (n < (CRT_VRES - aberration)) {
|
||||
|
||||
/* video line */
|
||||
while (t < SYNC_BEG) line[t++] = BLANK_LEVEL; /* FP */
|
||||
while (t < BW_BEG) line[t++] = SYNC_LEVEL; /* SYNC */
|
||||
}
|
||||
while (t < AV_BEG) line[t++] = BLANK_LEVEL; /* BW + CB + BP */
|
||||
|
||||
if (n < CRT_TOP) {
|
||||
while (t < CRT_HRES) line[t++] = BLANK_LEVEL;
|
||||
}
|
||||
@@ -263,12 +251,6 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
}
|
||||
}
|
||||
|
||||
if(s->vhs_mode != VHS_OFF)
|
||||
{
|
||||
/* reset hsync every frame so only the bottom part is warped */
|
||||
v->hsync = 0;
|
||||
}
|
||||
|
||||
for (y = 0; y < desth; y++) {
|
||||
int field_offset;
|
||||
int sy;
|
||||
@@ -293,11 +275,34 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
int ire; /* composite signal */
|
||||
int xoff;
|
||||
|
||||
pix = s->data + ((((x * s->w) / destw) + sy) * BPP);
|
||||
pix = s->data + ((((x * s->w) / destw) + sy) * bpp);
|
||||
switch (s->format) {
|
||||
case CRT_PIX_FORMAT_RGB:
|
||||
case CRT_PIX_FORMAT_RGBA:
|
||||
rA = pix[0];
|
||||
gA = pix[1];
|
||||
bA = pix[2];
|
||||
|
||||
break;
|
||||
case CRT_PIX_FORMAT_BGR:
|
||||
case CRT_PIX_FORMAT_BGRA:
|
||||
rA = pix[2];
|
||||
gA = pix[1];
|
||||
bA = pix[0];
|
||||
break;
|
||||
case CRT_PIX_FORMAT_ARGB:
|
||||
rA = pix[1];
|
||||
gA = pix[2];
|
||||
bA = pix[3];
|
||||
break;
|
||||
case CRT_PIX_FORMAT_ABGR:
|
||||
rA = pix[3];
|
||||
gA = pix[2];
|
||||
bA = pix[1];
|
||||
break;
|
||||
default:
|
||||
rA = gA = bA = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* RGB to YIQ */
|
||||
fy = (19595 * rA + 38470 * gA + 7471 * bA) >> 14;
|
||||
@@ -319,15 +324,8 @@ crt_modulate(struct CRT *v, struct NTSC_SETTINGS *s)
|
||||
}
|
||||
for (n = 0; n < CRT_CC_VPER; n++) {
|
||||
for (x = 0; x < CRT_CC_SAMPLES; x++) {
|
||||
if(s->vhs_mode != VHS_OFF)
|
||||
{
|
||||
v->ccf[n][x] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
v->ccf[n][x] = iccf[x] << 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -8,17 +8,16 @@
|
||||
* Discord: https://discord.com/invite/hdYctSmyQJ
|
||||
*/
|
||||
/*****************************************************************************/
|
||||
#ifndef _CRT_NTSC_VHS_H_
|
||||
#define _CRT_NTSC_VHS_H_
|
||||
#ifndef _CRT_NTSC_H_
|
||||
#define _CRT_NTSC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* crt_ntscvhs.h
|
||||
/* crt_ntsc.h
|
||||
*
|
||||
* An interface to convert a digital image to an analog NTSC signal with VHS
|
||||
* quality and some optional signal aberration at the bottom.
|
||||
* An interface to convert a digital image to an analog NTSC signal.
|
||||
*
|
||||
*/
|
||||
/* 0 = vertical chroma (228 chroma clocks per line) */
|
||||
@@ -96,32 +95,11 @@ extern "C" {
|
||||
/* somewhere between 7 and 12 cycles */
|
||||
#define CB_CYCLES 10
|
||||
|
||||
#define VHS_OFF 0
|
||||
#define VHS_SP 1
|
||||
#define VHS_LP 2
|
||||
#define VHS_EP 3
|
||||
|
||||
#define VHS_MODE VHS_OFF
|
||||
|
||||
/* frequencies for bandlimiting */
|
||||
#define L_FREQ 1431818 /* full line */
|
||||
|
||||
#define Y_FREQ_OFF 420000 /* Luma (Y) 4.2 MHz of the 14.31818 MHz */
|
||||
#define I_FREQ_OFF 150000 /* Chroma (I) 1.5 MHz of the 14.31818 MHz */
|
||||
#define Q_FREQ_OFF 55000 /* Chroma (Q) 0.55 MHz of the 14.31818 MHz */
|
||||
|
||||
#define Y_FREQ_SP 300000 /* Luma (Y) 3.0 MHz of the 14.31818 MHz */
|
||||
#define I_FREQ_SP 62700 /* Chroma (I) 627 kHz of the 14.31818 MHz */
|
||||
#define Q_FREQ_SP 62700 /* Chroma (Q) 627 kHz of the 14.31818 MHz */
|
||||
|
||||
#define Y_FREQ_LP 240000 /* Luma (Y) 2.4 MHz of the 14.31818 MHz */
|
||||
#define I_FREQ_LP 40000 /* Chroma (I) 400 kHz of the 14.31818 MHz */
|
||||
#define Q_FREQ_LP 40000 /* Chroma (Q) 400 kHz of the 14.31818 MHz */
|
||||
|
||||
#define Y_FREQ_EP 200000 /* Luma (Y) 2.0 MHz of the 14.31818 MHz */
|
||||
#define I_FREQ_EP 37000 /* Chroma (I) 370 kHz of the 14.31818 MHz */
|
||||
#define Q_FREQ_EP 37000 /* Chroma (Q) 370 kHz of the 14.31818 MHz */
|
||||
|
||||
#define Y_FREQ 420000 /* Luma (Y) 4.2 MHz of the 14.31818 MHz */
|
||||
#define I_FREQ 150000 /* Chroma (I) 1.5 MHz of the 14.31818 MHz */
|
||||
#define Q_FREQ 55000 /* Chroma (Q) 0.55 MHz of the 14.31818 MHz */
|
||||
|
||||
/* IRE units (100 = 1.0V, -40 = 0.0V) */
|
||||
#define WHITE_LEVEL 100
|
||||
@@ -132,6 +110,7 @@ extern "C" {
|
||||
|
||||
struct NTSC_SETTINGS {
|
||||
const unsigned char *data; /* image data */
|
||||
int format; /* pix format (one of the CRT_PIX_FORMATs in crt_core.h) */
|
||||
int w, h; /* width and height of image */
|
||||
int raw; /* 0 = scale image to fit monitor, 1 = don't scale */
|
||||
int as_color; /* 0 = monochrome, 1 = full color */
|
||||
@@ -140,14 +119,6 @@ struct NTSC_SETTINGS {
|
||||
int hue; /* 0-359 */
|
||||
int xoffset; /* x offset in sample space. 0 is minimum value */
|
||||
int yoffset; /* y offset in # of lines. 0 is minimum value */
|
||||
int do_aberration; /* 0 = no aberration, 1 = with aberration */
|
||||
|
||||
// these are changed by the vhs mode
|
||||
int vhs_mode;
|
||||
int y_freq;
|
||||
int i_freq;
|
||||
int q_freq;
|
||||
|
||||
/* make sure your NTSC_SETTINGS struct is zeroed out before you do anything */
|
||||
int iirs_initialized; /* internal state */
|
||||
};
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "frei0r.h"
|
||||
#include "frei0r/math.h"
|
||||
|
||||
#include "crt_core.h"
|
||||
|
||||
// the actual NTSC emulation code is modified from here: https://github.com/LMP88959/NTSC-CRT
|
||||
// the actual NTSC emulation code is from here: https://github.com/LMP88959/NTSC-CRT
|
||||
|
||||
|
||||
typedef struct ntsc_instance
|
||||
{
|
||||
@@ -15,16 +17,15 @@ typedef struct ntsc_instance
|
||||
|
||||
// parameters
|
||||
struct CRT crt;
|
||||
struct NTSC_SETTINGS ntsc_settings;
|
||||
struct NTSC_SETTINGS ntsc;
|
||||
|
||||
int noise;
|
||||
double vhs_speed;
|
||||
|
||||
int field;
|
||||
int progressive;
|
||||
|
||||
} ntsc_instance_t;
|
||||
|
||||
|
||||
// these functions are for frei0r
|
||||
// mostly copy/paste/slightly modified from the other frei0r effects
|
||||
int f0r_init()
|
||||
@@ -44,8 +45,8 @@ void f0r_get_plugin_info(f0r_plugin_info_t* info)
|
||||
info->color_model = F0R_COLOR_MODEL_RGBA8888;
|
||||
info->frei0r_version = FREI0R_MAJOR_VERSION;
|
||||
info->major_version = 0;
|
||||
info->minor_version = 1;
|
||||
info->num_params = 8;
|
||||
info->minor_version = 2;
|
||||
info->num_params = 3;
|
||||
}
|
||||
|
||||
void f0r_get_param_info(f0r_param_info_t* info, int param_index)
|
||||
@@ -59,49 +60,20 @@ void f0r_get_param_info(f0r_param_info_t* info, int param_index)
|
||||
break;
|
||||
|
||||
case 1:
|
||||
info->name = "VHS Speed";
|
||||
info->explanation = "Simulates VHS. 0 = off, 1 = SP, 2 = LP, 3 = EP";
|
||||
info->type = F0R_PARAM_DOUBLE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
info->name = "VHS Noise";
|
||||
info->explanation = "Toggles VHS noise at the bottom of the screen";
|
||||
info->type = F0R_PARAM_BOOL;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
info->name = "Aberration";
|
||||
info->explanation = "Toggles VHS aberration at the bottom of the screen. Not visible if V-sync is on.";
|
||||
info->type = F0R_PARAM_BOOL;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
info->name = "Force V-sync";
|
||||
info->explanation = "Forces V-sync even when the signal is really noisy.";
|
||||
info->type = F0R_PARAM_BOOL;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
info->name = "Force H-sync";
|
||||
info->explanation = "Forces V-sync even when the signal is really noisy.";
|
||||
info->type = F0R_PARAM_BOOL;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
info->name = "Progressive Scan";
|
||||
info->explanation = "Toggles progressive scan (Interlaced if off).";
|
||||
info->type = F0R_PARAM_BOOL;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
info->name = "Blend";
|
||||
info->explanation = "Blends frames.";
|
||||
case 2:
|
||||
info->name = "Scanlines";
|
||||
info->explanation = "Draw borders between scanlines.";
|
||||
info->type = F0R_PARAM_BOOL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
|
||||
{
|
||||
ntsc_instance_t* inst = (ntsc_instance_t*)calloc(1, sizeof(*inst));
|
||||
@@ -109,35 +81,27 @@ f0r_instance_t f0r_construct(unsigned int width, unsigned int height)
|
||||
inst->width = width;
|
||||
inst->height = height;
|
||||
|
||||
inst->vhs_speed = 0.0;
|
||||
inst->field = 0;
|
||||
inst->progressive = 1;
|
||||
|
||||
crt_init(&(inst->crt), width, height, NULL);
|
||||
|
||||
// init NTSC_SETTINGS
|
||||
inst->ntsc_settings.data = NULL;
|
||||
inst->ntsc_settings.w = width;
|
||||
inst->ntsc_settings.h = height;
|
||||
inst->ntsc_settings.raw = 0;
|
||||
inst->ntsc_settings.as_color = 1;
|
||||
inst->ntsc_settings.field = 0;
|
||||
inst->ntsc_settings.frame = 0;
|
||||
inst->ntsc_settings.hue = 0;
|
||||
inst->ntsc_settings.xoffset = 0;
|
||||
inst->ntsc_settings.yoffset = 0;
|
||||
inst->ntsc_settings.do_aberration = 0;
|
||||
|
||||
// these are changed by the vhs mode
|
||||
inst->ntsc_settings.vhs_mode = 0;
|
||||
inst->ntsc_settings.y_freq = 0;
|
||||
inst->ntsc_settings.i_freq = 0;
|
||||
inst->ntsc_settings.q_freq = 0;
|
||||
|
||||
/* make sure your NTSC_SETTINGS struct is zeroed out before you do anything */
|
||||
inst->ntsc_settings.iirs_initialized = 0;
|
||||
inst->ntsc.format = CRT_PIX_FORMAT_RGBA;
|
||||
inst->ntsc.w = width;
|
||||
inst->ntsc.h = height;
|
||||
inst->ntsc.raw = 0;
|
||||
inst->ntsc.field = 0;
|
||||
inst->ntsc.frame = 0;
|
||||
inst->ntsc.as_color = 1;
|
||||
inst->ntsc.hue = 0;
|
||||
inst->ntsc.xoffset = 0;
|
||||
inst->ntsc.yoffset = 0;
|
||||
inst->ntsc.iirs_initialized = 0;
|
||||
|
||||
inst->noise = 0;
|
||||
inst->progressive = 0;
|
||||
inst->field = 0;
|
||||
|
||||
crt_init(&(inst->crt), width, height, CRT_PIX_FORMAT_RGBA, NULL);
|
||||
inst->crt.blend = 0;
|
||||
inst->crt.scanlines = 0;
|
||||
|
||||
|
||||
|
||||
return (f0r_instance_t)inst;
|
||||
}
|
||||
@@ -155,29 +119,13 @@ void f0r_set_param_value(f0r_instance_t instance, f0r_param_t param, int param_i
|
||||
switch(param_index)
|
||||
{
|
||||
case 0:
|
||||
inst->noise = *((double*)param) * 100;
|
||||
inst->noise = *((double*)param) * 200;
|
||||
break;
|
||||
case 1:
|
||||
inst->ntsc_settings.vhs_mode = (int)CLAMP(*((double*)param) * 4, 0, 4);
|
||||
inst->ntsc_settings.iirs_initialized = 0;
|
||||
break;
|
||||
case 2:
|
||||
inst->crt.do_vhs_noise = (*((double*)param) >= 0.5);
|
||||
break;
|
||||
case 3:
|
||||
inst->ntsc_settings.do_aberration = (*((double*)param) >= 0.5);
|
||||
break;
|
||||
case 4:
|
||||
inst->crt.crt_do_vsync = !(*((double*)param) >= 0.5);
|
||||
break;
|
||||
case 5:
|
||||
inst->crt.crt_do_hsync = !(*((double*)param) >= 0.5);
|
||||
break;
|
||||
case 6:
|
||||
inst->progressive = (*((double*)param) >= 0.5);
|
||||
break;
|
||||
case 7:
|
||||
inst->crt.blend = (*((double*)param) >= 0.5);
|
||||
case 2:
|
||||
inst->crt.scanlines = (*((double*)param) >= 0.5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -188,28 +136,13 @@ void f0r_get_param_value(f0r_instance_t instance, f0r_param_t param, int param_i
|
||||
switch(param_index)
|
||||
{
|
||||
case 0:
|
||||
*((double*)param) = (inst->noise / 100);
|
||||
*((double*)param) = (inst->noise / 200);
|
||||
break;
|
||||
case 1:
|
||||
*((double*)param) = (inst->ntsc_settings.vhs_mode / 4);
|
||||
break;
|
||||
case 2:
|
||||
*((double*)param) = (inst->crt.do_vhs_noise ? 1.0 : 0.0);
|
||||
break;
|
||||
case 3:
|
||||
*((double*)param) = (inst->ntsc_settings.do_aberration ? 1.0 : 0.0);
|
||||
break;
|
||||
case 4:
|
||||
*((double*)param) = !(inst->crt.crt_do_vsync ? 1.0 : 0.0);
|
||||
break;
|
||||
case 5:
|
||||
*((double*)param) = !(inst->crt.crt_do_hsync ? 1.0 : 0.0);
|
||||
break;
|
||||
case 6:
|
||||
*((double*)param) = (inst->progressive ? 1.0 : 0.0);
|
||||
break;
|
||||
case 7:
|
||||
*((double*)param) = (inst->crt.blend ? 1.0 : 0.0);
|
||||
case 2:
|
||||
*((double*)param) = (inst->crt.scanlines ? 1.0 : 0.0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -219,19 +152,36 @@ void f0r_update(f0r_instance_t instance, double time, const uint32_t* inframe, u
|
||||
{
|
||||
ntsc_instance_t* inst = (ntsc_instance_t*)instance;
|
||||
|
||||
// clear the output frame
|
||||
memset(outframe, 0, inst->width * inst->height * sizeof(uint32_t));
|
||||
inst->crt.blend = 0;
|
||||
|
||||
// set everything up for the simulation
|
||||
inst->crt.out = (char*)outframe;
|
||||
inst->ntsc_settings.data = (const char*)inframe;
|
||||
inst->ntsc.data = (const char*)inframe;
|
||||
|
||||
inst->ntsc_settings.field = inst->field & 1;
|
||||
if (inst->ntsc_settings.field == 0) {
|
||||
_render_field:
|
||||
inst->ntsc.field = inst->field & 1;
|
||||
|
||||
if (inst->ntsc.field == 0) {
|
||||
/* a frame is two fields */
|
||||
inst->ntsc_settings.frame ^= 1;
|
||||
inst->ntsc.frame ^= 1;
|
||||
}
|
||||
|
||||
crt_modulate(&(inst->crt), &(inst->ntsc_settings));
|
||||
// encode and decode ntsc signal
|
||||
crt_modulate(&(inst->crt), &(inst->ntsc));
|
||||
crt_demodulate(&(inst->crt), inst->noise);
|
||||
if(!inst->progressive)
|
||||
{
|
||||
|
||||
inst->field ^= 1;
|
||||
// if we are in progressive mode, we render both fields onto the frame.
|
||||
// in interlaced mode, we will hit the opposite field on the next frame.
|
||||
if(inst->field && inst->progressive)
|
||||
{
|
||||
// if we are not leaving scanlines blank, we will want to blend the frames in progressive mode
|
||||
if(!inst->crt.scanlines)
|
||||
{
|
||||
inst->crt.blend = 1;
|
||||
}
|
||||
goto _render_field;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user