OSDN Git Service

Merge branch 'master' of github.com:Artanejp/common_source_project-fm7
[csp-qt/common_source_project-fm7.git] / source / src / win32 / osd.h
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2015.11.20-
6
7         [ win32 dependent ]
8 */
9
10 #ifndef _WIN32_OSD_H_
11 #define _WIN32_OSD_H_
12
13 #ifndef _WIN32_WINNT
14 #define _WIN32_WINNT            0x500
15 #endif
16 #define DIRECTSOUND_VERSION     0x900
17 #define DIRECT3D_VERSION        0x900
18 // XXX: if your DirectX 9.0 SDK is newer and does not contain dinput.lib,
19 // please change the definition of DIRECTINPUT_VERSION from 0x500 to 0x800
20 #define DIRECTINPUT_VERSION     0x500
21 //#define DIRECTINPUT_VERSION   0x800
22
23 #include <windows.h>
24 #include <windowsx.h>
25 #include <mmsystem.h>
26 #include <process.h>
27 #include <commctrl.h>
28 #include <wingdi.h>
29 #include <gdiplus.h>
30 #include <d3d9.h>
31 #include <d3dx9.h>
32 #include <d3d9types.h>
33 #include <vfw.h>
34 #include <dsound.h>
35 #include <dinput.h>
36 #include "../vm/vm.h"
37 //#include "../emu.h"
38 #include "../common.h"
39 #include "../config.h"
40
41 #ifdef USE_ZLIB
42 // relative path from *.vcproj/*.vcxproj, not from this directory :-(
43         #if defined(_MSC_VER) && (_MSC_VER >= 1800)
44                 #ifdef _DEBUG
45                         #pragma comment(lib, "../src/zlib-1.2.11/vc++2013/debug/zlibstat.lib")
46                 #else
47                         #pragma comment(lib, "../src/zlib-1.2.11/vc++2013/release/zlibstat.lib")
48                 #endif
49         #else
50                 #ifdef _DEBUG
51                         #pragma comment(lib, "../src/zlib-1.2.11/vc++2008/debug/zlibstat.lib")
52                 #else
53                         #pragma comment(lib, "../src/zlib-1.2.11/vc++2008/release/zlibstat.lib")
54                 #endif
55         #endif
56 #endif
57
58 #ifdef USE_SOCKET
59 #include <winsock.h>
60 #pragma comment(lib, "wsock32.lib")
61 #endif
62 #pragma comment(lib, "comctl32.lib")
63 #pragma comment(lib, "msimg32.lib")
64 #pragma comment(lib, "gdiplus.lib")
65 using namespace Gdiplus;
66 #pragma comment(lib, "d3d9.lib")
67 #pragma comment(lib, "d3dx9.lib")
68 #pragma comment(lib, "vfw32.lib")
69 #pragma comment(lib, "dsound.lib")
70 #if DIRECTINPUT_VERSION >= 0x0800
71 #pragma comment(lib, "dinput8.lib")
72 #else
73 #pragma comment(lib, "dinput.lib")
74 #endif
75 #pragma comment(lib, "dxguid.lib")
76
77 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
78 #pragma comment(lib, "strmiids.lib")
79 #include <dshow.h>
80 //#include <qedit.h>
81 EXTERN_C const CLSID CLSID_SampleGrabber;
82 EXTERN_C const CLSID CLSID_NullRenderer;
83 EXTERN_C const IID IID_ISampleGrabberCB;
84 MIDL_INTERFACE("0579154A-2B53-4994-B0D0-E773148EFF85")
85 ISampleGrabberCB : public IUnknown {
86 public:
87         virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
88         virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
89 };
90 EXTERN_C const IID IID_ISampleGrabber;
91 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
92 ISampleGrabber : public IUnknown {
93 public:
94         virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot) = 0;
95         virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType) = 0;
96         virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType) = 0;
97         virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem) = 0;
98         virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( /* [out][in] */ long *pBufferSize,/* [out] */ long *pBuffer) = 0;
99         virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( /* [retval][out] */ IMediaSample **ppSample) = 0;
100         virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback,long WhichMethodToCallback) = 0;
101 };
102 #endif
103 #ifdef USE_MOVIE_PLAYER
104 class CMySampleGrabberCB : public ISampleGrabberCB {
105 private:
106         VM *vm;
107 public:
108         CMySampleGrabberCB(VM *vm_ptr)
109         {
110                 vm = vm_ptr;
111         }
112         STDMETHODIMP_(ULONG) AddRef()
113         {
114                 return 2;
115         }
116         STDMETHODIMP_(ULONG) Release()
117         {
118                 return 1;
119         }
120         STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
121         {
122                 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
123                         *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
124                         return NOERROR;
125                 }
126                 return E_NOINTERFACE;
127         }
128         STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
129         {
130                 return S_OK;
131         }
132         STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
133         {
134                 vm->movie_sound_callback(pBuffer, lBufferSize);
135                 return S_OK;
136         }
137 };
138 #endif
139
140 #define WM_RESIZE  (WM_USER + 1)
141 #define WM_SOCKET0 (WM_USER + 2)
142 #define WM_SOCKET1 (WM_USER + 3)
143 #define WM_SOCKET2 (WM_USER + 4)
144 #define WM_SOCKET3 (WM_USER + 5)
145
146 #ifdef USE_SOCKET
147 #define SOCKET_MAX 4
148 #define SOCKET_BUFFER_MAX 0x100000
149 #endif
150
151 #ifdef USE_VIDEO_CAPTURE
152 #define MAX_CAPTURE_DEVS 8
153 #endif
154
155 #define SUPPORT_WIN32_DLL
156
157 #define SCREEN_FILTER_NONE      0
158 #define SCREEN_FILTER_RGB       1
159 #define SCREEN_FILTER_RF        2
160
161 // check memory leaks
162 #ifdef _DEBUG
163 // _malloca is defined in typeinfo.h
164 #ifdef _malloca
165 #undef _malloca
166 #endif
167 #define _CRTDBG_MAP_ALLOC
168 #include <crtdbg.h>
169 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
170 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
171 #endif
172
173 typedef struct bitmap_s {
174         // common
175         inline bool initialized()
176         {
177                 return (hdcDib != NULL);
178         }
179         inline scrntype_t* get_buffer(int y)
180         {
181                 return lpBmp + width * (height - y - 1);
182         }
183         int width, height;
184         // win32 dependent
185         HDC hdcDib;
186         HBITMAP hBmp, hOldBmp;
187         LPBYTE lpBuf;
188         scrntype_t* lpBmp;
189         LPBITMAPINFO lpDib;
190 } bitmap_t;
191
192 typedef struct font_s {
193         // common
194         inline bool initialized()
195         {
196                 return (hFont != NULL);
197         }
198         _TCHAR family[64];
199         int width, height, rotate;
200         bool bold, italic;
201         // win32 dependent
202         HFONT hFont;
203 } font_t;
204
205 typedef struct pen_s {
206         // common
207         inline bool initialized()
208         {
209                 return (hPen != NULL);
210         }
211         int width;
212         uint8_t r, g, b;
213         // win32 dependent
214         HPEN hPen;
215 } pen_t;
216
217 typedef struct {
218         PAVISTREAM pAVICompressed;
219         scrntype_t* lpBmp;
220         LPBITMAPINFOHEADER pbmInfoHeader;
221         DWORD dwAVIFileSize;
222         LONG lAVIFrames;
223         int frames;
224         int result;
225 } rec_video_thread_param_t;
226
227 class FIFO;
228 class FILEIO;
229
230 class OSD
231 {
232 private:
233         int lock_count;
234         
235         // console
236         HANDLE hStdIn, hStdOut;
237         
238         // input
239         void initialize_input();
240         void release_input();
241         
242 #if DIRECTINPUT_VERSION >= 0x0800
243         LPDIRECTINPUT8 lpdi;
244         LPDIRECTINPUTDEVICE8 lpdikey;
245 //      LPDIRECTINPUTDEVICE8 lpdijoy;
246 #else
247         LPDIRECTINPUT lpdi;
248         LPDIRECTINPUTDEVICE lpdikey;
249 //      LPDIRECTINPUTDEVICE lpdijoy;
250 #endif
251         bool dinput_key_available;
252 //      bool dinput_joy_available;
253         
254         uint8_t keycode_conv[256];
255         uint8_t key_status[256];        // windows key code mapping
256         uint8_t key_dik_prev[256];
257 #ifdef USE_SHIFT_NUMPAD_KEY
258         bool key_shift_pressed, key_shift_released;
259 #endif
260         bool key_caps_locked;
261         bool lost_focus;
262         
263 #ifdef USE_JOYSTICK
264         uint32_t joy_status[4];         // joystick #1-#4 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
265         int joy_num;
266         uint32_t joy_mask[4];
267 #endif
268         
269 #ifdef USE_MOUSE
270         int32_t mouse_status[3];        // x, y, button (b0 = left, b1 = right)
271         bool mouse_enabled;
272 #endif
273         
274         // screen
275         void initialize_screen();
276         void release_screen();
277         void initialize_screen_buffer(bitmap_t *buffer, int width, int height, int mode);
278         void release_screen_buffer(bitmap_t *buffer);
279 #ifdef USE_SCREEN_FILTER
280         void apply_rgb_filter_to_screen_buffer(bitmap_t *source, bitmap_t *dest);
281         void apply_rgb_filter_x3_y3(bitmap_t *source, bitmap_t *dest);
282         void apply_rgb_filter_x3_y2(bitmap_t *source, bitmap_t *dest);
283         void apply_rgb_filter_x2_y3(bitmap_t *source, bitmap_t *dest);
284         void apply_rgb_filter_x2_y2(bitmap_t *source, bitmap_t *dest);
285         void apply_rgb_filter_x1_y1(bitmap_t *source, bitmap_t *dest);
286 #endif
287 //#ifdef USE_SCREEN_ROTATE
288         void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
289 //#endif
290         void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
291         bool initialize_d3d9();
292         bool initialize_d3d9_surface(bitmap_t *buffer);
293         void release_d3d9();
294         void release_d3d9_surface();
295         void copy_to_d3d9_surface(bitmap_t *buffer);
296         int add_video_frames();
297         
298         bitmap_t vm_screen_buffer;
299 #ifdef USE_SCREEN_FILTER
300         bitmap_t filtered_screen_buffer;
301         bitmap_t tmp_filtered_screen_buffer;
302 #endif
303 //#ifdef USE_SCREEN_ROTATE
304         bitmap_t rotated_screen_buffer;
305 //#endif
306         bitmap_t stretched_screen_buffer;
307         bitmap_t shrinked_screen_buffer;
308         bitmap_t video_screen_buffer;
309         
310         bitmap_t* draw_screen_buffer;
311         
312         int host_window_width, host_window_height;
313         bool host_window_mode;
314         int vm_screen_width, vm_screen_height;
315         int vm_window_width, vm_window_height;
316         int vm_window_width_aspect, vm_window_height_aspect;
317         int draw_screen_width, draw_screen_height;
318         
319         Gdiplus::GdiplusStartupInput gdiSI;
320         ULONG_PTR gdiToken;
321         
322         LPDIRECT3D9 lpd3d9;
323         LPDIRECT3DDEVICE9 lpd3d9Device;
324         LPDIRECT3DSURFACE9 lpd3d9Surface;
325         LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
326         
327         _TCHAR video_file_path[_MAX_PATH];
328         int rec_video_fps;
329         double rec_video_run_frames;
330         double rec_video_frames;
331         
332         LPBITMAPINFO lpDibRec;
333         PAVIFILE pAVIFile;
334         PAVISTREAM pAVIStream;
335         PAVISTREAM pAVICompressed;
336         AVICOMPRESSOPTIONS AVIOpts;
337         DWORD dwAVIFileSize;
338         LONG lAVIFrames;
339         HANDLE hVideoThread;
340         rec_video_thread_param_t rec_video_thread_param;
341         
342         bool first_draw_screen;
343         bool first_invalidate;
344         bool self_invalidate;
345         
346         // sound
347         void initialize_sound(int rate, int samples);
348         void release_sound();
349         
350         int sound_rate, sound_samples;
351         bool sound_available, sound_started, sound_muted;
352         
353         LPDIRECTSOUND lpds;
354         LPDIRECTSOUNDBUFFER lpdsPrimaryBuffer, lpdsSecondaryBuffer;
355         bool sound_first_half;
356         
357         _TCHAR sound_file_path[_MAX_PATH];
358         FILEIO* rec_sound_fio;
359         int rec_sound_bytes;
360         int rec_sound_buffer_ptr;
361         
362         // video device
363 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
364         void initialize_video();
365         void release_video();
366         
367         IGraphBuilder *pGraphBuilder;
368         IBaseFilter *pVideoBaseFilter;
369         IBaseFilter *pCaptureBaseFilter;
370         ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
371         ISampleGrabber *pVideoSampleGrabber;
372         IBaseFilter *pSoundBaseFilter;
373         ISampleGrabber *pSoundSampleGrabber;
374         CMySampleGrabberCB *pSoundCallBack;
375         IMediaControl *pMediaControl;
376         IMediaSeeking *pMediaSeeking;
377         IMediaPosition *pMediaPosition;
378         IVideoWindow *pVideoWindow;
379         IBasicVideo *pBasicVideo;
380         IBasicAudio *pBasicAudio;
381         bool bTimeFormatFrame;
382         bool bVerticalReversed;
383         
384         bitmap_t direct_show_screen_buffer;
385         bitmap_t direct_show_stretch_buffer;
386         int direct_show_width, direct_show_height;
387         bool direct_show_mute[2];
388 #endif
389 #ifdef USE_MOVIE_PLAYER
390         double movie_frame_rate;
391         int movie_sound_rate;
392 #endif
393 #ifdef USE_VIDEO_CAPTURE
394         void enum_capture_devs();
395         bool connect_capture_dev(int index, bool pin);
396         int cur_capture_dev_index;
397         int num_capture_devs;
398         _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
399 #endif
400         
401         // socket
402 #ifdef USE_SOCKET
403         void initialize_socket();
404         void release_socket();
405         
406         int soc[SOCKET_MAX];
407         bool is_tcp[SOCKET_MAX];
408         struct sockaddr_in udpaddr[SOCKET_MAX];
409         int socket_delay[SOCKET_MAX];
410         char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
411         int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
412 #endif
413         
414 public:
415         OSD()
416         {
417                 lock_count = 0;
418         }
419         ~OSD() {}
420         
421         // common
422         VM* vm;
423         
424         void initialize(int rate, int samples);
425         void release();
426         void power_off();
427         void suspend();
428         void restore();
429         void lock_vm();
430         void unlock_vm();
431         bool is_vm_locked()
432         {
433                 return (lock_count != 0);
434         }
435         void force_unlock_vm();
436         void sleep(uint32_t ms);
437         
438         // common console
439         void open_console(const _TCHAR* title);
440         void close_console();
441         unsigned int get_console_code_page();
442         bool is_console_active();
443         void set_console_text_attribute(unsigned short attr);
444         void write_console(_TCHAR* buffer, unsigned int length);
445         int read_console_input(_TCHAR* buffer, unsigned int length);
446         bool is_console_key_pressed(int vk);
447         void close_debugger_console();
448         
449         // common input
450         void update_input();
451         void key_down(int code, bool extended, bool repeat);
452         void key_up(int code, bool extended);
453         void key_down_native(int code, bool repeat);
454         void key_up_native(int code);
455         void key_lost_focus()
456         {
457                 lost_focus = true;
458         }
459 #ifdef USE_MOUSE
460         void enable_mouse();
461         void disable_mouse();
462         void toggle_mouse();
463         bool is_mouse_enabled()
464         {
465                 return mouse_enabled;
466         }
467 #endif
468         uint8_t* get_key_buffer()
469         {
470                 return key_status;
471         }
472 #ifdef USE_JOYSTICK
473         uint32_t* get_joy_buffer()
474         {
475                 return joy_status;
476         }
477 #endif
478 #ifdef USE_MOUSE
479         int32_t* get_mouse_buffer()
480         {
481                 return mouse_status;
482         }
483 #endif
484 #ifdef USE_AUTO_KEY
485         bool now_auto_key;
486 #endif
487         
488         // common screen
489         int get_window_mode_width(int mode);
490         int get_window_mode_height(int mode);
491         void set_host_window_size(int window_width, int window_height, bool window_mode);
492         void set_vm_screen_size(int screen_width, int screen_height, int window_width, int window_height, int window_width_aspect, int window_height_aspect);
493         void set_vm_screen_lines(int lines);
494         int get_vm_window_width()
495         {
496                 return vm_window_width;
497         }
498         int get_vm_window_height()
499         {
500                 return vm_window_height;
501         }
502         int get_vm_window_width_aspect()
503         {
504                 return vm_window_width_aspect;
505         }
506         int get_vm_window_height_aspect()
507         {
508                 return vm_window_height_aspect;
509         }
510         scrntype_t* get_vm_screen_buffer(int y);
511         int draw_screen();
512 #ifdef ONE_BOARD_MICRO_COMPUTER
513         void reload_bitmap()
514         {
515                 first_invalidate = true;
516         }
517 #endif
518         void capture_screen();
519         bool start_record_video(int fps);
520         void stop_record_video();
521         void restart_record_video();
522         void add_extra_frames(int extra_frames);
523         bool now_record_video;
524 #ifdef USE_SCREEN_FILTER
525         bool screen_skip_line;
526 #endif
527         
528         // common sound
529         void update_sound(int* extra_frames);
530         void mute_sound();
531         void stop_sound();
532         void start_record_sound();
533         void stop_record_sound();
534         void restart_record_sound();
535         bool now_record_sound;
536         
537         // common video device
538 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
539         void get_video_buffer();
540         void mute_video_dev(bool l, bool r);
541 #endif
542 #ifdef USE_MOVIE_PLAYER
543         bool open_movie_file(const _TCHAR* file_path);
544         void close_movie_file();
545         void play_movie();
546         void stop_movie();
547         void pause_movie();
548         double get_movie_frame_rate()
549         {
550                 return movie_frame_rate;
551         }
552         int get_movie_sound_rate()
553         {
554                 return movie_sound_rate;
555         }
556         void set_cur_movie_frame(int frame, bool relative);
557         uint32_t get_cur_movie_frame();
558         bool now_movie_play, now_movie_pause;
559 #endif
560 #ifdef USE_VIDEO_CAPTURE
561         int get_cur_capture_dev_index()
562         {
563                 return cur_capture_dev_index;
564         }
565         int get_num_capture_devs()
566         {
567                 return num_capture_devs;
568         }
569         _TCHAR* get_capture_dev_name(int index)
570         {
571                 return capture_dev_name[index];
572         }
573         void open_capture_dev(int index, bool pin);
574         void close_capture_dev();
575         void show_capture_dev_filter();
576         void show_capture_dev_pin();
577         void show_capture_dev_source();
578         void set_capture_dev_channel(int ch);
579 #endif
580         
581         // common printer
582 #ifdef USE_PRINTER
583         void create_bitmap(bitmap_t *bitmap, int width, int height);
584         void release_bitmap(bitmap_t *bitmap);
585         void create_font(font_t *font, const _TCHAR *family, int width, int height, int rotate, bool bold, bool italic);
586         void release_font(font_t *font);
587         void create_pen(pen_t *pen, int width, uint8_t r, uint8_t g, uint8_t b);
588         void release_pen(pen_t *pen);
589         void clear_bitmap(bitmap_t *bitmap, uint8_t r, uint8_t g, uint8_t b);
590         int get_text_width(bitmap_t *bitmap, font_t *font, const char *text);
591         void draw_text_to_bitmap(bitmap_t *bitmap, font_t *font, int x, int y, const char *text, uint8_t r, uint8_t g, uint8_t b);
592         void draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen, int sx, int sy, int ex, int ey);
593         void draw_rectangle_to_bitmap(bitmap_t *bitmap, int x, int y, int width, int height, uint8_t r, uint8_t g, uint8_t b);
594         void draw_point_to_bitmap(bitmap_t *bitmap, int x, int y, uint8_t r, uint8_t g, uint8_t b);
595         void stretch_bitmap(bitmap_t *dest, int dest_x, int dest_y, int dest_width, int dest_height, bitmap_t *source, int source_x, int source_y, int source_width, int source_height);
596 #endif
597         void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
598         
599         // common socket
600 #ifdef USE_SOCKET
601         int get_socket(int ch)
602         {
603                 return soc[ch];
604         }
605         void notify_socket_connected(int ch);
606         void notify_socket_disconnected(int ch);
607         void update_socket();
608         bool initialize_socket_tcp(int ch);
609         bool initialize_socket_udp(int ch);
610         bool connect_socket(int ch, uint32_t ipaddr, int port);
611         void disconnect_socket(int ch);
612         bool listen_socket(int ch);
613         void send_socket_data_tcp(int ch);
614         void send_socket_data_udp(int ch, uint32_t ipaddr, int port);
615         void send_socket_data(int ch);
616         void recv_socket_data(int ch);
617 #endif
618         
619         // win32 dependent
620         void invalidate_screen();
621         void update_screen(HDC hdc);
622         HWND main_window_handle;
623         HINSTANCE instance_handle;
624         bool vista_or_later;
625 };
626
627 #endif