2 Skelton for retropc emulator
4 Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
21 #include "../config.h"
22 #include "../fileio.h"
30 SDL_sem **pSndApplySem;
39 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
40 ISampleGrabberCB : public IUnknown {
42 virtual HRESULT STDMETHODCALLTYPE SampleCB( double SampleTime,IMediaSample *pSample) = 0;
43 virtual HRESULT STDMETHODCALLTYPE BufferCB( double SampleTime,BYTE *pBuffer,long BufferLen) = 0;
45 EXTERN_C const IID IID_ISampleGrabber;
46 MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
47 ISampleGrabber : public IUnknown {
49 virtual HRESULT STDMETHODCALLTYPE SetOneShot( BOOL OneShot) = 0;
50 virtual HRESULT STDMETHODCALLTYPE SetMediaType( const AM_MEDIA_TYPE *pType) = 0;
51 virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType( AM_MEDIA_TYPE *pType) = 0;
52 virtual HRESULT STDMETHODCALLTYPE SetBufferSamples( BOOL BufferThem) = 0;
53 virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer( /* [out][in] */ long *pBufferSize,/* [out] */ long *pBuffer) = 0;
54 virtual HRESULT STDMETHODCALLTYPE GetCurrentSample( /* [retval][out] */ IMediaSample **ppSample) = 0;
55 virtual HRESULT STDMETHODCALLTYPE SetCallback( ISampleGrabberCB *pCallback,long WhichMethodToCallback) = 0;
58 #ifdef USE_MOVIE_PLAYER
59 class CMySampleGrabberCB : public ISampleGrabberCB {
63 CMySampleGrabberCB(VM *vm_ptr)
67 STDMETHODIMP_(ULONG) AddRef()
71 STDMETHODIMP_(ULONG) Release()
75 STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
77 if(riid == IID_ISampleGrabberCB || riid == IID_IUnknown) {
78 *ppv = (void *) static_cast<ISampleGrabberCB*>(this);
83 STDMETHODIMP SampleCB(double SampleTime, IMediaSample *pSample)
87 STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize)
89 vm->movie_sound_callback(pBuffer, lBufferSize);
96 #define WM_RESIZE (WM_USER + 1)
97 #define WM_SOCKET0 (WM_USER + 2)
98 #define WM_SOCKET1 (WM_USER + 3)
99 #define WM_SOCKET2 (WM_USER + 4)
100 #define WM_SOCKET3 (WM_USER + 5)
104 #define SOCKET_BUFFER_MAX 0x100000
107 #ifdef USE_VIDEO_CAPTURE
108 #define MAX_CAPTURE_DEVS 8
111 // check memory leaks
113 //#define _CRTDBG_MAP_ALLOC
114 //#include <crtdbg.h>
115 //#define malloc(s) _malloc_dbg(s, _NORMAL_BLOCK, __FILE__, __LINE__)
116 //#define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
119 typedef struct screen_buffer_s {
121 //HBITMAP hBmp, hOldBmp;
128 //PAVISTREAM pAVICompressed;
130 //LPBITMAPINFOHEADER pbmInfoHeader;
135 } rec_video_thread_param_t;
138 class EmuThreadClass;
139 class DrawThreadClass;
145 class OSD : public QThread
151 EmuThreadClass *parent_thread;
153 _TCHAR auto_key_str[2048];
154 sdl_snddata_t snddata;
156 _TCHAR app_path[_MAX_PATH];
159 FILE *hStdIn, *hStdOut;
162 void initialize_input();
163 void release_input();
164 void key_down_sub(int code, bool repeat);
165 void key_up_sub(int code);
166 scrntype *get_buffer(screen_buffer_t *p, int y);
168 // bool dinput_joy_ok;
170 uint8 keycode_conv[256];
171 uint8 key_status[256]; // windows key code mapping
172 uint8 key_dik_prev[256];
173 #ifdef USE_SHIFT_NUMPAD_KEY
174 uint8 key_converted[256];
175 bool key_shift_pressed, key_shift_released;
177 uint32_t modkey_status;
180 uint32 joy_status[2]; // joystick #1, #2 (b0 = up, b1 = down, b2 = left, b3 = right, b4- = buttons
184 int mouse_status[3]; // x, y, button (b0 = left, b1 = right)
191 Qt::CursorShape mouse_shape;
194 FIFO* autokey_buffer;
195 int autokey_phase, autokey_shift;
196 int autokey_table[256];
202 void initialize_screen();
203 void release_screen();
204 void initialize_screen_buffer(screen_buffer_t *buffer, int width, int height, int mode);
205 void release_screen_buffer(screen_buffer_t *buffer);
206 #ifdef USE_CRT_FILTER
207 void apply_crt_fileter_to_screen_buffer(screen_buffer_t *source, screen_buffer_t *dest);
208 void apply_crt_filter_x3_y3(screen_buffer_t *source, screen_buffer_t *dest);
209 void apply_crt_filter_x3_y2(screen_buffer_t *source, screen_buffer_t *dest);
210 void apply_crt_filter_x2_y3(screen_buffer_t *source, screen_buffer_t *dest);
211 void apply_crt_filter_x2_y2(screen_buffer_t *source, screen_buffer_t *dest);
212 void apply_crt_filter_x1_y1(screen_buffer_t *source, screen_buffer_t *dest);
214 #ifdef USE_SCREEN_ROTATE
215 void rotate_screen_buffer(screen_buffer_t *source, screen_buffer_t *dest);
217 void stretch_screen_buffer(screen_buffer_t *source, screen_buffer_t *dest);
218 int add_video_frames();
220 screen_buffer_t vm_screen_buffer;
221 screen_buffer_t video_screen_buffer;
222 #ifdef USE_CRT_FILTER
223 screen_buffer_t filtered_screen_buffer;
225 screen_buffer_t* draw_screen_buffer;
227 int host_window_width, host_window_height;
228 bool host_window_mode;
229 int base_window_width, base_window_height;
230 int vm_screen_width, vm_screen_height, vm_screen_width_aspect, vm_screen_height_aspect;
231 int draw_screen_width, draw_screen_height;
234 _TCHAR video_file_name[_MAX_PATH];
236 double rec_video_run_frames;
237 double rec_video_frames;
239 //LPBITMAPINFO lpDibRec;
241 //PAVISTREAM pAVIStream;
242 //PAVISTREAM pAVICompressed;
243 //AVICOMPRESSOPTIONS AVIOpts;
246 //HANDLE hVideoThread;
247 rec_video_thread_param_t rec_video_thread_param;
249 bool first_draw_screen;
250 bool first_invalidate;
251 bool self_invalidate;
254 void initialize_sound(int rate, int samples);
255 void release_sound();
257 int sound_rate, sound_samples;
258 bool sound_ok, sound_started, now_mute;
259 bool sound_first_half;
261 _TCHAR sound_file_name[_MAX_PATH];
262 FILEIO* rec_sound_fio;
264 int rec_sound_buffer_ptr;
267 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
269 void initialize_video();
270 void release_video();
272 //IGraphBuilder *pGraphBuilder;
273 //IBaseFilter *pVideoBaseFilter;
274 //IBaseFilter *pCaptureBaseFilter;
275 //ICaptureGraphBuilder2 *pCaptureGraphBuilder2;
276 //ISampleGrabber *pVideoSampleGrabber;
277 //IBaseFilter *pSoundBaseFilter;
278 //ISampleGrabber *pSoundSampleGrabber;
279 //CMySampleGrabberCB *pSoundCallBack;
280 //IMediaControl *pMediaControl;
281 //IMediaSeeking *pMediaSeeking;
282 //IMediaPosition *pMediaPosition;
283 //IVideoWindow *pVideoWindow;
284 //IBasicVideo *pBasicVideo;
285 //IBasicAudio *pBasicAudio;
286 //bool bTimeFormatFrame;
287 //bool bVerticalReversed;
289 screen_buffer_t dshow_screen_buffer;
290 int direct_show_width, direct_show_height;
291 bool direct_show_mute[2];
293 #ifdef USE_MOVIE_PLAYER
294 double movie_frame_rate;
295 int movie_sound_rate;
297 #ifdef USE_VIDEO_CAPTURE
298 void enum_capture_devs();
299 bool connect_capture_dev(int index, bool pin);
300 int cur_capture_dev_index;
301 int num_capture_devs;
302 _TCHAR capture_dev_name[MAX_CAPTURE_DEVS][256];
304 _TCHAR prn_file_name[_MAX_PATH];
306 int prn_data, prn_wait_frames;
311 void initialize_socket();
312 void release_socket();
315 bool is_tcp[SOCKET_MAX];
316 //struct sockaddr_in udpaddr[SOCKET_MAX];
317 int socket_delay[SOCKET_MAX];
318 char recv_buffer[SOCKET_MAX][SOCKET_BUFFER_MAX];
319 int recv_r_ptr[SOCKET_MAX], recv_w_ptr[SOCKET_MAX];
329 class Ui_MainWindow *main_window_handle;
332 void initialize(int rate, int samples);
337 _TCHAR* application_path()
341 _TCHAR* bios_path(const _TCHAR* file_name);
342 void get_host_time(cur_time_t* time);
343 void sleep(uint32 ms);
344 void create_date_file_name(_TCHAR *name, int length, _TCHAR *extension);
347 void open_console(_TCHAR* title);
348 void close_console();
349 unsigned int get_console_code_page();
350 bool is_console_active();
351 void set_console_text_attribute(unsigned short attr);
352 void write_console(_TCHAR* buffer, unsigned int length);
353 int read_console_input(_TCHAR* buffer);
357 void key_down(int code, bool repeat);
358 void key_up(int code);
359 void key_lost_focus()
363 #ifdef ONE_BOARD_MICRO_COMPUTER
364 void press_button(int num);
366 # if !defined(Q_OS_WIN) && !defined(Q_OS_CYGWIN)
367 uint16_t GetAsyncKeyState(uint32_t vk); // Win32 GetAsyncKeyState() wrappeer.
369 void key_mod(uint32 mod) {
373 void disenable_mouse();
375 bool get_mouse_enabled()
377 return mouse_enabled;
379 //QImage *getPseudoVramClass(void) { return pPseudoVram;}
380 void setMousePointer(int x, int y) {
384 void setMouseButton(int button) {
385 mouse_button = button;
387 int getMouseButton() {
391 void start_auto_key();
392 void stop_auto_key();
395 return (autokey_phase != 0);
412 void reset_printer() {
413 close_printer_file();
417 void update_printer() {
418 if(prn_fio->IsOpened() && --prn_wait_frames == 0) {
419 close_printer_file();
422 void printer_out(uint8 value) {
425 void printer_strobe(bool value) {
426 bool falling = (prn_strobe && !value);
430 if(!prn_fio->IsOpened()) {
436 prn_fio->Fputc(prn_data);
438 #ifdef SUPPORT_VARIABLE_TIMING
439 prn_wait_frames = (int)(vm->frame_rate() * 10.0 + 0.5);
441 prn_wait_frames = (int)(FRAMES_PER_SEC * 10.0 + 0.5);
446 void initialize_printer();
447 void release_printer();
448 void open_printer_file() {
449 create_date_file_name(prn_file_name, _MAX_PATH, _T("txt"));
450 prn_fio->Fopen(bios_path(prn_file_name), FILEIO_WRITE_BINARY);
453 void close_printer_file() {
454 if(prn_fio->IsOpened()) {
455 // remove if the file size is less than 2 bytes
456 bool remove = (prn_fio->Ftell() < 2);
459 FILEIO::RemoveFile(bios_path(prn_file_name));
465 int get_window_width(int mode);
466 int get_window_height(int mode);
467 void set_window_size(int window_width, int window_height, bool window_mode);
468 void set_vm_screen_size(int width, int height, int width_aspect, int height_aspect, int window_width, int window_height);
469 scrntype* get_vm_screen_buffer(int y);
471 #ifdef ONE_BOARD_MICRO_COMPUTER
474 first_invalidate = true;
477 void capture_screen();
478 bool start_rec_video(int fps);
479 void stop_rec_video();
480 void restart_rec_video();
481 void add_extra_frames(int extra_frames);
483 #ifdef USE_CRT_FILTER
484 bool screen_skip_line;
488 void update_sound(int* extra_frames);
491 void start_rec_sound();
492 void stop_rec_sound();
493 void restart_rec_sound();
496 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
497 // common video device
498 void get_video_buffer();
499 void mute_video_dev(bool l, bool r);
501 #ifdef USE_MOVIE_PLAYER
502 bool open_movie_file(const _TCHAR* file_path);
503 void close_movie_file();
507 double get_movie_frame_rate()
509 return movie_frame_rate;
511 int get_movie_sound_rate()
513 return movie_sound_rate;
515 void set_cur_movie_frame(int frame, bool relative);
516 uint32 get_cur_movie_frame();
517 bool now_movie_play, now_movie_pause;
519 #ifdef USE_VIDEO_CAPTURE
520 int get_cur_capture_dev_index()
522 return cur_capture_dev_index;
524 int get_num_capture_devs()
526 return num_capture_devs;
528 _TCHAR* get_capture_dev_name(int index)
530 return capture_dev_name[index];
532 void open_capture_dev(int index, bool pin);
533 void close_capture_dev();
534 void show_capture_dev_filter();
535 void show_capture_dev_pin();
536 void show_capture_dev_source();
537 void set_capture_dev_channel(int ch);
542 int get_socket(int ch)
546 void socket_connected(int ch);
547 void socket_disconnected(int ch);
548 void update_socket();
549 bool init_socket_tcp(int ch);
550 bool init_socket_udp(int ch);
551 bool connect_socket(int ch, uint32 ipaddr, int port);
552 void disconnect_socket(int ch);
553 bool listen_socket(int ch);
554 void send_data_tcp(int ch);
555 void send_data_udp(int ch, uint32 ipaddr, int port);
556 void send_data(int ch);
557 void recv_data(int ch);
561 void update_screen();
562 void set_parent_thread(EmuThreadClass *parent);
566 void unlock_vm(void){
571 void set_auto_key_string(QByteArray);
574 int sig_update_screen(screen_buffer_t *);
575 int sig_save_screen(const char *);
576 int sig_close_window(void);
577 int sig_resize_vm_screen(QImage *, int, int);