2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
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
27 #include <d3d9types.h>
33 #include "../config.h"
37 #pragma comment(lib, "wsock32.lib")
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")
48 #pragma comment(lib, "dinput.lib")
50 #pragma comment(lib, "dxguid.lib")
52 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
53 #pragma comment(lib, "strmiids.lib")
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 {
62 virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
63 virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
65 EXTERN_C const IID IID_ISampleGrabber;
66 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
67 ISampleGrabber : public IUnknown {
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;
78 #ifdef USE_MOVIE_PLAYER
79 class CMySampleGrabberCB : public ISampleGrabberCB {
83 CMySampleGrabberCB(VM *vm_ptr)
87 STDMETHODIMP_(ULONG) AddRef()
91 STDMETHODIMP_(ULONG) Release()
95 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
97 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
98 *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
101 return E_NOINTERFACE;
103 STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
107 STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
109 vm->movie_sound_callback(pBuffer, lBufferSize);
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)
123 #define SOCKET_BUFFER_MAX 0x100000
126 #ifdef USE_VIDEO_CAPTURE
127 #define MAX_CAPTURE_DEVS 8
130 #define SUPPORT_WIN32_DLL
132 // check memory leaks
134 #define _CRTDBG_MAP_ALLOC
136 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
137 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
140 typedef struct bitmap_s {
142 inline bool initialized()
144 return (hdcDib != NULL);
146 inline scrntype_t* get_buffer(int y)
148 return lpBmp + width * (height - y - 1);
153 HBITMAP hBmp, hOldBmp;
159 typedef struct font_s {
161 inline bool initialized()
163 return (hFont != NULL);
166 int width, height, rotate;
172 typedef struct pen_s {
174 inline bool initialized()
176 return (hPen != NULL);
185 PAVISTREAM pAVICompressed;
187 LPBITMAPINFOHEADER pbmInfoHeader;
192 } rec_video_thread_param_t;
203 HANDLE hStdIn, hStdOut;
206 void initialize_input();
207 void release_input();
209 #if DIRECTINPUT_VERSION >= 0x0800
211 LPDIRECTINPUTDEVICE8 lpdikey;
212 // LPDIRECTINPUTDEVICE8 lpdijoy;
215 LPDIRECTINPUTDEVICE lpdikey;
216 // LPDIRECTINPUTDEVICE lpdijoy;
218 bool dinput_key_available;
219 // bool dinput_joy_available;
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;
231 uint32_t joy_status[4]; // joystick #1-#4 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
233 uint32_t joy_mask[4];
237 int32_t mouse_status[3]; // x, y, button (b0 = left, b1 = right)
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);
254 #ifdef USE_SCREEN_ROTATE
255 void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
257 void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
258 bool initialize_d3d9();
259 bool initialize_d3d9_surface(bitmap_t *buffer);
261 void release_d3d9_surface();
262 void copy_to_d3d9_surface(bitmap_t *buffer);
263 int add_video_frames();
265 bitmap_t vm_screen_buffer;
266 #ifdef USE_CRT_FILTER
267 bitmap_t filtered_screen_buffer;
268 bitmap_t tmp_filtered_screen_buffer;
270 #ifdef USE_SCREEN_ROTATE
271 bitmap_t rotated_screen_buffer;
273 bitmap_t stretched_screen_buffer;
274 bitmap_t shrinked_screen_buffer;
275 bitmap_t video_screen_buffer;
277 bitmap_t* draw_screen_buffer;
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;
286 Gdiplus::GdiplusStartupInput gdiSI;
290 LPDIRECT3DDEVICE9 lpd3d9Device;
291 LPDIRECT3DSURFACE9 lpd3d9Surface;
292 LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
294 _TCHAR video_file_path[_MAX_PATH];
296 double rec_video_run_frames;
297 double rec_video_frames;
299 LPBITMAPINFO lpDibRec;
301 PAVISTREAM pAVIStream;
302 PAVISTREAM pAVICompressed;
303 AVICOMPRESSOPTIONS AVIOpts;
307 rec_video_thread_param_t rec_video_thread_param;
309 bool first_draw_screen;
310 bool first_invalidate;
311 bool self_invalidate;
314 void initialize_sound(int rate, int samples);
315 void release_sound();
317 int sound_rate, sound_samples;
318 bool sound_available, sound_started, sound_muted;
321 LPDIRECTSOUNDBUFFER lpdsPrimaryBuffer, lpdsSecondaryBuffer;
322 bool sound_first_half;
324 _TCHAR sound_file_path[_MAX_PATH];
325 FILEIO* rec_sound_fio;
327 int rec_sound_buffer_ptr;
330 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
331 void initialize_video();
332 void release_video();
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;
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];
356 #ifdef USE_MOVIE_PLAYER
357 double movie_frame_rate;
358 int movie_sound_rate;
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];
370 void initialize_socket();
371 void release_socket();
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];
391 void initialize(int rate, int samples);
400 return (lock_count != 0);
402 void force_unlock_vm();
403 void sleep(uint32_t ms);
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();
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()
428 void disable_mouse();
430 bool is_mouse_enabled()
432 return mouse_enabled;
435 uint8_t* get_key_buffer()
440 uint32_t* get_joy_buffer()
446 int32_t* get_mouse_buffer()
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()
462 return vm_window_width;
464 int get_vm_window_height()
466 return vm_window_height;
468 int get_vm_window_width_aspect()
470 return vm_window_width_aspect;
472 int get_vm_window_height_aspect()
474 return vm_window_height_aspect;
476 scrntype_t* get_vm_screen_buffer(int y);
478 #ifdef ONE_BOARD_MICRO_COMPUTER
481 first_invalidate = true;
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;
495 void update_sound(int* extra_frames);
498 void start_record_sound();
499 void stop_record_sound();
500 void restart_record_sound();
501 bool now_record_sound;
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);
508 #ifdef USE_MOVIE_PLAYER
509 bool open_movie_file(const _TCHAR* file_path);
510 void close_movie_file();
514 double get_movie_frame_rate()
516 return movie_frame_rate;
518 int get_movie_sound_rate()
520 return movie_sound_rate;
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;
526 #ifdef USE_VIDEO_CAPTURE
527 int get_cur_capture_dev_index()
529 return cur_capture_dev_index;
531 int get_num_capture_devs()
533 return num_capture_devs;
535 _TCHAR* get_capture_dev_name(int index)
537 return capture_dev_name[index];
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);
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);
563 void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
567 int get_socket(int ch)
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);
586 void update_screen(HDC hdc);
587 HWND main_window_handle;
588 HINSTANCE instance_handle;