emu: added small help window to memview (M-F1)
[zymosis.git] / src / ZXEmuT / libvideo / video.h
blob54039fd2c017f71ed8dcb82bb0ca3a678d297e67
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
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdint.h>
26 #include <stddef.h>
27 #include <SDL.h>
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
34 ////////////////////////////////////////////////////////////////////////////////
35 enum {
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;
57 extern KeyCB keyCB;
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 enum {
87 VID_SCALER_NONE,
88 VID_SCALER_nX,
89 VID_SCALER_HQX,
91 VID_SCALER_MAX,
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)) {
107 uint8_t ch;
108 uint8_t attr; // low 4 bits:fg; high 4 bits:bg
109 } VidTChar;
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);
137 typedef struct {
138 int x, y;
139 int w, h;
140 int cursor_y;
141 int page_top;
142 int textview;
143 uint8_t clr_frame, clr_win, clr_prompt;
144 uint8_t clr_item, clr_cursor; // for text view, headers and normal text
145 char *prompt;
146 char **items;
147 uint32_t item_count;
148 } vt_simple_menu;
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 ////////////////////////////////////////////////////////////////////////////////
174 enum {
175 TIMER_ERROR = -1,
176 TIMER_HPET = 0,
177 TIMER_OTHER = 1
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 ////////////////////////////////////////////////////////////////////////////////
199 // NO LOCKING!
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 ////////////////////////////////////////////////////////////////////////////////
220 typedef struct {
221 SDL_Surface *s;
222 int needUnlock;
223 } SurfaceLock;
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 ////////////////////////////////////////////////////////////////////////////////
258 typedef struct {
259 int w, h;
260 uint8_t *data;
261 } VOverlay;
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
296 typedef struct {
297 int vClipX0, vClipY0;
298 int vClipX1, vClipY1;
299 int vOfsX, vOfsY;
300 } VClipInfo;
303 typedef struct {
304 VOverlay *vo;
305 VClipInfo clip;
306 } VExSurface;
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) {
322 if (sfc != NULL) {
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) {
332 if (sfc != NULL) {
333 if (w < 0) w = 0;
334 if (h < 0) h = 0;
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) {
356 if (sfc != NULL) {
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;
360 } else {
361 if (sfc->clip.vClipX0 < x) sfc->clip.vClipX0 = x;
362 if (sfc->clip.vClipY0 < y) sfc->clip.vClipY0 = y;
363 x += w-1;
364 y += h-1;
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) {
373 if (sfc != NULL) {
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);
399 enum {
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...
426 enum {
427 AID_DEFAULT = -1, // AID_COOKE
428 AID_BIG = 0,
429 AID_LESSER,
430 AID_UGLY,
431 AID_UGLYIER,
432 AID_TINY_BGE,
433 AID_COOKE,
434 AID_ARTSTUDIO,
435 AID_SMALL_BYTEX,
436 AID_UGLY_EXCESS,
437 AID_EMPTY
440 extern Uint8 msCurClr0, msCurClr1;
442 extern void drawMouseCursor (int x, int y, int id);
445 #ifdef __cplusplus
447 #endif
448 #endif