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
21 // output fdc debug log
22 // #define _FDC_DEBUG_LOG
23 // output i/o debug log
24 // #define _IO_DEBUG_LOG
27 #if defined(_USE_AGAR)
29 # include <agar/core.h>
30 # include <agar/gui.h>
31 # include "simd_types.h"
32 // Wrapper of WIN32->*nix
35 #define _MAX_PATH AG_PATHNAME_MAX
38 #elif defined(_USE_QT)
39 # include <SDL2/SDL.h>
40 //# include "menuclasses.h"
41 //# include "mainwidget.h"
42 //# include "qt_gldraw.h"
43 //# include "emu_utils.h"
44 //# include "qt_main.h"
45 # include "simd_types.h"
46 // Wrapper of WIN32->*nix
50 #define _MAX_PATH MAX_PATH
53 #define _MAX_PATH 2048
74 #if defined(_USE_AGAR)
75 #include "agar_input.h"
76 #elif defined(_USE_QT)
80 #if defined(_USE_AGAR) || defined(_USE_QT)
87 #define WM_RESIZE (WM_USER + 1)
88 #define WM_SOCKET0 (WM_USER + 2)
89 #define WM_SOCKET1 (WM_USER + 3)
90 #define WM_SOCKET2 (WM_USER + 4)
91 #define WM_SOCKET3 (WM_USER + 5)
94 #if defined(USE_LASER_DISC) || defined(USE_VIDEO_CAPTURE)
95 #define USE_DIRECT_SHOW
98 #ifdef USE_VIDEO_CAPTURE
99 #define MAX_CAPTURE_DEVS 8
102 #ifndef SCREEN_WIDTH_ASPECT
103 #define SCREEN_WIDTH_ASPECT SCREEN_WIDTH
105 #ifndef SCREEN_HEIGHT_ASPECT
106 #define SCREEN_HEIGHT_ASPECT SCREEN_HEIGHT
109 #define WINDOW_WIDTH SCREEN_WIDTH_ASPECT
111 #ifndef WINDOW_HEIGHT
112 #define WINDOW_HEIGHT SCREEN_HEIGHT_ASPECT
115 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
122 SDL_sem **pSndApplySem;
129 #pragma comment(lib, "d3d9.lib")
130 #pragma comment(lib, "d3dx9.lib")
133 #include <d3d9types.h>
138 #pragma comment(lib, "dinput.lib")
139 #pragma comment(lib, "dxguid.lib")
142 #ifdef USE_DIRECT_SHOW
143 #pragma comment(lib, "strmiids.lib")
146 EXTERN_C const CLSID CLSID_SampleGrabber;
147 EXTERN_C const CLSID CLSID_NullRenderer;
148 EXTERN_C const IID IID_ISampleGrabberCB;
149 MIDL_INTERFACE("0579154A-2B53-4994-B0D0-E773148EFF85")
150 ISampleGrabberCB : public IUnknown {
152 virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
153 virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
155 EXTERN_C const IID IID_ISampleGrabber;
156 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
157 ISampleGrabber : public IUnknown {
159 virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot) = 0;
160 virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType) = 0;
161 virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType) = 0;
162 virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem) = 0;
163 virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( /* [out][in] */ long *pBufferSize,/* [out] */ long *pBuffer) = 0;
164 virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( /* [retval][out] */ IMediaSample **ppSample) = 0;
165 virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback,long WhichMethodToCallback) = 0;
170 #ifdef USE_LASER_DISC
171 class CMySampleGrabberCB : public ISampleGrabberCB {
175 CMySampleGrabberCB(VM *vm_ptr)
179 STDMETHODIMP_(ULONG) AddRef()
183 STDMETHODIMP_(ULONG) Release()
187 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
189 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
190 *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
193 return E_NOINTERFACE;
195 STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
199 STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
201 vm->movie_sound_callback(pBuffer, lBufferSize);
210 # if defined(_USE_AGAR) || defined(_USE_SDL)
211 # elif defined(_USE_QT)
213 # include <winsock.h>
217 // check memory leaks
219 #define _CRTDBG_MAP_ALLOC
221 #define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
222 #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
226 #define MAX_D88_BANKS 64
231 #define SOCKET_BUFFER_MAX 0x100000
243 #if defined(_USE_AGAR) || defined(_USE_QT)
244 typedef Uint32 scrntype;
247 PAVISTREAM pAVICompressed;
248 scrntype* lpBmpSource;
249 LPBITMAPINFOHEADER pbmInfoHeader;
263 bool request_terminate;
272 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
273 SDL_sem *pVMSemaphore; // To be thread safed.
276 // ----------------------------------------
278 // ----------------------------------------
279 void initialize_input();
280 void release_input();
282 void key_down_sub(int code, bool repeat);
283 void key_up_sub(int code);
285 #if !defined(_USE_AGAR) && !defined(_USE_SDL) && !defined(_USE_QT)
287 LPDIRECTINPUTDEVICE lpdikey;
288 LPDIRECTINPUTDEVICE lpdijoy;
293 uint8 keycode_conv[256];
294 uint8 key_status[256]; // windows key code mapping
295 uint32_t modkey_status;
296 uint8 key_dik_prev[256];
297 #ifdef USE_SHIFT_NUMPAD_KEY
298 uint8 key_converted[256];
299 bool key_shift_pressed, key_shift_released;
303 uint32 joy_status[2]; // joystick #1, #2 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
307 int mouse_status[3]; // x, y, button (b0 = left, b1 = right)
311 FIFO* autokey_buffer;
312 int autokey_phase, autokey_shift;
315 // ----------------------------------------
317 // ----------------------------------------
318 void initialize_screen();
319 void release_screen();
320 #if !defined(_USE_AGAR) && !defined(_USE_SDL) && !defined(_USE_QT)
321 void create_dib_section(HDC hdc, int width, int height, HDC *hdcDib, HBITMAP *hBmp, HBITMAP *hOldBmp, LPBYTE *lpBuf, scrntype **lpBmp, LPBITMAPINFO *lpDib);
324 int screen_width, screen_height;
325 int screen_width_aspect, screen_height_aspect;
326 int window_width, window_height;
327 int display_width, display_height;
328 bool screen_size_changed;
330 #if defined(_USE_AGAR)
332 #elif defined(_USE_QT)
336 scrntype* lpBmpSource;
337 LPBITMAPINFO lpDibSource;
338 LPBITMAPINFOHEADER pbmInfoHeader;
341 int source_width, source_height;
342 int source_width_aspect, source_height_aspect;
343 int stretched_width, stretched_height;
344 int stretch_pow_x, stretch_pow_y;
345 int screen_dest_x, screen_dest_y;
349 bool first_draw_screen;
350 bool first_invalidate;
351 bool self_invalidate;
354 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
356 #ifdef USE_SCREEN_ROTATE
362 bool render_to_SDLFB;
365 bool render_with_OpenCL;
375 _TCHAR video_file_name[_MAX_PATH];
377 _TCHAR video_file_name[AG_PATHNAME_MAX];
380 double rec_video_run_frames;
381 double rec_video_frames;
383 // LPBITMAPINFO lpDibRec;
384 // PAVIFILE pAVIFile;
385 // PAVISTREAM pAVIStream;
386 // PAVISTREAM pAVICompressed;
387 // AVICOMPRESSOPTIONS opts;
388 // DWORD dwAVIFileSize;
392 // HBITMAP hBmpRec, hOldBmpRec;
394 // scrntype* lpBmpRec;
396 bool use_video_thread;
399 AG_Thread hVideoThread;
401 //video_thread_t video_thread_param;
403 // ----------------------------------------
405 // ----------------------------------------
406 void initialize_sound();
407 void release_sound();
408 void update_sound(int* extra_frames);
409 //void AudioCallbackSDL(void *udata, Uint8 *stream, int len);
411 sdl_snddata_t snddata;
412 int sound_rate, sound_samples;
413 bool sound_ok, sound_started, now_mute;
414 SDL_AudioSpec SndSpecReq, SndSpecPresented;
415 //Uint8 iTotalVolume;
421 _TCHAR sound_file_name[_MAX_PATH];
423 _TCHAR sound_file_name[AG_PATHNAME_MAX];
431 HBITMAP hBmp, hOldBmp;
436 #ifdef USE_SCREEN_ROTATE
439 HBITMAP hBmpRotate, hOldBmpRotate;
441 scrntype* lpBmpRotate;
442 LPBITMAPINFO lpDibRotate;
447 HBITMAP hBmpStretch1, hOldBmpStretch1;
448 LPBYTE lpBufStretch1;
449 scrntype* lpBmpStretch1;
450 LPBITMAPINFO lpDibStretch1;
453 HBITMAP hBmpStretch2, hOldBmpStretch2;
454 LPBYTE lpBufStretch2;
455 scrntype* lpBmpStretch2;
456 LPBITMAPINFO lpDibStretch2;
460 LPDIRECT3DDEVICE9 lpd3d9Device;
461 LPDIRECT3DSURFACE9 lpd3d9Surface;
462 LPDIRECT3DSURFACE9 lpd3d9OffscreenSurface;
463 scrntype *lpd3d9Buffer;
464 bool render_to_d3d9Buffer;
468 _TCHAR video_file_name[_MAX_PATH];
470 double rec_video_run_frames;
471 double rec_video_frames;
474 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
476 LPBITMAPINFO lpDibRec;
478 PAVISTREAM pAVIStream;
479 PAVISTREAM pAVICompressed;
480 AVICOMPRESSOPTIONS opts;
485 HBITMAP hBmpRec, hOldBmpRec;
489 bool use_video_thread;
491 video_thread_t video_thread_param;
493 void initialize_sound();
494 void release_sound();
495 void update_sound(int* extra_frames);
497 int sound_rate, sound_samples;
498 bool sound_ok, sound_started, now_mute;
503 // ----------------------------------------
505 // ----------------------------------------
506 #if defined(_USE_AGAR) || defined(_USE_QT)
510 LPDIRECTSOUNDBUFFER lpdsb, lpdsp;
514 _TCHAR sound_file_name[_MAX_PATH];
521 #if defined(_USE_AGAR)
522 // ----------------------------------------
524 // ----------------------------------------
525 void initialize_display_agar();
526 void release_display_agar();
527 #elif defined(_USE_QT)
528 #ifdef USE_LASER_DISC
529 double movie_frame_rate;
530 int movie_sound_rate;
531 bool now_movie_play, now_movie_pause;
534 #ifdef USE_DIRECT_SHOW
535 // ----------------------------------------
537 // ----------------------------------------
538 void initialize_direct_show();
539 void release_direct_show();
540 void create_direct_show_dib_section();
541 void release_direct_show_dib_section();
543 IGraphBuilder *pGraphBuilder;
544 IBaseFilter *pVideoBaseFilter;
545 IBaseFilter *pCaptureBaseFilter;
546 ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
547 ISampleGrabber *pVideoSampleGrabber;
548 IBaseFilter *pSoundBaseFilter;
549 ISampleGrabber *pSoundSampleGrabber;
550 CMySampleGrabberCB *pSoundCallBack;
551 IMediaControl *pMediaControl;
552 IMediaSeeking *pMediaSeeking;
553 IMediaPosition *pMediaPosition;
554 IVideoWindow *pVideoWindow;
555 IBasicVideo *pBasicVideo;
556 IBasicAudio *pBasicAudio;
557 bool bTimeFormatFrame;
558 bool bVerticalReversed;
561 HBITMAP hBmpDShow, hOldBmpDShow;
563 scrntype* lpBmpDShow;
564 LPBITMAPINFO lpDibDShow;
566 int direct_show_width, direct_show_height;
567 bool direct_show_mute[2];
568 #ifdef USE_LASER_DISC
569 double movie_frame_rate;
570 int movie_sound_rate;
571 bool now_movie_play, now_movie_pause;
573 #ifdef USE_VIDEO_CAPTURE
574 void enum_capture_devs();
575 bool connect_capture_dev(int index, bool pin);
576 int cur_capture_dev_index;
577 int num_capture_devs;
578 _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
583 // ----------------------------------------
585 // ----------------------------------------
587 _TCHAR path[_MAX_PATH];
594 media_status_t cart_status[MAX_CART];
597 media_status_t disk_status[MAX_FD];
600 media_status_t quickdisk_status[MAX_QD];
603 media_status_t tape_status;
605 #ifdef USE_LASER_DISC
606 media_status_t laser_disc_status;
609 void initialize_media();
611 void restore_media();
613 void clear_media_status(media_status_t *status)
615 status->path[0] = _T('\0');
616 status->wait_count = 0;
619 // ----------------------------------------
621 // ----------------------------------------
622 void initialize_printer();
623 void release_printer();
624 void reset_printer();
625 void update_printer();
626 void open_printer_file();
627 void close_printer_file();
629 _TCHAR prn_file_name[_MAX_PATH];
631 _TCHAR prn_file_name[AG_PATHNAME_MAX];
634 int prn_data, prn_wait_frames;
638 // ----------------------------------------
640 // ----------------------------------------
641 void initialize_socket();
642 void release_socket();
643 void update_socket();
646 bool is_tcp[SOCKET_MAX];
647 struct sockaddr_in udpaddr[SOCKET_MAX];
648 int socket_delay[SOCKET_MAX];
649 char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
650 int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
654 // ----------------------------------------
656 // ----------------------------------------
657 void initialize_debugger();
658 void release_debugger();
659 #if defined(_USE_AGAR)
660 AG_Thread hDebuggerThread;
661 #elif defined(_USE_QT)
663 HANDLE hDebuggerThread;
665 debugger_thread_t debugger_thread_param;
669 // ----------------------------------------
671 // ----------------------------------------
672 void initialize_debug_log();
673 void release_debug_log();
678 // ----------------------------------------
680 // ----------------------------------------
681 void save_state_tmp(_TCHAR* file_path);
682 bool load_state_tmp(_TCHAR* file_path);
685 // ----------------------------------------
687 // ----------------------------------------
691 #ifdef USE_SOUND_DEVICE_TYPE
692 int sound_device_type;
694 _TCHAR app_path[_MAX_PATH];
698 bool bDrawLine[SCREEN_HEIGHT];
699 uint32_t *getJoyStatPtr(void) {
703 // ----------------------------------------
705 // ----------------------------------------
706 #if defined(_USE_AGAR)
707 EMU(AG_Window *hwnd, AG_Widget *hinst);
708 #elif defined(_USE_QT)
709 EMU(class Ui_MainWindow*, GLDrawClass*);
711 EMU(HWND hwnd, HINSTANCE hinst);
715 _TCHAR* application_path()
719 _TCHAR* bios_path(_TCHAR* file_name);
720 #if defined(_USE_AGAR) || defined(_USE_SDL) || defined(_USE_QT)
721 // To be thread safety.
723 if(pVMSemaphore) SDL_SemWait(pVMSemaphore);
725 void UnlockVM(void) {
726 if(pVMSemaphore) SDL_SemPost(pVMSemaphore);
730 QImage *getPseudoVramClass(void) { return pPseudoVram;}
732 // ----------------------------------------
734 // ----------------------------------------
735 #if defined(_USE_AGAR)
736 AG_Window *main_window_handle;
737 AG_Widget *instance_handle;
740 #elif defined(_USE_QT)
741 class Ui_MainWindow *main_window_handle;
742 GLDrawClass *instance_handle;
746 HWND main_window_handle;
747 HINSTANCE instance_handle;
750 // drive virtual machine
751 int frame_interval();
754 #ifdef USE_SPECIAL_RESET
755 void special_reset();
758 void notify_power_off();
765 _TCHAR path[_MAX_PATH];
767 // _TCHAR name[128]; // Convert to UTF8
769 // } bank[MAX_D88_BANKS];
770 _TCHAR disk_name[MAX_D88_BANKS][128]; // Convert to UTF8
775 int get_access_lamp(void);
779 void open_cart(int drv, _TCHAR* file_path);
780 void close_cart(int drv);
781 bool cart_inserted(int drv);
784 void open_disk(int drv, _TCHAR* file_path, int bank);
785 void close_disk(int drv);
786 bool disk_inserted(int drv);
787 bool is_write_protected_fd(int drv);
788 void write_protect_fd(int drv, bool flag);
791 void open_quickdisk(int drv, _TCHAR* file_path);
792 void close_quickdisk(int drv);
793 bool quickdisk_inserted(int drv);
796 void play_tape(_TCHAR* file_path);
797 void rec_tape(_TCHAR* file_path);
799 bool tape_inserted();
802 return vm->get_tape_ptr();
806 #ifdef USE_TAPE_BUTTON
809 void push_fast_forward();
810 void push_fast_rewind();
811 void push_apss_forward();
812 void push_apss_rewind();
813 bool get_tape_play(void)
815 return vm->get_tape_play();
818 #ifdef USE_LASER_DISC
819 void open_laser_disc(_TCHAR* file_path);
820 void close_laser_disc();
821 bool laser_disc_inserted();
823 #ifdef USE_BINARY_FILE1
824 void load_binary(int drv, _TCHAR* file_path);
825 void save_binary(int drv, _TCHAR* file_path);
829 void start_rec_sound();
830 void stop_rec_sound();
831 void restart_rec_sound();
834 void capture_screen();
835 bool start_rec_video(int fps);
836 void stop_rec_video();
837 void restart_rec_video();
840 void update_config();
849 void key_mod(uint32 mod) {
853 void key_down(int code, bool repeat);
854 void key_up(int code);
855 void key_lost_focus()
859 uint32 recent_key_sym;
860 uint32 recent_key_mod;
861 uint32 recent_key_unicode;
863 void press_button(int num);
867 void disenable_mouse();
869 bool get_mouse_enabled()
871 return mouse_enabled;
875 void start_auto_key();
876 void stop_auto_key();
879 return (autokey_phase != 0);
884 int get_window_width(int mode);
885 int get_window_height(int mode);
886 void set_display_size(int width, int height, bool window_mode);
888 #if defined(_USE_AGAR)
889 void update_screen(AG_Widget *target);
890 #elif defined(_USE_QT)
891 void update_screen(GLDrawClass *glv);
893 void update_screen(HDC hdc);
898 first_invalidate = true;
905 #ifdef USE_VIDEO_CAPTURE
907 int get_cur_capture_dev_index()
909 return cur_capture_dev_index;
911 int get_num_capture_devs()
913 return num_capture_devs;
915 _TCHAR* get_capture_dev_name(int index)
917 return capture_dev_name[index];
919 void open_capture_dev(int index, bool pin);
920 void close_capture_dev();
921 void show_capture_dev_filter();
922 void show_capture_dev_pin();
923 void show_capture_dev_source();
928 int get_socket(int ch)
932 void socket_connected(int ch);
933 void socket_disconnected(int ch);
934 void send_data(int ch);
935 void recv_data(int ch);
940 void open_debugger(int cpu_index);
941 void close_debugger();
942 bool debugger_enabled(int cpu_index);
946 // ----------------------------------------
947 // for virtual machine
948 // ----------------------------------------
953 #if defined(_USE_AGAR)
955 #elif defined(_USE_QT)
958 PostMessage(main_window_handle, WM_CLOSE, 0, 0L);
977 void change_screen_size(int sw, int sh, int swa, int sha, int ww, int wh);
978 int get_screen_width_aspect(void) {return screen_width_aspect;}
979 int get_screen_height_aspect(void) {return screen_height_aspect;}
980 scrntype* screen_buffer(int y);
981 #ifdef USE_CRT_FILTER
982 bool screen_skip_line;
986 void get_host_time(cur_time_t* time);
989 void printer_out(uint8 value);
990 void printer_strobe(bool value);
992 #ifdef USE_DIRECT_SHOW
994 void get_direct_show_buffer();
995 void mute_direct_show_dev(bool l, bool r);
997 #ifdef USE_LASER_DISC
998 bool open_movie_file(_TCHAR* file_path);
999 void close_movie_file();
1005 double get_movie_frame_rate()
1007 return movie_frame_rate;
1009 int get_movie_sound_rate()
1011 return movie_sound_rate;
1013 void set_cur_movie_frame(int frame, bool relative);
1014 uint32 get_cur_movie_frame();
1016 #ifdef USE_VIDEO_CAPTURE
1017 void set_capture_dev_channel(int ch);
1023 bool init_socket_tcp(int ch);
1024 bool init_socket_udp(int ch);
1025 bool connect_socket(int ch, uint32 ipaddr, int port);
1026 void disconnect_socket(int ch);
1027 bool listen_socket(int ch);
1028 void send_data_tcp(int ch);
1029 void send_data_udp(int ch, uint32 ipaddr, int port);
1033 void out_debug_log(const _TCHAR* format, ...);
1035 void out_message(const _TCHAR* format, ...);
1037 _TCHAR message[_MAX_PATH];