2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
7 [ win32 emulation i/f ]
14 #define DIRECTSOUND_VERSION 0x900
15 #define DIRECT3D_VERSION 0x900
16 //#define DIRECTINPUT_VERSION 0x500
17 #define DIRECTINPUT_VERSION 0x800
22 // output fdc debug log
23 // #define _FDC_DEBUG_LOG
24 // output i/o debug log
25 // #define _IO_DEBUG_LOG
30 //# include "menuclasses.h"
31 //# include "mainwidget.h"
32 //# include "qt_gldraw.h"
33 //# include "emu_utils.h"
34 //# include "qt_main.h"
35 # include "simd_types.h"
36 // Wrapper of WIN32->*nix
61 # if !defined(Q_OS_WIN32)
73 #define WM_RESIZE (WM_USER + 1)
74 #define WM_SOCKET0 (WM_USER + 2)
75 #define WM_SOCKET1 (WM_USER + 3)
76 #define WM_SOCKET2 (WM_USER + 4)
77 #define WM_SOCKET3 (WM_USER + 5)
80 #if defined(USE_LASER_DISC) || defined(USE_VIDEO_CAPTURE)
81 #define USE_DIRECT_SHOW
84 #ifdef USE_VIDEO_CAPTURE
85 #define MAX_CAPTURE_DEVS 8
88 #ifndef SCREEN_WIDTH_ASPECT
89 #define SCREEN_WIDTH_ASPECT SCREEN_WIDTH
91 #ifndef SCREEN_HEIGHT_ASPECT
92 #define SCREEN_HEIGHT_ASPECT SCREEN_HEIGHT
94 #ifndef WINDOW_WIDTH_ASPECT
95 #define WINDOW_WIDTH_ASPECT SCREEN_WIDTH
97 #ifndef WINDOW_HEIGHT_ASPECT
98 #define WINDOW_HEIGHT_ASPECT SCREEN_HEIGHT
101 #define WINDOW_WIDTH SCREEN_WIDTH_ASPECT
103 #ifndef WINDOW_HEIGHT
104 #define WINDOW_HEIGHT SCREEN_HEIGHT_ASPECT
114 SDL_sem **pSndApplySem;
121 #pragma comment(lib, "d3d9.lib")
122 #pragma comment(lib, "d3dx9.lib")
125 #include <d3d9types.h>
130 //#pragma comment(lib, "dinput.lib")
131 #pragma comment(lib, "dinput8.lib")
132 #pragma comment(lib, "dxguid.lib")
135 #ifdef USE_DIRECT_SHOW
136 #pragma comment(lib, "strmiids.lib")
139 EXTERN_C const CLSID CLSID_SampleGrabber;
140 EXTERN_C const CLSID CLSID_NullRenderer;
141 EXTERN_C const IID IID_ISampleGrabberCB;
142 MIDL_INTERFACE("0579154A-2B53-4994-B0D0-E773148EFF85")
143 ISampleGrabberCB : public IUnknown {
145 virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
146 virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
148 EXTERN_C const IID IID_ISampleGrabber;
149 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
150 ISampleGrabber : public IUnknown {
152 virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot) = 0;
153 virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType) = 0;
154 virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType) = 0;
155 virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem) = 0;
156 virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( /* [out][in] */ long *pBufferSize,/* [out] */ long *pBuffer) = 0;
157 virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( /* [retval][out] */ IMediaSample **ppSample) = 0;
158 virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback,long WhichMethodToCallback) = 0;
163 #ifdef USE_LASER_DISC
164 class CMySampleGrabberCB : public ISampleGrabberCB {
168 CMySampleGrabberCB(VM *vm_ptr)
172 STDMETHODIMP_(ULONG) AddRef()
176 STDMETHODIMP_(ULONG) Release()
180 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
182 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
183 *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
186 return E_NOINTERFACE;
188 STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
192 STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
194 vm->movie_sound_callback(pBuffer, lBufferSize);
203 # if defined(_USE_QT)
205 # include <winsock.h>
209 // check memory leaks
211 #define _CRTDBG_MAP_ALLOC
213 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
214 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
218 #define MAX_D88_BANKS 64
223 #define SOCKET_BUFFER_MAX 0x100000
236 typedef Uint32 scrntype;
239 PAVISTREAM pAVICompressed;
240 scrntype* lpBmpSource;
241 LPBITMAPINFOHEADER pbmInfoHeader;
255 bool request_terminate;
270 // ----------------------------------------
272 // ----------------------------------------
273 void initialize_input();
274 void release_input();
276 void key_down_sub(int code, bool repeat);
277 void key_up_sub(int code);
279 #if !defined(_USE_QT)
281 LPDIRECTINPUTDEVICE lpdikey;
282 LPDIRECTINPUTDEVICE lpdijoy;
287 uint8 keycode_conv[256];
288 uint8 key_status[256]; // windows key code mapping
289 uint32 modkey_status;
290 uint8 key_dik_prev[256];
291 #ifdef USE_SHIFT_NUMPAD_KEY
292 uint8 key_converted[256];
293 bool key_shift_pressed, key_shift_released;
297 uint32 joy_status[2]; // joystick #1, #2 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
301 int mouse_status[3]; // x, y, button (b0 = left, b1 = right)
309 Qt::CursorShape mouse_shape;
312 FIFO* autokey_buffer;
313 int autokey_phase, autokey_shift;
314 int autokey_table[256];
315 char auto_key_str[65536];
318 #ifdef USE_CRT_FILTER
319 #ifdef USE_SCREEN_ROTATE
320 void apply_crt_filter_and_stretch_rotated_screen_buffer_x3_y3();
321 void apply_crt_filter_and_stretch_rotated_screen_buffer_x3_y2();
322 void apply_crt_filter_and_stretch_rotated_screen_buffer_x2_y3();
323 void apply_crt_filter_and_stretch_rotated_screen_buffer_x2_y2();
324 void apply_crt_filter_to_rotated_screen_buffer();
326 void apply_crt_filter_and_stretch_screen_buffer_x3_y3();
327 void apply_crt_filter_and_stretch_screen_buffer_x3_y2();
328 void apply_crt_filter_and_stretch_screen_buffer_x2_y3();
329 void apply_crt_filter_and_stretch_screen_buffer_x2_y2();
330 void apply_crt_filter_to_screen_buffer();
332 void stretch_screen_buffer();
334 // ----------------------------------------
336 // ----------------------------------------
337 void initialize_screen();
338 void release_screen();
339 #if !defined(_USE_QT)
340 void create_dib_section(HDC hdc, int width, int height, HDC *hdcDib, HBITMAP *hBmp, HBITMAP *hOldBmp, LPBYTE *lpBuf, scrntype **lpBmp, LPBITMAPINFO *lpDib);
343 int screen_width, screen_height;
344 int screen_width_aspect, screen_height_aspect;
345 int window_width, window_height;
346 int display_width, display_height;
347 bool screen_size_changed;
353 scrntype* lpBmpSource;
354 LPBITMAPINFO lpDibSource;
355 LPBITMAPINFOHEADER pbmInfoHeader;
358 int source_width, source_height;
359 int source_width_aspect, source_height_aspect;
360 int stretched_width, stretched_height;
361 int stretch_pow_x, stretch_pow_y;
362 int screen_dest_x, screen_dest_y;
366 bool first_draw_screen;
367 bool first_invalidate;
368 bool self_invalidate;
373 #ifdef USE_SCREEN_ROTATE
379 bool render_to_SDLFB;
382 bool render_with_OpenCL;
392 _TCHAR video_file_name[_MAX_PATH];
394 _TCHAR video_file_name[AG_PATHNAME_MAX];
397 double rec_video_run_frames;
398 double rec_video_frames;
400 // LPBITMAPINFO lpDibRec;
401 // PAVIFILE pAVIFile;
402 // PAVISTREAM pAVIStream;
403 // PAVISTREAM pAVICompressed;
404 // AVICOMPRESSOPTIONS opts;
405 // DWORD dwAVIFileSize;
409 // HBITMAP hBmpRec, hOldBmpRec;
411 // scrntype* lpBmpRec;
413 bool use_video_thread;
416 AG_Thread hVideoThread;
418 //video_thread_t video_thread_param;
420 // ----------------------------------------
422 // ----------------------------------------
423 void initialize_sound();
424 void release_sound();
425 void update_sound(int* extra_frames);
426 //void AudioCallbackSDL(void *udata, Uint8 *stream, int len);
428 sdl_snddata_t snddata;
429 int sound_rate, sound_samples;
430 bool sound_ok, sound_started, now_mute;
431 SDL_AudioSpec SndSpecReq, SndSpecPresented;
432 //Uint8 iTotalVolume;
438 _TCHAR sound_file_name[_MAX_PATH];
440 _TCHAR sound_file_name[AG_PATHNAME_MAX];
448 HBITMAP hBmp, hOldBmp;
453 #ifdef USE_SCREEN_ROTATE
456 HBITMAP hBmpRotate, hOldBmpRotate;
458 scrntype* lpBmpRotate;
459 LPBITMAPINFO lpDibRotate;
464 HBITMAP hBmpStretch1, hOldBmpStretch1;
465 LPBYTE lpBufStretch1;
466 scrntype* lpBmpStretch1;
467 LPBITMAPINFO lpDibStretch1;
470 HBITMAP hBmpStretch2, hOldBmpStretch2;
471 LPBYTE lpBufStretch2;
472 scrntype* lpBmpStretch2;
473 LPBITMAPINFO lpDibStretch2;
477 LPDIRECT3DDEVICE9 lpd3d9Device;
478 LPDIRECT3DSURFACE9 lpd3d9Surface;
479 LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
483 _TCHAR video_file_name[_MAX_PATH];
485 double rec_video_run_frames;
486 double rec_video_frames;
489 #if !defined(_USE_QT)
490 LPBITMAPINFO lpDibRec;
492 PAVISTREAM pAVIStream;
493 PAVISTREAM pAVICompressed;
494 AVICOMPRESSOPTIONS opts;
499 HBITMAP hBmpRec, hOldBmpRec;
503 bool use_video_thread;
505 video_thread_t video_thread_param;
507 void initialize_sound();
508 void release_sound();
509 void update_sound(int* extra_frames);
511 int sound_rate, sound_samples;
512 bool sound_ok, sound_started, now_mute;
517 // ----------------------------------------
519 // ----------------------------------------
520 #if !defined(_USE_QT)
523 LPDIRECTSOUNDBUFFER lpdsb, lpdsp;
527 _TCHAR sound_file_name[_MAX_PATH];
535 #ifdef USE_LASER_DISC
536 double movie_frame_rate;
537 int movie_sound_rate;
538 bool now_movie_play, now_movie_pause;
541 #ifdef USE_DIRECT_SHOW
542 // ----------------------------------------
544 // ----------------------------------------
545 void initialize_direct_show();
546 void release_direct_show();
547 void create_direct_show_dib_section();
548 void release_direct_show_dib_section();
550 IGraphBuilder *pGraphBuilder;
551 IBaseFilter *pVideoBaseFilter;
552 IBaseFilter *pCaptureBaseFilter;
553 ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
554 ISampleGrabber *pVideoSampleGrabber;
555 IBaseFilter *pSoundBaseFilter;
556 ISampleGrabber *pSoundSampleGrabber;
557 #ifdef USE_LASER_DISC
558 CMySampleGrabberCB *pSoundCallBack;
560 IMediaControl *pMediaControl;
561 IMediaSeeking *pMediaSeeking;
562 IMediaPosition *pMediaPosition;
563 IVideoWindow *pVideoWindow;
564 IBasicVideo *pBasicVideo;
565 IBasicAudio *pBasicAudio;
566 bool bTimeFormatFrame;
567 bool bVerticalReversed;
570 HBITMAP hBmpDShow, hOldBmpDShow;
572 scrntype* lpBmpDShow;
573 LPBITMAPINFO lpDibDShow;
575 int direct_show_width, direct_show_height;
576 bool direct_show_mute[2];
577 #ifdef USE_LASER_DISC
578 double movie_frame_rate;
579 int movie_sound_rate;
580 bool now_movie_play, now_movie_pause;
582 #ifdef USE_VIDEO_CAPTURE
583 void enum_capture_devs();
584 bool connect_capture_dev(int index, bool pin);
585 int cur_capture_dev_index;
586 int num_capture_devs;
587 _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
592 // ----------------------------------------
594 // ----------------------------------------
596 _TCHAR path[_MAX_PATH];
603 media_status_t cart_status[MAX_CART];
606 media_status_t disk_status[MAX_FD];
609 media_status_t quickdisk_status[MAX_QD];
612 media_status_t tape_status;
614 #ifdef USE_LASER_DISC
615 media_status_t laser_disc_status;
618 void initialize_media();
620 void restore_media();
622 void clear_media_status(media_status_t *status)
624 status->path[0] = _T('\0');
625 status->wait_count = 0;
628 // ----------------------------------------
630 // ----------------------------------------
631 void initialize_printer();
632 void release_printer();
633 void reset_printer();
634 void update_printer();
635 void open_printer_file();
636 void close_printer_file();
638 _TCHAR prn_file_name[_MAX_PATH];
640 _TCHAR prn_file_name[_MAX_PATH];
643 int prn_data, prn_wait_frames;
647 // ----------------------------------------
649 // ----------------------------------------
650 void initialize_socket();
651 void release_socket();
652 void update_socket();
655 bool is_tcp[SOCKET_MAX];
656 #if !defined(_USE_QT)
657 struct sockaddr_in udpaddr[SOCKET_MAX];
659 int socket_delay[SOCKET_MAX];
660 char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
661 int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
665 // ----------------------------------------
667 // ----------------------------------------
668 void initialize_debugger();
669 void release_debugger();
671 //CSP_Debugger *hDebugger;
672 //QThread *hDebuggerThread;
674 HANDLE hDebuggerThread;
675 debugger_thread_t debugger_thread_param;
680 // ----------------------------------------
682 // ----------------------------------------
683 void initialize_debug_log();
684 void release_debug_log();
689 // ----------------------------------------
691 // ----------------------------------------
692 void save_state_tmp(const _TCHAR* file_path);
693 bool load_state_tmp(const _TCHAR* file_path);
696 // ----------------------------------------
698 // ----------------------------------------
702 #ifdef USE_SOUND_DEVICE_TYPE
703 int sound_device_type;
705 _TCHAR app_path[_MAX_PATH];
709 bool bDrawLine[SCREEN_HEIGHT];
710 uint32 *getJoyStatPtr(void) {
714 // ----------------------------------------
716 // ----------------------------------------
718 EMU(class Ui_MainWindow*, GLDrawClass*);
720 EMU(HWND hwnd, HINSTANCE hinst);
724 _TCHAR* application_path()
728 _TCHAR* bios_path(const _TCHAR* file_name);
731 if(host_cpus > 1) VMSemaphore->lock();
733 void UnlockVM(void) {
734 if(host_cpus > 1) VMSemaphore->unlock();
736 void SetHostCpus(int v) {
747 void UnlockVM(void) {
751 QImage *getPseudoVramClass(void) { return pPseudoVram;}
752 void setMousePointer(int x, int y) {
756 void setMouseButton(int button) {
757 mouse_button = button;
759 int getMouseButton() {
764 // ----------------------------------------
766 // ----------------------------------------
768 class Ui_MainWindow *main_window_handle;
769 GLDrawClass *instance_handle;
773 debugger_thread_t debugger_thread_param;
774 CSP_Debugger *hDebugger;
779 //QThread *hDebuggerThread;
781 HWND main_window_handle;
782 HINSTANCE instance_handle;
785 // drive virtual machine
786 int frame_interval();
789 #ifdef USE_SPECIAL_RESET
790 void special_reset();
793 void notify_power_off();
800 _TCHAR path[_MAX_PATH];
802 // _TCHAR name[128]; // Convert to UTF8
804 // } bank[MAX_D88_BANKS];
805 _TCHAR disk_name[MAX_D88_BANKS][128]; // Convert to UTF8
810 int get_access_lamp(void);
814 void open_cart(int drv, const _TCHAR* file_path);
815 void close_cart(int drv);
816 bool cart_inserted(int drv);
819 void open_disk(int drv, const _TCHAR* file_path, int bank);
820 void close_disk(int drv);
821 bool disk_inserted(int drv);
822 void set_disk_protected(int drv, bool value);
823 bool get_disk_protected(int drv);
826 void open_quickdisk(int drv, const _TCHAR* file_path);
827 void close_quickdisk(int drv);
828 bool quickdisk_inserted(int drv);
831 void play_tape(const _TCHAR* file_path);
832 void rec_tape(const _TCHAR* file_path);
834 bool tape_inserted();
837 return vm->get_tape_ptr();
841 #ifdef USE_TAPE_BUTTON
844 void push_fast_forward();
845 void push_fast_rewind();
846 void push_apss_forward();
847 void push_apss_rewind();
848 bool get_tape_play(void)
850 return vm->get_tape_play();
853 #ifdef USE_LASER_DISC
854 void open_laser_disc(const _TCHAR* file_path);
855 void close_laser_disc();
856 bool laser_disc_inserted();
858 #ifdef USE_BINARY_FILE1
859 void load_binary(int drv, const _TCHAR* file_path);
860 void save_binary(int drv, const _TCHAR* file_path);
862 #ifdef SUPPORT_DUMMY_DEVICE_LED
863 uint32 get_led_status(void);
867 void start_rec_sound();
868 void stop_rec_sound();
869 void restart_rec_sound();
872 void capture_screen();
873 bool start_rec_video(int fps);
874 void stop_rec_video();
875 void restart_rec_video();
878 void update_config();
887 void key_mod(uint32 mod) {
891 void key_down(int code, bool repeat);
892 void key_up(int code);
893 void key_lost_focus()
897 uint32 recent_key_sym;
898 uint32 recent_key_mod;
899 uint32 recent_key_unicode;
901 void press_button(int num);
905 void disenable_mouse();
907 bool get_mouse_enabled()
909 return mouse_enabled;
913 void start_auto_key();
914 void stop_auto_key();
917 return (autokey_phase != 0);
919 # if defined(_USE_QT) || defined(Q_OS_WIN)
920 void set_auto_key_string(const char *cstr);
925 int get_window_width(int mode);
926 int get_window_height(int mode);
927 void set_display_size(int width, int height, bool window_mode);
930 void update_screen();
932 void update_screen(HDC hdc);
937 first_invalidate = true;
944 #ifdef USE_VIDEO_CAPTURE
946 int get_cur_capture_dev_index()
948 return cur_capture_dev_index;
950 int get_num_capture_devs()
952 return num_capture_devs;
954 _TCHAR* get_capture_dev_name(int index)
956 return capture_dev_name[index];
958 void open_capture_dev(int index, bool pin);
959 void close_capture_dev();
960 void show_capture_dev_filter();
961 void show_capture_dev_pin();
962 void show_capture_dev_source();
967 int get_socket(int ch)
971 void socket_connected(int ch);
972 void socket_disconnected(int ch);
973 void send_data(int ch);
974 void recv_data(int ch);
979 void open_debugger(int cpu_index);
980 void close_debugger();
981 bool debugger_enabled(int cpu_index);
985 # if !defined(Q_OS_WIN) && !defined(Q_OS_CYGWIN)
986 uint16_t GetAsyncKeyState(uint32_t vk); // Win32 GetAsyncKeyState() wrappeer.
989 // ----------------------------------------
990 // for virtual machine
991 // ----------------------------------------
996 #if !defined(_USE_QT)
997 PostMessage(main_window_handle, WM_CLOSE, 0, 0L);
1006 uint32* joy_buffer()
1012 return mouse_status;
1016 void change_screen_size(int sw, int sh, int swa, int sha, int ww, int wh);
1017 int get_screen_width_aspect(void) {return screen_width_aspect;}
1018 int get_screen_height_aspect(void) {return screen_height_aspect;}
1019 scrntype* screen_buffer(int y);
1020 #ifdef USE_CRT_FILTER
1021 bool screen_skip_line;
1025 void get_host_time(cur_time_t* time);
1028 void printer_out(uint8 value);
1029 void printer_strobe(bool value);
1031 #ifdef USE_DIRECT_SHOW
1033 void get_direct_show_buffer();
1034 void mute_direct_show_dev(bool l, bool r);
1036 #ifdef USE_LASER_DISC
1037 bool open_movie_file(const _TCHAR* file_path);
1038 void close_movie_file();
1044 double get_movie_frame_rate()
1046 return movie_frame_rate;
1048 int get_movie_sound_rate()
1050 return movie_sound_rate;
1052 void set_cur_movie_frame(int frame, bool relative);
1053 uint32 get_cur_movie_frame();
1055 #ifdef USE_VIDEO_CAPTURE
1056 void set_capture_dev_channel(int ch);
1062 bool init_socket_tcp(int ch);
1063 bool init_socket_udp(int ch);
1064 bool connect_socket(int ch, uint32 ipaddr, int port);
1065 void disconnect_socket(int ch);
1066 bool listen_socket(int ch);
1067 void send_data_tcp(int ch);
1068 void send_data_udp(int ch, uint32 ipaddr, int port);
1070 #if defined(USE_DIG_RESOLUTION)
1071 void get_screen_resolution(int *w, int *h);
1074 void out_debug_log(const _TCHAR* format, ...);
1076 void out_message(const _TCHAR* format, ...);
1078 _TCHAR message[_MAX_PATH];
1081 void sleep(uint32 ms);