OSDN Git Service

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