OSDN Git Service

[VM][General][Qt] Merge upstream 2015-12-31.
[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         void key_down_sub(int code, bool repeat);
202         void key_up_sub(int code);
203         
204         LPDIRECTINPUT lpdi;
205         LPDIRECTINPUTDEVICE lpdikey;
206 //      LPDIRECTINPUTDEVICE lpdijoy;
207         bool dinput_key_ok;
208 //      bool dinput_joy_ok;
209         
210         uint8 keycode_conv[256];
211         uint8 key_status[256];  // windows key code mapping
212         uint8 key_dik_prev[256];
213 #ifdef USE_SHIFT_NUMPAD_KEY
214         uint8 key_converted[256];
215         bool key_shift_pressed, key_shift_released;
216 #endif
217         bool lost_focus;
218         
219         uint32 joy_status[2];   // joystick #1, #2 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
220         int joy_num;
221         uint32 joy_mask[2];
222         
223         int mouse_status[3];    // x, y, button (b0 = left, b1 = right)
224         bool mouse_enabled;
225         
226 #ifdef USE_AUTO_KEY
227         FIFO* autokey_buffer;
228         int autokey_phase, autokey_shift;
229         int autokey_table[256];
230 #endif
231         
232         // screen
233         void initialize_screen();
234         void release_screen();
235         void initialize_screen_buffer(bitmap_t *buffer, int width, int height, int mode);
236         void release_screen_buffer(bitmap_t *buffer);
237 #ifdef USE_CRT_FILTER
238         void apply_crt_fileter_to_screen_buffer(bitmap_t *source, bitmap_t *dest);
239         void apply_crt_filter_x3_y3(bitmap_t *source, bitmap_t *dest);
240         void apply_crt_filter_x3_y2(bitmap_t *source, bitmap_t *dest);
241         void apply_crt_filter_x2_y3(bitmap_t *source, bitmap_t *dest);
242         void apply_crt_filter_x2_y2(bitmap_t *source, bitmap_t *dest);
243         void apply_crt_filter_x1_y1(bitmap_t *source, bitmap_t *dest);
244 #endif
245 #ifdef USE_SCREEN_ROTATE
246         void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
247 #endif
248         void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
249         bool initialize_d3d9();
250         bool initialize_d3d9_surface(bitmap_t *buffer);
251         void release_d3d9();
252         void release_d3d9_surface();
253         void copy_to_d3d9_surface(bitmap_t *buffer);
254         int add_video_frames();
255         
256         bitmap_t vm_screen_buffer;
257 #ifdef USE_CRT_FILTER
258         bitmap_t filtered_screen_buffer;
259         bitmap_t tmp_filtered_screen_buffer;
260 #endif
261 #ifdef USE_SCREEN_ROTATE
262         bitmap_t rotated_screen_buffer;
263 #endif
264         bitmap_t stretched_screen_buffer;
265         bitmap_t shrinked_screen_buffer;
266         bitmap_t video_screen_buffer;
267         
268         bitmap_t* draw_screen_buffer;
269         
270         int host_window_width, host_window_height;
271         bool host_window_mode;
272         int base_window_width, base_window_height;
273         int vm_screen_width, vm_screen_height, vm_screen_width_aspect, vm_screen_height_aspect;
274         int draw_screen_width, draw_screen_height;
275         
276         Gdiplus::GdiplusStartupInput gdiSI;
277         ULONG_PTR gdiToken;
278         
279         LPDIRECT3D9 lpd3d9;
280         LPDIRECT3DDEVICE9 lpd3d9Device;
281         LPDIRECT3DSURFACE9 lpd3d9Surface;
282         LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
283         
284         _TCHAR video_file_path[_MAX_PATH];
285         int rec_video_fps;
286         double rec_video_run_frames;
287         double rec_video_frames;
288         
289         LPBITMAPINFO lpDibRec;
290         PAVIFILE pAVIFile;
291         PAVISTREAM pAVIStream;
292         PAVISTREAM pAVICompressed;
293         AVICOMPRESSOPTIONS AVIOpts;
294         DWORD dwAVIFileSize;
295         LONG lAVIFrames;
296         HANDLE hVideoThread;
297         rec_video_thread_param_t rec_video_thread_param;
298         
299         bool first_draw_screen;
300         bool first_invalidate;
301         bool self_invalidate;
302         
303         // sound
304         void initialize_sound(int rate, int samples);
305         void release_sound();
306         
307         int sound_rate, sound_samples;
308         bool sound_ok, sound_started, now_mute;
309         
310         LPDIRECTSOUND lpds;
311         LPDIRECTSOUNDBUFFER lpdsPrimaryBuffer, lpdsSecondaryBuffer;
312         bool sound_first_half;
313         
314         _TCHAR sound_file_path[_MAX_PATH];
315         FILEIO* rec_sound_fio;
316         int rec_sound_bytes;
317         int rec_sound_buffer_ptr;
318         
319         // video device
320 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
321         void initialize_video();
322         void release_video();
323         
324         IGraphBuilder *pGraphBuilder;
325         IBaseFilter *pVideoBaseFilter;
326         IBaseFilter *pCaptureBaseFilter;
327         ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
328         ISampleGrabber *pVideoSampleGrabber;
329         IBaseFilter *pSoundBaseFilter;
330         ISampleGrabber *pSoundSampleGrabber;
331         CMySampleGrabberCB *pSoundCallBack;
332         IMediaControl *pMediaControl;
333         IMediaSeeking *pMediaSeeking;
334         IMediaPosition *pMediaPosition;
335         IVideoWindow *pVideoWindow;
336         IBasicVideo *pBasicVideo;
337         IBasicAudio *pBasicAudio;
338         bool bTimeFormatFrame;
339         bool bVerticalReversed;
340         
341         bitmap_t dshow_screen_buffer;
342         int direct_show_width, direct_show_height;
343         bool direct_show_mute[2];
344 #endif
345 #ifdef USE_MOVIE_PLAYER
346         double movie_frame_rate;
347         int movie_sound_rate;
348 #endif
349 #ifdef USE_VIDEO_CAPTURE
350         void enum_capture_devs();
351         bool connect_capture_dev(int index, bool pin);
352         int cur_capture_dev_index;
353         int num_capture_devs;
354         _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
355 #endif
356         
357         // socket
358 #ifdef USE_SOCKET
359         void initialize_socket();
360         void release_socket();
361         
362         int soc[SOCKET_MAX];
363         bool is_tcp[SOCKET_MAX];
364         struct sockaddr_in udpaddr[SOCKET_MAX];
365         int socket_delay[SOCKET_MAX];
366         char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
367         int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
368 #endif
369         
370 public:
371         OSD()
372         {
373                 lock_count = 0;
374         }
375         ~OSD() {}
376         
377         // common
378         VM* vm;
379         
380         void initialize(int rate, int samples);
381         void release();
382         void power_off();
383         void suspend();
384         void restore();
385         void lock_vm();
386         void unlock_vm();
387         void force_unlock_vm();
388         void sleep(uint32 ms);
389         
390         // common console
391         void open_console(_TCHAR* title);
392         void close_console();
393         unsigned int get_console_code_page();
394         bool is_console_active();
395         void set_console_text_attribute(unsigned short attr);
396         void write_console(_TCHAR* buffer, unsigned int length);
397         int read_console_input(_TCHAR* buffer);
398         
399         // common input
400         void update_input();
401         void key_down(int code, bool repeat);
402         void key_up(int code);
403         void key_lost_focus()
404         {
405                 lost_focus = true;
406         }
407 #ifdef ONE_BOARD_MICRO_COMPUTER
408         void press_button(int num);
409 #endif
410         void enable_mouse();
411         void disenable_mouse();
412         void toggle_mouse();
413         bool get_mouse_enabled()
414         {
415                 return mouse_enabled;
416         }
417 #ifdef USE_AUTO_KEY
418         void start_auto_key();
419         void stop_auto_key();
420         bool now_auto_key()
421         {
422                 return (autokey_phase != 0);
423         }
424 #endif
425         uint8* key_buffer()
426         {
427                 return key_status;
428         }
429         uint32* joy_buffer()
430         {
431                 return joy_status;
432         }
433         int* mouse_buffer()
434         {
435                 return mouse_status;
436         }
437         
438         // common screen
439         int get_window_width(int mode);
440         int get_window_height(int mode);
441         void set_window_size(int window_width, int window_height, bool window_mode);
442         void set_vm_screen_size(int width, int height, int width_aspect, int height_aspect, int window_width, int window_height);
443         scrntype* get_vm_screen_buffer(int y);
444         int draw_screen();
445 #ifdef ONE_BOARD_MICRO_COMPUTER
446         void reload_bitmap()
447         {
448                 first_invalidate = true;
449         }
450 #endif
451         void capture_screen();
452         bool start_rec_video(int fps);
453         void stop_rec_video();
454         void restart_rec_video();
455         void add_extra_frames(int extra_frames);
456         bool now_rec_video;
457 #ifdef USE_CRT_FILTER
458         bool screen_skip_line;
459 #endif
460         
461         // common sound
462         void update_sound(int* extra_frames);
463         void mute_sound();
464         void stop_sound();
465         void start_rec_sound();
466         void stop_rec_sound();
467         void restart_rec_sound();
468         bool now_rec_sound;
469         
470         // common video device
471 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
472         void get_video_buffer();
473         void mute_video_dev(bool l, bool r);
474 #endif
475 #ifdef USE_MOVIE_PLAYER
476         bool open_movie_file(const _TCHAR* file_path);
477         void close_movie_file();
478         void play_movie();
479         void stop_movie();
480         void pause_movie();
481         double get_movie_frame_rate()
482         {
483                 return movie_frame_rate;
484         }
485         int get_movie_sound_rate()
486         {
487                 return movie_sound_rate;
488         }
489         void set_cur_movie_frame(int frame, bool relative);
490         uint32 get_cur_movie_frame();
491         bool now_movie_play, now_movie_pause;
492 #endif
493 #ifdef USE_VIDEO_CAPTURE
494         int get_cur_capture_dev_index()
495         {
496                 return cur_capture_dev_index;
497         }
498         int get_num_capture_devs()
499         {
500                 return num_capture_devs;
501         }
502         _TCHAR* get_capture_dev_name(int index)
503         {
504                 return capture_dev_name[index];
505         }
506         void open_capture_dev(int index, bool pin);
507         void close_capture_dev();
508         void show_capture_dev_filter();
509         void show_capture_dev_pin();
510         void show_capture_dev_source();
511         void set_capture_dev_channel(int ch);
512 #endif
513         
514         // common printer
515 #ifdef USE_PRINTER
516         void create_bitmap(bitmap_t *bitmap, int width, int height);
517         void release_bitmap(bitmap_t *bitmap);
518         void create_font(font_t *font, const _TCHAR *family, int width, int height, int rotate, bool bold, bool italic);
519         void release_font(font_t *font);
520         void create_pen(pen_t *pen, int width, uint8 r, uint8 g, uint8 b);
521         void release_pen(pen_t *pen);
522         void clear_bitmap(bitmap_t *bitmap, uint8 r, uint8 g, uint8 b);
523         int get_text_width(bitmap_t *bitmap, font_t *font, const char *text);
524         void draw_text_to_bitmap(bitmap_t *bitmap, font_t *font, int x, int y, const char *text, uint8 r, uint8 g, uint8 b);
525         void draw_line_to_bitmap(bitmap_t *bitmap, pen_t *pen, int sx, int sy, int ex, int ey);
526         void draw_rectangle_to_bitmap(bitmap_t *bitmap, int x, int y, int width, int height, uint8 r, uint8 g, uint8 b);
527         void draw_point_to_bitmap(bitmap_t *bitmap, int x, int y, uint8 r, uint8 g, uint8 b);
528         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);
529 #endif
530         void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
531         
532         // common socket
533 #ifdef USE_SOCKET
534         int get_socket(int ch)
535         {
536                 return soc[ch];
537         }
538         void socket_connected(int ch);
539         void socket_disconnected(int ch);
540         void update_socket();
541         bool init_socket_tcp(int ch);
542         bool init_socket_udp(int ch);
543         bool connect_socket(int ch, uint32 ipaddr, int port);
544         void disconnect_socket(int ch);
545         bool listen_socket(int ch);
546         void send_data_tcp(int ch);
547         void send_data_udp(int ch, uint32 ipaddr, int port);
548         void send_data(int ch);
549         void recv_data(int ch);
550 #endif
551         
552         // win32 dependent
553         void update_screen(HDC hdc);
554         HWND main_window_handle;
555         HINSTANCE instance_handle;
556         bool vista_or_later;
557 };
558
559 #endif