2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
13 #define DIRECTSOUND_VERSION 0x900
14 #define DIRECT3D_VERSION 0x900
15 #define DIRECTINPUT_VERSION 0x500
24 #include <d3d9types.h>
30 #include "../config.h"
34 #pragma comment(lib, "wsock32.lib")
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")
45 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
46 #pragma comment(lib, "strmiids.lib")
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 {
55 virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
56 virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
58 EXTERN_C const IID IID_ISampleGrabber;
59 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
60 ISampleGrabber : public IUnknown {
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;
71 #ifdef USE_MOVIE_PLAYER
72 class CMySampleGrabberCB : public ISampleGrabberCB {
76 CMySampleGrabberCB(VM *vm_ptr)
80 STDMETHODIMP_(ULONG) AddRef()
84 STDMETHODIMP_(ULONG) Release()
88 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
90 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
91 *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
96 STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
100 STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
102 vm->movie_sound_callback(pBuffer, lBufferSize);
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)
116 #define SOCKET_BUFFER_MAX 0x100000
119 #ifdef USE_VIDEO_CAPTURE
120 #define MAX_CAPTURE_DEVS 8
123 #define SUPPORT_WIN32_DLL
125 // check memory leaks
127 #define _CRTDBG_MAP_ALLOC
129 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
130 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
133 typedef struct bitmap_s {
135 inline bool initialized()
137 return (hdcDib != NULL);
139 inline scrntype* get_buffer(int y)
141 return lpBmp + width * (height - y - 1);
146 HBITMAP hBmp, hOldBmp;
152 typedef struct font_s {
154 inline bool initialized()
156 return (hFont != NULL);
159 int width, height, rotate;
165 typedef struct pen_s {
167 inline bool initialized()
169 return (hPen != NULL);
178 PAVISTREAM pAVICompressed;
180 LPBITMAPINFOHEADER pbmInfoHeader;
185 } rec_video_thread_param_t;
196 HANDLE hStdIn, hStdOut;
199 void initialize_input();
200 void release_input();
203 LPDIRECTINPUTDEVICE lpdikey;
204 // LPDIRECTINPUTDEVICE lpdijoy;
205 bool dinput_key_available;
206 // bool dinput_joy_available;
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;
217 uint32 joy_status[4]; // joystick #1-#4 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
221 int mouse_status[3]; // x, y, button (b0 = left, b1 = right)
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);
237 #ifdef USE_SCREEN_ROTATE
238 void rotate_screen_buffer(bitmap_t *source, bitmap_t *dest);
240 void stretch_screen_buffer(bitmap_t *source, bitmap_t *dest);
241 bool initialize_d3d9();
242 bool initialize_d3d9_surface(bitmap_t *buffer);
244 void release_d3d9_surface();
245 void copy_to_d3d9_surface(bitmap_t *buffer);
246 int add_video_frames();
248 bitmap_t vm_screen_buffer;
249 #ifdef USE_CRT_FILTER
250 bitmap_t filtered_screen_buffer;
251 bitmap_t tmp_filtered_screen_buffer;
253 #ifdef USE_SCREEN_ROTATE
254 bitmap_t rotated_screen_buffer;
256 bitmap_t stretched_screen_buffer;
257 bitmap_t shrinked_screen_buffer;
258 bitmap_t video_screen_buffer;
260 bitmap_t* draw_screen_buffer;
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;
269 Gdiplus::GdiplusStartupInput gdiSI;
273 LPDIRECT3DDEVICE9 lpd3d9Device;
274 LPDIRECT3DSURFACE9 lpd3d9Surface;
275 LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
277 _TCHAR video_file_path[_MAX_PATH];
279 double rec_video_run_frames;
280 double rec_video_frames;
282 LPBITMAPINFO lpDibRec;
284 PAVISTREAM pAVIStream;
285 PAVISTREAM pAVICompressed;
286 AVICOMPRESSOPTIONS AVIOpts;
290 rec_video_thread_param_t rec_video_thread_param;
292 bool first_draw_screen;
293 bool first_invalidate;
294 bool self_invalidate;
297 void initialize_sound(int rate, int samples);
298 void release_sound();
300 int sound_rate, sound_samples;
301 bool sound_available, sound_started, sound_muted;
304 LPDIRECTSOUNDBUFFER lpdsPrimaryBuffer, lpdsSecondaryBuffer;
305 bool sound_first_half;
307 _TCHAR sound_file_path[_MAX_PATH];
308 FILEIO* rec_sound_fio;
310 int rec_sound_buffer_ptr;
313 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
314 void initialize_video();
315 void release_video();
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;
334 bitmap_t dshow_screen_buffer;
335 int direct_show_width, direct_show_height;
336 bool direct_show_mute[2];
338 #ifdef USE_MOVIE_PLAYER
339 double movie_frame_rate;
340 int movie_sound_rate;
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];
352 void initialize_socket();
353 void release_socket();
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];
373 void initialize(int rate, int samples);
382 return (lock_count != 0);
384 void force_unlock_vm();
385 void sleep(uint32 ms);
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);
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()
407 void disenable_mouse();
409 bool is_mouse_enabled()
411 return mouse_enabled;
413 uint8* get_key_buffer()
417 uint32* get_joy_buffer()
421 int* get_mouse_buffer()
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()
436 return vm_window_width;
438 int get_vm_window_height()
440 return vm_window_height;
442 int get_vm_window_width_aspect()
444 return vm_window_width_aspect;
446 int get_vm_window_height_aspect()
448 return vm_window_height_aspect;
450 scrntype* get_vm_screen_buffer(int y);
452 #ifdef ONE_BOARD_MICRO_COMPUTER
455 first_invalidate = true;
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;
469 void update_sound(int* extra_frames);
472 void start_record_sound();
473 void stop_record_sound();
474 void restart_record_sound();
475 bool now_record_sound;
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);
482 #ifdef USE_MOVIE_PLAYER
483 bool open_movie_file(const _TCHAR* file_path);
484 void close_movie_file();
488 double get_movie_frame_rate()
490 return movie_frame_rate;
492 int get_movie_sound_rate()
494 return movie_sound_rate;
496 void set_cur_movie_frame(int frame, bool relative);
497 uint32 get_cur_movie_frame();
498 bool now_movie_play, now_movie_pause;
500 #ifdef USE_VIDEO_CAPTURE
501 int get_cur_capture_dev_index()
503 return cur_capture_dev_index;
505 int get_num_capture_devs()
507 return num_capture_devs;
509 _TCHAR* get_capture_dev_name(int index)
511 return capture_dev_name[index];
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);
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);
537 void write_bitmap_to_file(bitmap_t *bitmap, const _TCHAR *file_path);
541 int get_socket(int ch)
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);
560 void update_screen(HDC hdc);
561 HWND main_window_handle;
562 HINSTANCE instance_handle;