2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
14 #define _WIN32_WINNT 0x500
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
32 #include <d3d9types.h>
38 #include "../common.h"
39 #include "../config.h"
42 // relative path from *.vcproj/*.vcxproj, not from this directory :-(
43 #if defined(_MSC_VER) && (_MSC_VER >= 1800)
45 #pragma comment(lib, "../src/zlib-1.2.11/vc++2013/debug/zlibstat.lib")
47 #pragma comment(lib, "../src/zlib-1.2.11/vc++2013/release/zlibstat.lib")
51 #pragma comment(lib, "../src/zlib-1.2.11/vc++2008/debug/zlibstat.lib")
53 #pragma comment(lib, "../src/zlib-1.2.11/vc++2008/release/zlibstat.lib")
60 #pragma comment(lib, "wsock32.lib")
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")
73 #pragma comment(lib, "dinput.lib")
75 #pragma comment(lib, "dxguid.lib")
77 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
78 #pragma comment(lib, "strmiids.lib")
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 {
87 virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
88 virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
90 EXTERN_C const IID IID_ISampleGrabber;
91 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
92 ISampleGrabber : public IUnknown {
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;
103 #ifdef USE_MOVIE_PLAYER
104 class CMySampleGrabberCB : public ISampleGrabberCB {
108 CMySampleGrabberCB(VM *vm_ptr)
112 STDMETHODIMP_(ULONG) AddRef()
116 STDMETHODIMP_(ULONG) Release()
120 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
122 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
123 *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
126 return E_NOINTERFACE;
128 STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
132 STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
134 vm->movie_sound_callback(pBuffer, lBufferSize);
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)
148 #define SOCKET_BUFFER_MAX 0x100000
151 #ifdef USE_VIDEO_CAPTURE
152 #define MAX_CAPTURE_DEVS 8
155 #define SUPPORT_WIN32_DLL
157 #define SCREEN_FILTER_NONE 0
158 #define SCREEN_FILTER_RGB 1
159 #define SCREEN_FILTER_RF 2
161 // check memory leaks
163 // _malloca is defined in typeinfo.h
167 #define _CRTDBG_MAP_ALLOC
169 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
170 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
173 typedef struct bitmap_s {
175 inline bool initialized()
177 return (hdcDib != NULL);
179 inline scrntype_t* get_buffer(int y)
181 return lpBmp + width * (height - y - 1);
186 HBITMAP hBmp, hOldBmp;
192 typedef struct font_s {
194 inline bool initialized()
196 return (hFont != NULL);
199 int width, height, rotate;
205 typedef struct pen_s {
207 inline bool initialized()
209 return (hPen != NULL);
218 PAVISTREAM pAVICompressed;
220 LPBITMAPINFOHEADER pbmInfoHeader;
225 } rec_video_thread_param_t;
236 HANDLE hStdIn, hStdOut;
239 void initialize_input();
240 void release_input();
242 #if DIRECTINPUT_VERSION >= 0x0800
244 LPDIRECTINPUTDEVICE8 lpdikey;
245 // LPDIRECTINPUTDEVICE8 lpdijoy;
248 LPDIRECTINPUTDEVICE lpdikey;
249 // LPDIRECTINPUTDEVICE lpdijoy;
251 bool dinput_key_available;
252 // bool dinput_joy_available;
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;
260 bool key_caps_locked;
264 uint32_t joy_status[4]; // joystick #1-#4 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
266 uint32_t joy_mask[4];
270 int32_t mouse_status[3]; // x, y, button (b0 = left, b1 = right)
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);
287 //#ifdef USE_SCREEN_ROTATE
288 void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
290 void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
291 bool initialize_d3d9();
292 bool initialize_d3d9_surface(bitmap_t *buffer);
294 void release_d3d9_surface();
295 void copy_to_d3d9_surface(bitmap_t *buffer);
296 int add_video_frames();
298 bitmap_t vm_screen_buffer;
299 #ifdef USE_SCREEN_FILTER
300 bitmap_t filtered_screen_buffer;
301 bitmap_t tmp_filtered_screen_buffer;
303 //#ifdef USE_SCREEN_ROTATE
304 bitmap_t rotated_screen_buffer;
306 bitmap_t stretched_screen_buffer;
307 bitmap_t shrinked_screen_buffer;
308 bitmap_t video_screen_buffer;
310 bitmap_t* draw_screen_buffer;
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;
319 Gdiplus::GdiplusStartupInput gdiSI;
323 LPDIRECT3DDEVICE9 lpd3d9Device;
324 LPDIRECT3DSURFACE9 lpd3d9Surface;
325 LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
327 _TCHAR video_file_path[_MAX_PATH];
329 double rec_video_run_frames;
330 double rec_video_frames;
332 LPBITMAPINFO lpDibRec;
334 PAVISTREAM pAVIStream;
335 PAVISTREAM pAVICompressed;
336 AVICOMPRESSOPTIONS AVIOpts;
340 rec_video_thread_param_t rec_video_thread_param;
342 bool first_draw_screen;
343 bool first_invalidate;
344 bool self_invalidate;
347 void initialize_sound(int rate, int samples);
348 void release_sound();
350 int sound_rate, sound_samples;
351 bool sound_available, sound_started, sound_muted;
354 LPDIRECTSOUNDBUFFER lpdsPrimaryBuffer, lpdsSecondaryBuffer;
355 bool sound_first_half;
357 _TCHAR sound_file_path[_MAX_PATH];
358 FILEIO* rec_sound_fio;
360 int rec_sound_buffer_ptr;
363 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
364 void initialize_video();
365 void release_video();
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;
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];
389 #ifdef USE_MOVIE_PLAYER
390 double movie_frame_rate;
391 int movie_sound_rate;
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];
403 void initialize_socket();
404 void release_socket();
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];
424 void initialize(int rate, int samples);
433 return (lock_count != 0);
435 void force_unlock_vm();
436 void sleep(uint32_t ms);
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();
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()
461 void disable_mouse();
463 bool is_mouse_enabled()
465 return mouse_enabled;
468 uint8_t* get_key_buffer()
473 uint32_t* get_joy_buffer()
479 int32_t* get_mouse_buffer()
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()
496 return vm_window_width;
498 int get_vm_window_height()
500 return vm_window_height;
502 int get_vm_window_width_aspect()
504 return vm_window_width_aspect;
506 int get_vm_window_height_aspect()
508 return vm_window_height_aspect;
510 scrntype_t* get_vm_screen_buffer(int y);
512 #ifdef ONE_BOARD_MICRO_COMPUTER
515 first_invalidate = true;
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;
529 void update_sound(int* extra_frames);
532 void start_record_sound();
533 void stop_record_sound();
534 void restart_record_sound();
535 bool now_record_sound;
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);
542 #ifdef USE_MOVIE_PLAYER
543 bool open_movie_file(const _TCHAR* file_path);
544 void close_movie_file();
548 double get_movie_frame_rate()
550 return movie_frame_rate;
552 int get_movie_sound_rate()
554 return movie_sound_rate;
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;
560 #ifdef USE_VIDEO_CAPTURE
561 int get_cur_capture_dev_index()
563 return cur_capture_dev_index;
565 int get_num_capture_devs()
567 return num_capture_devs;
569 _TCHAR* get_capture_dev_name(int index)
571 return capture_dev_name[index];
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);
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);
597 void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
601 int get_socket(int ch)
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);
620 void invalidate_screen();
621 void update_screen(HDC hdc);
622 HWND main_window_handle;
623 HINSTANCE instance_handle;