1 /***************************************************************************
3 * ZXEmuT -- ZX Spectrum Emulator with Tcl scripting
5 * Copyright (C) 2012-2022 Ketmar Dark <ketmar@ketmar.no-ip.org>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 3 of the License ONLY.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **************************************************************************/
20 #ifndef ZXEMUT_VIDEO_H
21 #define ZXEMUT_VIDEO_H
34 ////////////////////////////////////////////////////////////////////////////////
36 MS_BUTTON_LEFT
= 0x01,
37 MS_BUTTON_RIGHT
= 0x02,
38 MS_BUTTON_MIDDLE
= 0x04,
39 MS_BUTTON_WHEELUP
= 0x10,
40 MS_BUTTON_WHEELDOWN
= 0x20,
42 MS_BUTTON_AUTO
= 0x80, // autogenerated mouse press
44 MS_BUTTON_MASK
= 0xff, // ignore 'depressed' flag for mouseButtonCB
45 MS_BUTTON_DEPRESSED
= 0x100,
49 typedef void (*FrameCB
) (void);
50 typedef void (*KeyCB
) (SDL_KeyboardEvent
*key
);
51 typedef void (*MouseCB
) (int x
, int y
, int xrel
, int yrel
, int buttons
);
52 typedef void (*MouseButtonCB
) (int x
, int y
, int button
, int buttons
);
53 typedef void (*WindowActivationCB
) (int activated
);
56 extern FrameCB frameCB
;
58 extern MouseCB mouseCB
;
59 extern MouseButtonCB mouseButtonCB
; // button: which button state was changed (possibly with MS_BUTTON_DEPRESSED)
60 extern WindowActivationCB windowActivationCB
;
61 // on deactivation, keyboard and mouse button handlers will be called for
62 // pressed control keys and mouse buttons before this callback
64 extern int msButtons
, msLastX
, msLastY
, kbCtrl
, kbAlt
, kbShift
;
65 extern int kbLCtrl
, kbRCtrl
, kbLAlt
, kbRAlt
, kbLShift
, kbRShift
;
66 extern int msAutoTimeMSFirst
; // mouse button autorepeat event time in milliseconds; <1: never
67 extern int msAutoTimeMSRepeat
; // mouse button autorepeat event time in milliseconds; <1: never
68 extern int msAutoTresholdX
, msAutoTresholdY
;
70 extern const uint8_t vid_font8x16
[4096];
71 extern const uint8_t vid_font8x8
[2048];
74 ////////////////////////////////////////////////////////////////////////////////
75 extern int optFullscreen
;
76 extern int optTVScaler
;
77 extern int vidScale
; // 1, 2, 3, 4; default is 3
78 extern SDL_Surface
*screen
; // always 32bpp
79 extern SDL_Surface
*screenReal
; // always 32bpp
80 extern Uint32 palette
[256]; // converted for frameSfc
81 extern unsigned paletteUsed
; // used colors in the palette
82 extern uint8_t palRGB
[256][4]; // [3] is unused
83 extern int vidRIdx
, vidGIdx
, vidBIdx
;
84 extern SDL_Surface
*frameSfc
; // current frame surface for FrameCB
94 extern int vid_scaler_type
;
96 extern int vidWindowActivated
;
98 extern int vidColorMode
; // 0: ok; 1: b/w; 2: green
100 // if set, this is called after real screen was built
101 // can be used to render various fullscreen things
102 // use *ONLY* `sfc` to render things
103 // note that surface is properly locked here
104 extern void (*vidBeforeFlipCB
) (SDL_Surface
*sfc
);
106 typedef struct __attribute__((packed
)) {
108 uint8_t attr
; // low 4 bits:fg; high 4 bits:bg
111 #define VID_TEXT_WIDTH (80)
112 #define VID_TEXT_HEIGHT (30)
114 extern VidTChar vid_textscr
[VID_TEXT_WIDTH
*VID_TEXT_HEIGHT
];
115 extern int vid_textscr_active
;
116 extern int vid_textsrc_height
; // <= 0: full
119 extern void vt_cls (uint8_t ch
, uint8_t attr
);
120 extern void vt_writechar (int x
, int y
, uint8_t ch
, uint8_t attr
);
121 extern void vt_writechars (int x
, int y
, int count
, uint8_t ch
, uint8_t attr
);
122 extern void vt_writestrz (int x
, int y
, const char *s
, uint8_t attr
);
123 extern void vt_writestrcnt (int x
, int y
, const char *s
, size_t slen
, uint8_t attr
);
125 extern void vt_writeattr (int x
, int y
, uint8_t attr
);
126 extern void vt_writeattrs (int x
, int y
, int count
, uint8_t attr
);
128 extern void vt_draw_shadow (int x
, int y
, int w
, int h
);
130 #define VID_FRAME_SINGLE (0x00U)
131 #define VID_FRAME_DOUBLE (0x01U)
132 #define VID_FRAME_OVERWRITE (0x80U)
134 extern void vt_draw_frame (int x
, int y
, int w
, int h
, uint8_t attr
, unsigned flags
);
143 uint8_t clr_frame
, clr_win
, clr_prompt
;
144 uint8_t clr_item
, clr_cursor
; // for text view, headers and normal text
151 // copies all data to dynamic memory!
152 extern void vt_smm_init (vt_simple_menu
*menu
, const char *prompt
, const char *items
[]);
153 // simple text viewer; headers starts with "\x01"
154 extern void vt_smm_init_textview (vt_simple_menu
*menu
, const char *prompt
, const char *items
[]);
155 // releases all data, don't forget to call it!
156 extern void vt_smm_deinit (vt_simple_menu
*menu
);
158 extern void vt_smm_draw (vt_simple_menu
*menu
);
160 // `vt_smm_draw()` will automatically call this
161 // but `vt_smm_process_key()` will not
162 extern void vt_smm_ensure_cursor_visible (vt_simple_menu
*menu
);
164 #define VID_SMM_ESCAPE (-1)
165 #define VID_SMM_NOTMINE (0)
166 #define VID_SMM_EATEN (1)
167 #define VID_SMM_SELECTED (2)
169 // return VID_SMM_xxx
170 extern int vt_smm_process_key (vt_simple_menu
*menu
, SDL_KeyboardEvent
*key
);
173 ////////////////////////////////////////////////////////////////////////////////
181 extern int timerInit (void); // return TIMER_XXX
182 extern int timerReinit (void); // reset timer; <0: error
183 extern int64_t timerGetMS (void); // milliseconds
184 extern int64_t timerGetMicroSeconds (void); // microseconds
187 ////////////////////////////////////////////////////////////////////////////////
188 extern void sdlInit (void);
189 extern void initVideo (void);
190 extern void switchFullScreen (void);
191 extern void updateScale (void);
193 extern void rebuildPalette (void);
195 extern uint8_t zxPalette
[];
198 ////////////////////////////////////////////////////////////////////////////////
200 static inline void putPixel (int x
, int y
, Uint8 col
) {
201 if (frameSfc
!= NULL
&& col
!= 255 && x
>= 0 && y
>= 0 && x
< frameSfc
->w
&& y
< frameSfc
->h
) {
202 *(Uint32
*)(((Uint8
*)frameSfc
->pixels
)+(y
*frameSfc
->pitch
)+x
*4) = palette
[col
];
207 static inline void putPixelMix (int x
, int y
, Uint8 col0
, Uint8 col1
) {
208 if (frameSfc
!= NULL
&& x
>= 0 && y
>= 0 && x
< frameSfc
->w
&& y
< frameSfc
->h
) {
209 Uint8
*d
= (((Uint8
*)frameSfc
->pixels
)+(y
*frameSfc
->pitch
)+x
*4);
210 Uint32 r
= palRGB
[col0
][0], g
= palRGB
[col0
][1], b
= palRGB
[col0
][2];
212 d
[vidRIdx
] = (palRGB
[col1
][0]+r
)/2;
213 d
[vidGIdx
] = (palRGB
[col1
][1]+g
)/2;
214 d
[vidBIdx
] = (palRGB
[col1
][2]+b
)/2;
219 ////////////////////////////////////////////////////////////////////////////////
226 extern void lockSurface (SurfaceLock
*lock
, SDL_Surface
*s
);
227 extern void unlockSurface (SurfaceLock
*lock
);
229 extern void clearScreen (Uint8 col
);
232 ////////////////////////////////////////////////////////////////////////////////
233 // surface must be locked!
234 extern void drawChar6 (char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
235 extern void drawStr6 (const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
236 extern void drawChar8 (char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
237 extern void drawStr8 (const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
238 extern void drawStr6Outline (const char *str
, int x
, int y
, Uint8 fg
, Uint8 oc
);
239 extern void drawStr8Outline (const char *str
, int x
, int y
, Uint8 fg
, Uint8 oc
);
241 extern int drawCharZ (char ch
, int x
, int y
, Uint8 c1
, Uint8 c2
);
242 extern int drawStrZ (const char *str
, int x
, int y
, Uint8 c1
, Uint8 c2
);
245 ////////////////////////////////////////////////////////////////////////////////
246 // forcedShowFrame() can be called from FrameCB to force showing the current frame
247 // ugly name means that you shouldn't use it
248 // video module will not show the frame by itself if forcedShowFrame() was called
249 extern void forcedShowFrame (void);
251 extern void buildFrame (void);
252 extern int processEvents (int dowait
);
253 extern void mainLoop (void);
254 extern void postQuitMessage (void);
257 ////////////////////////////////////////////////////////////////////////////////
264 extern VOverlay
*createVO (int w
, int h
);
265 extern void resizeVO (VOverlay
*v
, int w
, int h
);
266 extern void freeVO (VOverlay
*v
);
268 extern void clearVO (VOverlay
*v
, Uint8 c
);
270 extern void drawChar6VO (VOverlay
*v
, char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
271 extern void drawStr6VO (VOverlay
*v
, const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
272 extern void drawChar8VO (VOverlay
*v
, char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
273 extern void drawStr8VO (VOverlay
*v
, const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
275 extern void drawFrameVO (VOverlay
*v
, int x0
, int y0
, int w
, int h
, Uint8 c
);
276 extern void fillRectVO (VOverlay
*v
, int x0
, int y0
, int w
, int h
, Uint8 c
);
278 extern void blitVO (VOverlay
*v
, int x0
, int y0
, Uint8 alpha
);
281 extern VOverlay
*createVOFromIcon (const void *iconbuf
);
284 static inline void putPixelVO (VOverlay
*v
, int x
, int y
, Uint8 c
) {
285 if (v
!= NULL
&& x
>= 0 && y
>= 0 && x
< v
->w
&& y
< v
->h
&& c
!= 255) v
->data
[y
*v
->w
+x
] = c
;
289 // dynamically allocate rgb colors
290 extern void vidResetPalette (void);
291 extern uint8_t vidAllocColor (int r
, int g
, int b
);
294 ////////////////////////////////////////////////////////////////////////////////
295 // rectangle that *includes* right and bottom edges
297 int vClipX0
, vClipY0
;
298 int vClipX1
, vClipY1
;
309 ////////////////////////////////////////////////////////////////////////////////
310 static inline void vPutPixel (const VExSurface
*sfc
, int x
, int y
, Uint8 clr
) {
311 if (sfc
!= NULL
&& sfc
->vo
!= NULL
) {
312 x
+= sfc
->clip
.vOfsX
;
313 y
+= sfc
->clip
.vOfsY
;
314 if (x
>= sfc
->clip
.vClipX0
&& y
>= sfc
->clip
.vClipY0
&&
315 x
<= sfc
->clip
.vClipX1
&& y
<= sfc
->clip
.vClipY1
) putPixelVO(sfc
->vo
, x
, y
, clr
);
320 ////////////////////////////////////////////////////////////////////////////////
321 static inline void vResetClip (VExSurface
*sfc
) {
323 sfc
->clip
.vClipX0
= sfc
->clip
.vClipY0
= 0;
324 sfc
->clip
.vClipX1
= sfc
->vo
->w
-1;
325 sfc
->clip
.vClipY1
= sfc
->vo
->h
-1;
326 sfc
->clip
.vOfsX
= sfc
->clip
.vOfsY
= 0;
331 static inline void vSetClip (VExSurface
*sfc
, int x
, int y
, int w
, int h
, int ox
, int oy
) {
335 sfc
->clip
.vClipX0
= x
;
336 sfc
->clip
.vClipY0
= y
;
337 sfc
->clip
.vClipX1
= x
+w
-1;
338 sfc
->clip
.vClipY1
= y
+h
-1;
339 sfc
->clip
.vOfsX
= ox
;
340 sfc
->clip
.vOfsY
= oy
;
345 static inline void vSaveClip (const VExSurface
*sfc
, VClipInfo
*ci
) {
346 if (sfc
!= NULL
&& ci
!= NULL
) *ci
= sfc
->clip
;
350 static inline void vRestoreClip (VExSurface
*sfc
, const VClipInfo
*ci
) {
351 if (sfc
!= NULL
&& ci
!= NULL
) sfc
->clip
= *ci
;
355 static inline void vRestrictClip (VExSurface
*sfc
, int x
, int y
, int w
, int h
) {
357 if (w
< 1 || h
< 1 || x
> sfc
->clip
.vClipX1
|| y
> sfc
->clip
.vClipY1
) {
358 sfc
->clip
.vClipX1
= sfc
->clip
.vClipX0
-1;
359 sfc
->clip
.vClipY1
= sfc
->clip
.vClipY0
-1;
361 if (sfc
->clip
.vClipX0
< x
) sfc
->clip
.vClipX0
= x
;
362 if (sfc
->clip
.vClipY0
< y
) sfc
->clip
.vClipY0
= y
;
365 if (sfc
->clip
.vClipX1
> x
) sfc
->clip
.vClipX1
= x
;
366 if (sfc
->clip
.vClipY1
> y
) sfc
->clip
.vClipY1
= y
;
372 static inline void vChangeClip (VExSurface
*sfc
, int dhor
, int dvert
) {
374 sfc
->clip
.vClipX0
+= dhor
;
375 sfc
->clip
.vClipY0
+= dvert
;
376 sfc
->clip
.vClipX1
-= dhor
;
377 sfc
->clip
.vClipY1
-= dvert
;
382 ////////////////////////////////////////////////////////////////////////////////
383 extern int vLineCountMaxLen (const char *str
, int *maxlenp
);
385 extern void vDrawChar (VExSurface
*sfc
, int x
, int y
, char ch
, Uint8 ink
, Uint8 paper
);
386 extern void vDrawText (VExSurface
*sfc
, int x
, int y
, const char *str
, Uint8 ink
, Uint8 paper
);
387 extern void vDrawOutlineText (VExSurface
*sfc
, int x
, int y
, const char *str
, Uint8 ink
, int oink
);
389 ////////////////////////////////////////////////////////////////////////////////
390 extern void vDrawHLine (VExSurface
*sfc
, int x
, int y
, int len
, Uint8 clr
);
391 extern void vDrawVLine (VExSurface
*sfc
, int x
, int y
, int len
, Uint8 clr
);
392 extern void vDrawBar (VExSurface
*sfc
, int x
, int y
, int width
, int height
, Uint8 clr
);
393 extern void vDrawRect (VExSurface
*sfc
, int x
, int y
, int width
, int height
, Uint8 clr
);
394 extern void vDrawRectW (VExSurface
*sfc
, int x
, int y
, int width
, int height
, Uint8 clr
);
396 ////////////////////////////////////////////////////////////////////////////////
397 extern void vDrawZXStripe (VExSurface
*sfc
, int x
, int y
, int dim
);
400 ZXVIDWF_STRIPES
= 0x01,
401 ZXVIDWF_STRIPES_DIM
= 0x02, // dim colors
404 extern void vDrawWindow (VExSurface
*sfc
, int x
, int y
, int width
, int height
, const char *title
,
405 int tink
, int tpaper
, int wpaper
, int flags
);
407 ////////////////////////////////////////////////////////////////////////////////
408 extern void vDrawUpArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
409 extern void vDrawDownArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
410 extern void vDrawLeftArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
411 extern void vDrawRightArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
413 ////////////////////////////////////////////////////////////////////////////////
414 extern void vDrawLine (VExSurface
*sfc
, int x0
, int y0
, int x1
, int y1
, Uint8 clr
);
415 extern void vDrawCircle (VExSurface
*sfc
, int cx
, int cy
, int radius
, Uint8 clr
);
416 extern void vDrawEllipse (VExSurface
*sfc
, int x0
, int y0
, int x1
, int y1
, Uint8 clr
);
417 extern void vDrawFilledCircle (VExSurface
*sfc
, int cx
, int cy
, int radius
, Uint8 clr
);
418 extern void vDrawFilledEllipse (VExSurface
*sfc
, int x0
, int y0
, int x1
, int y1
, Uint8 clr
);
420 ////////////////////////////////////////////////////////////////////////////////
421 extern void vDrawSelectionRect (VExSurface
*sfc
, int phase
, int x0
, int y0
, int wdt
, int hgt
, Uint8 col0
, Uint8 col1
);
424 ////////////////////////////////////////////////////////////////////////////////
425 // there are many predefined cursors...
427 AID_DEFAULT
= -1, // AID_COOKE
440 extern Uint8 msCurClr0
, msCurClr1
;
442 extern void drawMouseCursor (int x
, int y
, int id
);