1 /***************************************************************************
3 * ZXEmuT -- ZX Spectrum Emulator with Tcl scripting
5 * Copyright (C) 2012-2020 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
86 extern int vidWindowActivated
;
88 extern int vidColorMode
; // 0: ok; 1: b/w; 2: green
90 // if set, this is called after real screen was built
91 // can be used to render various fullscreen things
92 // use *ONLY* `sfc` to render things
93 // note that surface is properly locked here
94 extern void (*vidBeforeFlipCB
) (SDL_Surface
*sfc
);
96 typedef struct __attribute__((packed
)) {
98 uint8_t attr
; // low 4 bits:fg; high 4 bits:bg
101 #define VID_TEXT_WIDTH (80)
102 #define VID_TEXT_HEIGHT (30)
104 extern VidTChar vid_textscr
[VID_TEXT_WIDTH
*VID_TEXT_HEIGHT
];
105 extern int vid_textscr_active
;
106 extern int vid_textsrc_height
; // <= 0: full
109 extern void vt_cls (uint8_t ch
, uint8_t attr
);
110 extern void vt_writechar (int x
, int y
, uint8_t ch
, uint8_t attr
);
111 extern void vt_writechars (int x
, int y
, int count
, uint8_t ch
, uint8_t attr
);
112 extern void vt_writestrz (int x
, int y
, const char *s
, uint8_t attr
);
113 extern void vt_writestrcnt (int x
, int y
, const char *s
, size_t slen
, uint8_t attr
);
116 ////////////////////////////////////////////////////////////////////////////////
124 extern int timerInit (void); // return TIMER_XXX
125 extern int timerReinit (void); // reset timer; <0: error
126 extern int64_t timerGetMS (void); // milliseconds
127 extern int64_t timerGetMicroSeconds (void); // microseconds
130 ////////////////////////////////////////////////////////////////////////////////
131 extern void sdlInit (void);
132 extern void initVideo (void);
133 extern void switchFullScreen (void);
134 extern void updateScale (void);
136 extern void rebuildPalette (void);
138 extern uint8_t zxPalette
[];
141 ////////////////////////////////////////////////////////////////////////////////
143 static inline void putPixel (int x
, int y
, Uint8 col
) {
144 if (frameSfc
!= NULL
&& col
!= 255 && x
>= 0 && y
>= 0 && x
< frameSfc
->w
&& y
< frameSfc
->h
) {
145 *(Uint32
*)(((Uint8
*)frameSfc
->pixels
)+(y
*frameSfc
->pitch
)+x
*4) = palette
[col
];
150 static inline void putPixelMix (int x
, int y
, Uint8 col0
, Uint8 col1
) {
151 if (frameSfc
!= NULL
&& x
>= 0 && y
>= 0 && x
< frameSfc
->w
&& y
< frameSfc
->h
) {
152 Uint8
*d
= (((Uint8
*)frameSfc
->pixels
)+(y
*frameSfc
->pitch
)+x
*4);
153 Uint32 r
= palRGB
[col0
][0], g
= palRGB
[col0
][1], b
= palRGB
[col0
][2];
155 d
[vidRIdx
] = (palRGB
[col1
][0]+r
)/2;
156 d
[vidGIdx
] = (palRGB
[col1
][1]+g
)/2;
157 d
[vidBIdx
] = (palRGB
[col1
][2]+b
)/2;
162 ////////////////////////////////////////////////////////////////////////////////
169 extern void lockSurface (SurfaceLock
*lock
, SDL_Surface
*s
);
170 extern void unlockSurface (SurfaceLock
*lock
);
172 extern void clearScreen (Uint8 col
);
175 ////////////////////////////////////////////////////////////////////////////////
176 // surface must be locked!
177 extern void drawChar6 (char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
178 extern void drawStr6 (const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
179 extern void drawChar8 (char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
180 extern void drawStr8 (const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
181 extern void drawStr6Outline (const char *str
, int x
, int y
, Uint8 fg
, Uint8 oc
);
182 extern void drawStr8Outline (const char *str
, int x
, int y
, Uint8 fg
, Uint8 oc
);
184 extern int drawCharZ (char ch
, int x
, int y
, Uint8 c1
, Uint8 c2
);
185 extern int drawStrZ (const char *str
, int x
, int y
, Uint8 c1
, Uint8 c2
);
188 ////////////////////////////////////////////////////////////////////////////////
189 // forcedShowFrame() can be called from FrameCB to force showing the current frame
190 // ugly name means that you shouldn't use it
191 // video module will not show the frame by itself if forcedShowFrame() was called
192 extern void forcedShowFrame (void);
194 extern void buildFrame (void);
195 extern int processEvents (int dowait
);
196 extern void mainLoop (void);
197 extern void postQuitMessage (void);
200 ////////////////////////////////////////////////////////////////////////////////
207 extern VOverlay
*createVO (int w
, int h
);
208 extern void resizeVO (VOverlay
*v
, int w
, int h
);
209 extern void freeVO (VOverlay
*v
);
211 extern void clearVO (VOverlay
*v
, Uint8 c
);
213 extern void drawChar6VO (VOverlay
*v
, char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
214 extern void drawStr6VO (VOverlay
*v
, const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
215 extern void drawChar8VO (VOverlay
*v
, char ch
, int x
, int y
, Uint8 fg
, Uint8 bg
);
216 extern void drawStr8VO (VOverlay
*v
, const char *str
, int x
, int y
, Uint8 fg
, Uint8 bg
);
218 extern void drawFrameVO (VOverlay
*v
, int x0
, int y0
, int w
, int h
, Uint8 c
);
219 extern void fillRectVO (VOverlay
*v
, int x0
, int y0
, int w
, int h
, Uint8 c
);
221 extern void blitVO (VOverlay
*v
, int x0
, int y0
, Uint8 alpha
);
224 extern VOverlay
*createVOFromIcon (const void *iconbuf
);
227 static inline void putPixelVO (VOverlay
*v
, int x
, int y
, Uint8 c
) {
228 if (v
!= NULL
&& x
>= 0 && y
>= 0 && x
< v
->w
&& y
< v
->h
&& c
!= 255) v
->data
[y
*v
->w
+x
] = c
;
232 // dynamically allocate rgb colors
233 extern void vidResetPalette (void);
234 extern uint8_t vidAllocColor (int r
, int g
, int b
);
237 ////////////////////////////////////////////////////////////////////////////////
238 // rectangle that *includes* right and bottom edges
240 int vClipX0
, vClipY0
;
241 int vClipX1
, vClipY1
;
252 ////////////////////////////////////////////////////////////////////////////////
253 static inline void vPutPixel (const VExSurface
*sfc
, int x
, int y
, Uint8 clr
) {
254 if (sfc
!= NULL
&& sfc
->vo
!= NULL
) {
255 x
+= sfc
->clip
.vOfsX
;
256 y
+= sfc
->clip
.vOfsY
;
257 if (x
>= sfc
->clip
.vClipX0
&& y
>= sfc
->clip
.vClipY0
&&
258 x
<= sfc
->clip
.vClipX1
&& y
<= sfc
->clip
.vClipY1
) putPixelVO(sfc
->vo
, x
, y
, clr
);
263 ////////////////////////////////////////////////////////////////////////////////
264 static inline void vResetClip (VExSurface
*sfc
) {
266 sfc
->clip
.vClipX0
= sfc
->clip
.vClipY0
= 0;
267 sfc
->clip
.vClipX1
= sfc
->vo
->w
-1;
268 sfc
->clip
.vClipY1
= sfc
->vo
->h
-1;
269 sfc
->clip
.vOfsX
= sfc
->clip
.vOfsY
= 0;
274 static inline void vSetClip (VExSurface
*sfc
, int x
, int y
, int w
, int h
, int ox
, int oy
) {
278 sfc
->clip
.vClipX0
= x
;
279 sfc
->clip
.vClipY0
= y
;
280 sfc
->clip
.vClipX1
= x
+w
-1;
281 sfc
->clip
.vClipY1
= y
+h
-1;
282 sfc
->clip
.vOfsX
= ox
;
283 sfc
->clip
.vOfsY
= oy
;
288 static inline void vSaveClip (const VExSurface
*sfc
, VClipInfo
*ci
) {
289 if (sfc
!= NULL
&& ci
!= NULL
) *ci
= sfc
->clip
;
293 static inline void vRestoreClip (VExSurface
*sfc
, const VClipInfo
*ci
) {
294 if (sfc
!= NULL
&& ci
!= NULL
) sfc
->clip
= *ci
;
298 static inline void vRestrictClip (VExSurface
*sfc
, int x
, int y
, int w
, int h
) {
300 if (w
< 1 || h
< 1 || x
> sfc
->clip
.vClipX1
|| y
> sfc
->clip
.vClipY1
) {
301 sfc
->clip
.vClipX1
= sfc
->clip
.vClipX0
-1;
302 sfc
->clip
.vClipY1
= sfc
->clip
.vClipY0
-1;
304 if (sfc
->clip
.vClipX0
< x
) sfc
->clip
.vClipX0
= x
;
305 if (sfc
->clip
.vClipY0
< y
) sfc
->clip
.vClipY0
= y
;
308 if (sfc
->clip
.vClipX1
> x
) sfc
->clip
.vClipX1
= x
;
309 if (sfc
->clip
.vClipY1
> y
) sfc
->clip
.vClipY1
= y
;
315 static inline void vChangeClip (VExSurface
*sfc
, int dhor
, int dvert
) {
317 sfc
->clip
.vClipX0
+= dhor
;
318 sfc
->clip
.vClipY0
+= dvert
;
319 sfc
->clip
.vClipX1
-= dhor
;
320 sfc
->clip
.vClipY1
-= dvert
;
325 ////////////////////////////////////////////////////////////////////////////////
326 extern int vLineCountMaxLen (const char *str
, int *maxlenp
);
328 extern void vDrawChar (VExSurface
*sfc
, int x
, int y
, char ch
, Uint8 ink
, Uint8 paper
);
329 extern void vDrawText (VExSurface
*sfc
, int x
, int y
, const char *str
, Uint8 ink
, Uint8 paper
);
330 extern void vDrawOutlineText (VExSurface
*sfc
, int x
, int y
, const char *str
, Uint8 ink
, int oink
);
332 ////////////////////////////////////////////////////////////////////////////////
333 extern void vDrawHLine (VExSurface
*sfc
, int x
, int y
, int len
, Uint8 clr
);
334 extern void vDrawVLine (VExSurface
*sfc
, int x
, int y
, int len
, Uint8 clr
);
335 extern void vDrawBar (VExSurface
*sfc
, int x
, int y
, int width
, int height
, Uint8 clr
);
336 extern void vDrawRect (VExSurface
*sfc
, int x
, int y
, int width
, int height
, Uint8 clr
);
337 extern void vDrawRectW (VExSurface
*sfc
, int x
, int y
, int width
, int height
, Uint8 clr
);
339 ////////////////////////////////////////////////////////////////////////////////
340 extern void vDrawZXStripe (VExSurface
*sfc
, int x
, int y
, int dim
);
343 ZXVIDWF_STRIPES
= 0x01,
344 ZXVIDWF_STRIPES_DIM
= 0x02, // dim colors
347 extern void vDrawWindow (VExSurface
*sfc
, int x
, int y
, int width
, int height
, const char *title
,
348 int tink
, int tpaper
, int wpaper
, int flags
);
350 ////////////////////////////////////////////////////////////////////////////////
351 extern void vDrawUpArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
352 extern void vDrawDownArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
353 extern void vDrawLeftArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
354 extern void vDrawRightArrow (VExSurface
*sfc
, int x
, int y
, Uint8 ink
, Uint8 paper
);
356 ////////////////////////////////////////////////////////////////////////////////
357 extern void vDrawLine (VExSurface
*sfc
, int x0
, int y0
, int x1
, int y1
, Uint8 clr
);
358 extern void vDrawCircle (VExSurface
*sfc
, int cx
, int cy
, int radius
, Uint8 clr
);
359 extern void vDrawEllipse (VExSurface
*sfc
, int x0
, int y0
, int x1
, int y1
, Uint8 clr
);
360 extern void vDrawFilledCircle (VExSurface
*sfc
, int cx
, int cy
, int radius
, Uint8 clr
);
361 extern void vDrawFilledEllipse (VExSurface
*sfc
, int x0
, int y0
, int x1
, int y1
, Uint8 clr
);
363 ////////////////////////////////////////////////////////////////////////////////
364 extern void vDrawSelectionRect (VExSurface
*sfc
, int phase
, int x0
, int y0
, int wdt
, int hgt
, Uint8 col0
, Uint8 col1
);
367 ////////////////////////////////////////////////////////////////////////////////
368 // there are many predefined cursors...
370 AID_DEFAULT
= -1, // AID_COOKE
383 extern Uint8 msCurClr0
, msCurClr1
;
385 extern void drawMouseCursor (int x
, int y
, int id
);