OSDN Git Service

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