-/* analogtv, Copyright (c) 2003, 2004 Trevor Blackwell <tlb@tlb.org>
+/* analogtv, Copyright (c) 2003-2018 Trevor Blackwell <tlb@tlb.org>
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
#ifndef _XSCREENSAVER_ANALOGTV_H
#define _XSCREENSAVER_ANALOGTV_H
+#include "thread_util.h"
#include "xshm.h"
+#if defined(USE_IPHONE) || defined(HAVE_ANDROID)
+# define HAVE_MOBILE
+#endif
+
/*
You'll need these to generate standard NTSC TV signals
*/
ANALOGTV_SIGNAL_LEN=ANALOGTV_V*ANALOGTV_H,
/* The number of intensity levels we deal with for gamma correction &c */
- ANALOGTV_CV_MAX=1024
+ ANALOGTV_CV_MAX=1024,
+
+ /* MAX_LINEHEIGHT corresponds to 2400 vertical pixels, beyond which
+ it interpolates extra black lines. */
+ ANALOGTV_MAX_LINEHEIGHT=12
+
};
typedef struct analogtv_input_s {
The rest of this should be considered mostly opaque to the analogtv module.
*/
+struct analogtv_yiq_s {
+ float y,i,q;
+} /*yiq[ANALOGTV_PIC_LEN+10] */;
+
typedef struct analogtv_s {
Display *dpy;
Screen *screen;
XWindowAttributes xgwa;
+ struct threadpool threads;
+
#if 0
unsigned int onscreen_signature[ANALOGTV_V];
#endif
int interlace;
int interlace_counter;
- double agclevel;
+ float agclevel;
/* If you change these, call analogtv_set_demod */
- double tint_control,color_control,brightness_control,contrast_control;
- double height_control, width_control, squish_control;
- double horiz_desync;
- double squeezebottom;
- double powerup;
+ float tint_control,color_control,brightness_control,contrast_control;
+ float height_control, width_control, squish_control;
+ float horiz_desync;
+ float squeezebottom;
+ float powerup;
/* internal cache */
int blur_mult;
int fakeit_scroll;
int redraw_all;
- int use_shm,use_cmap,use_color;
+ int use_cmap,use_color;
int bilevel_signal;
-#ifdef HAVE_XSHM_EXTENSION
XShmSegmentInfo shm_info;
-#endif
int visdepth,visclass,visbits;
- int red_invprec,red_shift,red_mask;
- int green_invprec,green_shift,green_mask;
- int blue_invprec,blue_shift,blue_mask;
+ int red_invprec, red_shift;
+ int green_invprec, green_shift;
+ int blue_invprec, blue_shift;
+ unsigned long red_mask, green_mask, blue_mask;
Colormap colormap;
int usewidth,useheight,xrepl,subwidth;
GC gc;
int screen_xo,screen_yo; /* centers image in window */
- void (*event_handler)(Display *dpy, XEvent *event);
- int (*key_handler)(Display *dpy, XEvent *event,void *key_data);
- void *key_data;
-
int flutter_horiz_desync;
int flutter_tint;
int hashnoise_enable;
int shrinkpulse;
- double crtload[ANALOGTV_V];
+ float crtload[ANALOGTV_V];
unsigned int red_values[ANALOGTV_CV_MAX];
unsigned int green_values[ANALOGTV_CV_MAX];
unsigned int blue_values[ANALOGTV_CV_MAX];
- struct analogtv_yiq_s {
- float y,i,q;
- } yiq[ANALOGTV_PIC_LEN+10];
-
unsigned long colors[256];
int cmap_y_levels;
int cmap_i_levels;
int cmap_q_levels;
+ float tint_i, tint_q;
+
int cur_hsync;
int line_hsync[ANALOGTV_V];
int cur_vsync;
int channel_change_cycles;
double rx_signal_level;
- double rx_signal[ANALOGTV_SIGNAL_LEN + 2*ANALOGTV_H];
+ float *rx_signal;
+
+ struct {
+ int index;
+ double value;
+ } leveltable[ANALOGTV_MAX_LINEHEIGHT+1][ANALOGTV_MAX_LINEHEIGHT+1];
+ /* Only valid during draw. */
+ unsigned random0, random1;
+ double noiselevel;
+ const analogtv_reception *const *recs;
+ unsigned rec_count;
+
+ float *signal_subtotals;
+
+ float puheight;
} analogtv;
int analogtv_set_demod(analogtv *it);
void analogtv_setup_frame(analogtv *it);
void analogtv_setup_sync(analogtv_input *input, int do_cb, int do_ssavi);
-void analogtv_draw(analogtv *it);
+void analogtv_draw(analogtv *it, double noiselevel,
+ const analogtv_reception *const *recs, unsigned rec_count);
-int analogtv_load_ximage(analogtv *it, analogtv_input *input, XImage *pic_im);
+int analogtv_load_ximage(analogtv *it, analogtv_input *input,
+ XImage *pic_im, XImage *mask_im,
+ int xoff, int yoff, int width, int height);
void analogtv_reception_update(analogtv_reception *inp);
-void analogtv_init_signal(analogtv *it, double noiselevel);
-void analogtv_add_signal(analogtv *it, analogtv_reception *rec);
-
void analogtv_setup_teletext(analogtv_input *input);
char *s, int x, int y, int ntsc[4]);
void analogtv_draw_string_centered(analogtv_input *input, analogtv_font *f,
char *s, int x, int y, int ntsc[4]);
-void analogtv_draw_xpm(analogtv *tv, analogtv_input *input,
- const char * const *xpm, int left, int top);
int analogtv_handle_events (analogtv *it);
#define ANALOGTV_DEFAULTS_SHM
#endif
+#ifndef HAVE_MOBILE
+# define ANALOGTV_DEF_BRIGHTNESS "2"
+# define ANALOGTV_DEF_CONTRAST "150"
+#else
+ /* Need to really crank this up for it to look good on the iPhone screen. */
+# define ANALOGTV_DEF_BRIGHTNESS "3"
+# define ANALOGTV_DEF_CONTRAST "400"
+#endif
+
+/* Brightness: useful range is around -75 to 100.
+ Contrast: useful range is around 0 - 500.
+ Color: useful range is around +/- 500.
+ Tint: range is mod 360.
+
+ The values in the 'analogtv' struct are the resource divided by 100.0,
+ except for tint, which is exact.
+ */
+
#define ANALOGTV_DEFAULTS \
"*TVColor: 70", \
"*TVTint: 5", \
- "*TVBrightness: 2", \
- "*TVContrast: 150",\
+ "*TVBrightness: " ANALOGTV_DEF_BRIGHTNESS, \
+ "*TVContrast: " ANALOGTV_DEF_CONTRAST, \
"*Background: Black", \
"*use_cmap: 0", \
"*geometry: 800x600", \
+ "*fpsSolid: True", \
+ "*lowrez: True", \
+ THREAD_DEFAULTS \
ANALOGTV_DEFAULTS_SHM
#define ANALOGTV_OPTIONS \
- { "-use-cmap", ".use_cmap", XrmoptionSepArg, 0 },
-
+ THREAD_OPTIONS \
+ { "-use-cmap", ".use_cmap", XrmoptionSepArg, 0 }, \
+ { "-tv-color", ".TVColor", XrmoptionSepArg, 0 }, \
+ { "-tv-tint", ".TVTint", XrmoptionSepArg, 0 }, \
+ { "-tv-brightness", ".TVBrightness", XrmoptionSepArg, 0 }, \
+ { "-tv-contrast", ".TVContrast", XrmoptionSepArg, 0 },
#endif /* _XSCREENSAVER_ANALOGTV_H */