#LIB_INSTALL="/usr/local/lib/"
#LIB_INSTALL="/usr/lib/x86_64-linux-gnu/"
-CMAKE_APPENDFLAG="-DCMAKE_AR:STRING=gcc-ar-6 -DCMAKE_NM:STRING=gcc-nm-6 -DCMAKE_RANLIB:STRING=gcc-ranlib-6"
+CMAKE_APPENDFLAG="-DUSE_MOVIE_SAVER=ON -DUSE_MOVIE_LOADER=ON -DCMAKE_AR:STRING=gcc-ar-6 -DCMAKE_NM:STRING=gcc-nm-6 -DCMAKE_RANLIB:STRING=gcc-ranlib-6"
CMAKE_LINKFLAG="-static-libstdc++ -static-libgcc"
+CMAKE_APPENDFLAG="-DUSE_QT5_4_APIS=ON"
#CMAKE_APPENDFLAG="-DCMAKE_AR:STRING=i686-w64-mingw32-gcc-ar \
# -DCMAKE_LD:STRING=i686-w64-mingw32-gcc-ld \
# -DCMAKE_NM:STRING=i686-w64-mingw32-gcc-nm \
# -DCMAKE_RANLIB:STRING=i686-w64-mingw32-gcc-ranlib \
# "
-#CMAKE_APPENDFLAG="-DCMAKE_AR:STRING=i686-w64-mingw32-gcc-ar \
-# -DCMAKE_NM:STRING=i686-w64-mingw32-gcc-nm \
-## -DCMAKE_RANLIB:STRING=i686-w64-mingw32-gcc-ranlib \
-# "
-
rec_fps = fps;
p_osd = osd;
recording = false;
-#if defined(MOVIE_SAVER)
+#if defined(USE_MOVIE_SAVER)
memset(audio_frame, 0x00, sizeof(audio_frame));
memset(video_frame, 0x00, sizeof(video_frame));
memset(video_dst, 0x00, sizeof(video_dst));
void MOVIE_SAVER::enqueue_video(QByteArray *p, int width, int height)
{
-#if defined(MOVIE_SAVER)
+#if defined(USE_MOVIE_SAVER)
if(!recording) return;
if(p == NULL) return;
QByteArray *pp = new QByteArray(p->data(), p->size());
if(p == NULL) return false;
QByteArray *pp = video_data_queue.dequeue();
-#if defined(MOVIE_SAVER)
- if((pp == NULL) || (video_size <= 0)) return false;
+#if defined(USE_MOVIE_SAVER)
+ if(pp == NULL) return false;
video_size = pp->size();
+ if(video_size <= 0) return false;
memcpy(p, pp->data(), video_size);
#else
video_size = 0;
void MOVIE_SAVER::enqueue_audio(QByteArray *p)
{
-#if defined(MOVIE_SAVER)
+#if defined(USE_MOVIE_SAVER)
if(!recording) return;
if(p == NULL) return;
QByteArray *pp = new QByteArray(p->data(), p->size());
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Enqueue audio data %d bytes", p->size());
audio_data_queue.enqueue(pp);
#endif
}
if(audio_data_queue.isEmpty()) return false;
if(p == NULL) return false;
QByteArray *pp = audio_data_queue.dequeue();
-#if defined(MOVIE_SAVER)
- if((pp == NULL) || (audio_size <= 0)) return false;
+#if defined(USE_MOVIE_SAVER)
+ if(pp == NULL) return false;
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Dequeue audio data %d bytes", pp->size());
audio_size = pp->size();
- memcpy(p, pp->data(), audio_size);
+ if(audio_size <= 0) return false;
+ memcpy(p, pp->constData(), audio_size);
#else
audio_size = 0;
#endif
return true;
}
+
+
+int MOVIE_SAVER::write_audio_frame(const void *_time_base, void *_pkt)
+{
+#if defined(USE_LIBAV)
+ AVFormatContext *fmt_ctx = output_context;
+ AVStream *st = (AVStream *)audio_stream;
+ AVRational *time_base = (AVRational *)_time_base;
+ AVPacket *pkt = (AVPacket *)_pkt;
+
+ /* rescale output packet timestamp values from codec to stream timebase */
+ av_packet_rescale_ts(pkt, *time_base, st->time_base);
+ pkt->stream_index = st->index;
+ /* Write the compressed frame to the media file. */
+ //log_packet(fmt_ctx, pkt);
+ return av_interleaved_write_frame(fmt_ctx, pkt);
+#else
+ return -1;
+#endif
+}
+
void MOVIE_SAVER::run()
{
bRunThread = true;
+ //AGAR_DebugLog(AGAR_LOG_DEBUG, "MOVIE THREAD: Start");
+ AVCodecContext *c;
+ AVPacket pkt = { 0 }; // data and size must be 0;
+ AVFrame *frame;
+ int ret;
+ int got_packet;
+ int dst_nb_samples;
+
int fps_wait = (int)((1000.0 / p_osd->vm_frame_rate()) / 2.0);
int tmp_wait = fps_wait;
+ int ncount_audio = 0;
+ int ncount_video = 0;
+
while(bRunThread) {
if(recording) {
if(!bRunThread) break;
uint64_t us = (uint64_t)floor(((double)bytes * 1000000.0) / (double)audio_codec->sample_rate);
double samples = ((double)us / 1000000.0) * (double)audio_codec->sample_rate;
int ret;
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Write audio data %d bytes", bytes);
if(bytes == 0) goto _video;
av_init_packet(&pkt);
- pkt.dts = pkt.pts = (int64_t)samples;
- pkt.flags |= AV_PKT_FLAG_KEY;
- pkt.data = (uint8_t *)audio_frame;
- pkt.size = (uint32_t)bytes;
- pkt.stream_index = 1;
- ret = av_write_frame(output_context, &pkt);
+ {
+ frame = audio_tmp_frame;
+ if (av_compare_ts(audio_next_pts, audio_stream->codec->time_base,
+ (double)fps_wait, (AVRational){ 1, 1 }) >= 0)
+ goto _video;
+ frame->pts = audio_next_pts;
+ audio_next_pts += frame->nb_samples;
+ }
+
+ /* convert samples from native format to destination codec format, using the resampler */
+ /* compute destination number of samples */
+ audio_dst_nb_samples = av_rescale_rnd(swr_get_delay(audio_swr_context, audio_codec->sample_rate)
+ + frame->nb_samples,
+ audio_codec->sample_rate,
+ audio_codec->sample_rate,
+ AV_ROUND_UP);
+ //av_assert0(audio_dst_nb_samples == frame->nb_samples);
+ /* when we pass a frame to the encoder, it may keep a reference to it
+ * internally;
+ * make sure we do not overwrite it here
+ */
+ ret = av_frame_make_writable(frame);
+ if (ret < 0) {
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie/Audio: Error while converting\n");
+ do_close();
+ continue;
+ }
+ /* convert to destination format */
+ ret = swr_convert(audio_swr_context,
+ frame->data, audio_dst_nb_samples,
+ (const uint8_t **)frame->data, frame->nb_samples);
+ if (ret < 0) {
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie/Audio: Error while converting\n");
+ do_close();
+ continue;
+ }
+ frame->pts = av_rescale_q(audio_samples_count, (AVRational){1, audio_codec->sample_rate},
+ audio_codec->time_base);
+ audio_samples_count += dst_nb_samples;
+ ret = avcodec_encode_audio2(audio_codec, &pkt, frame, &got_packet);
+ if (ret < 0) {
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie/Audio : Error encoding audio frame\n");
+ do_close();
+ continue;
+ }
+ if (got_packet) {
+ ret = write_audio_frame((const void *)(&audio_codec->time_base), (void *)(&pkt));
+ if (ret < 0) {
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie/Audio Error while writing audio frame\n");
+ do_close();
+ continue;
+ }
+ }
#endif // defined(USE_LIBAV)
totalAudioFrame++;
+ ncount_audio++;
}
}
-_video:
- if(0) {
+ _video:
+ if(0) {
+ }
}
+ if(ncount_audio > 10) {
+ ncount_audio = 0;
}
+
if(fps_wait >= tmp_wait) {
this->msleep(tmp_wait);
tmp_wait = 0;
void MOVIE_SAVER::do_close()
{
+ int i;
#if defined(USE_LIBAV)
if(output_context != NULL) {
av_write_trailer(output_context);
avio_close(output_context->pb);
+ //av_freep(&output_context->pb);
}
if(audio_stream != NULL) {
av_free(audio_stream);
video_height_queue.clear();
// Message
- AGAR_DebugLog(AGAR_LOG_DEBUG, "MOVIE: Close: Read: Video %ll frames, Audio %ll frames", totalSrcFrame, totalAudioFrame);
- AGAR_DebugLog(AGAR_LOG_DEBUG, "MOVIE: Close: Write: Video %ll frames, Audio %ll frames", totalDstFrame, totalAudioFrame);
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "MOVIE: Close: Read: Video %q frames, Audio %q frames", totalSrcFrame, totalAudioFrame);
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "MOVIE: Close: Write: Video %q frames, Audio %q frames", totalDstFrame, totalAudioFrame);
totalSrcFrame = 0;
totalDstFrame = 0;
totalAudioFrame = 0;
{
return recording;
}
-#if defined(MOVIE_SAVER) && defined(USE_LIBAV)
+#if defined(USE_MOVIE_SAVER) && defined(USE_LIBAV)
static const AVRational time_base_15 = (AVRational){1001, 14485};
static const AVRational time_base_24 = (AVRational){1001, 23976};
static const AVRational time_base_25 = (AVRational){1001, 25025};
static const AVRational time_base_30 = (AVRational){1001, 29970};
static const AVRational time_base_60 = (AVRational){1001, 59940};
-#endif // defined(MOVIE_SAVER) && defined(USE_LIBAV)
+#endif // defined(USE_MOVIE_SAVER) && defined(USE_LIBAV)
-void MOVIE_SAVER::do_open(QString filename)
+AVFrame *MOVIE_SAVER::alloc_audio_frame(enum AVSampleFormat sample_fmt,
+ uint64_t channel_layout,
+ int sample_rate, int nb_samples)
+{
+ AVFrame *frame = av_frame_alloc();
+ int ret;
+ if (!frame) {
+ fprintf(stderr, "Error allocating an audio frame\n");
+ //exit(1);
+ return NULL;
+ }
+ frame->format = sample_fmt;
+ frame->channel_layout = channel_layout;
+ frame->sample_rate = sample_rate;
+ frame->nb_samples = nb_samples;
+ if (nb_samples) {
+ ret = av_frame_get_buffer(frame, 0);
+ if (ret < 0) {
+ fprintf(stderr, "Error allocating an audio buffer\n");
+ return NULL;
+ }
+ }
+ return frame;
+}
+
+void MOVIE_SAVER::do_open(QString filename, int fps)
{
do_close();
+ do_set_record_fps(fps);
_filename = filename;
#if defined(USE_LIBAV)
- format = av_guess_format("mp4", NULL, NULL);
-
+ av_register_all();
+ format = av_guess_format(NULL, filename.toLocal8Bit().constData(), NULL);
+ printf("%s\n", filename.toLocal8Bit().constData());
if(format == NULL) {
AGAR_DebugLog(AGAR_LOG_DEBUG, "AVC ERROR: Failed to initialize libavf");
return;
video_codec->has_b_frames = 1;
QString author = QString::fromUtf8("emu");
author = author + p_osd->get_vm_config_name();
- QString date_str = QString::fromUtf8("Record from");
+ QString date_str = QString::fromUtf8("Record from ");
date_str = date_str + create_date_file_name();
+ switch(rec_fps) {
+ case 15:
+ time_base = time_base_15;
+ break;
+ case 24:
+ time_base = time_base_24;
+ break;
+ case 25:
+ time_base = time_base_25;
+ break;
+ case 30:
+ time_base = time_base_30;
+ break;
+ case 60:
+ time_base = time_base_60;
+ break;
+ default:
+ time_base = (AVRational){1001, rec_fps * 1000};
+ break;
+ }
{ // Video Start
av_dict_set(&output_context->metadata, "title", date_str.toUtf8().constData(), 0);
av_dict_set(&output_context->metadata, "author", author.toUtf8().constData(), 0);
return;
}
+ audio_next_pts = 0;
+ audio_dst_nb_samples = 0;
+ audio_samples_count = 0;
// Temporally using libAV's AAC
audio_codec = audio_stream->codec;
audio_codec->frame_size = 1024;
audio_codec->bit_rate = audio_codec->sample_rate * 8 * 2;
audio_codec->rc_buffer_size = audio_codec->sample_rate / 4; // 250 ms worth
audio_codec->channels = 2;
-
+
+ if (audio_codec->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
+ audio_nb_samples = 10000;
+ else
+ audio_nb_samples = audio_codec->frame_size;
+ audio_frame_data = alloc_audio_frame(audio_codec->sample_fmt, audio_codec->channel_layout,
+ audio_codec->sample_rate, audio_nb_samples);
+ audio_tmp_frame = alloc_audio_frame(audio_codec->sample_fmt, audio_codec->channel_layout,
+ audio_codec->sample_rate, audio_nb_samples);
+
+ audio_swr_context = swr_alloc();
+ //if (audio_swr_context == NULL) {
+ // fprintf(stderr, "Could not allocate resampler context\n");
+ // return;
+ //}
+ av_opt_set_int (audio_swr_context, "in_channel_count", audio_codec->channels, 0);
+ av_opt_set_int (audio_swr_context, "in_sample_rate", audio_codec->sample_rate, 0);
+ av_opt_set_sample_fmt(audio_swr_context, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+ av_opt_set_int (audio_swr_context, "out_channel_count", audio_codec->channels, 0);
+ av_opt_set_int (audio_swr_context, "out_sample_rate", audio_codec->sample_rate, 0);
+ av_opt_set_sample_fmt(audio_swr_context, "out_sample_fmt", audio_codec->sample_fmt, 0);
+ /* initialize the resampling context */
+ //if ((ret = swr_init(ost->swr_ctx)) < 0) {
+ // fprintf(stderr, "Failed to initialize the resampling context\n");
+ // exit(1);
+ //}
// Context
//output_context->mux_rate = 100080 * 1000;
output_context->bit_rate = 100080 * 1000;
}
av_dump_format(output_context, 0, filename.toLocal8Bit().constData(), 1);
+ //av_dump_format(output_context, 1, NULL, 1);
AGAR_DebugLog(AGAR_LOG_DEBUG, "Successfully opened AVC stream.");
+
#endif // defined(USE_LIBAV)
recording = true;
}
#if defined(USE_LIBAV)
extern "C" {
+ #include "libavutil/channel_layout.h"
+ #include "libavutil/opt.h"
+ #include "libavutil/mathematics.h"
+ #include "libavutil/timestamp.h"
#include "libavformat/avformat.h"
+ #include "libswscale/swscale.h"
+ #include "libswresample/swresample.h"
}
#endif
AVCodecContext *video_codec;
AVStream *audio_stream;
AVStream *video_stream;
-
+
+ AVFrame *audio_frame_data;
+ AVFrame *audio_tmp_frame;
struct AVCodec codec_real;
+ struct SwrContext *audio_swr_context;
+ int audio_nb_samples;
+ int audio_samples_count;
+
+ int64_t audio_dst_nb_samples;
+ int64_t audio_next_pts;
#endif
QString _filename;
bool bRunThread;
bool dequeue_audio(int16_t *);
bool dequeue_video(uint32_t *);
QString create_date_file_name(void);
+ int write_audio_frame(const void *_time_base, void *_pkt);
+ AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
+ uint64_t channel_layout,
+ int sample_rate, int nb_samples);
public:
MOVIE_SAVER(int width, int height, int fps, OSD *osd);
void enqueue_video(QByteArray *p, int width, int height);
void enqueue_audio(QByteArray *p);
void do_close();
- void do_open(QString filename);
+ void do_open(QString filename, int);
void do_set_width(int width);
void do_set_height(int height);
void do_set_record_fps(int fps);
int opengl_filter_num_bak = config.opengl_filter_num;
//uint32_t key_mod_old = 0xffffffff;
int no_draw_count = 0;
+ bool prevRecordReq;
+
doing_debug_command = false;
ctext.clear();
bUpdateConfigReq = false;
bStartRecordSoundReq = false;
bStopRecordSoundReq = false;
-
+ bStartRecordMovieReq = false;
+ record_fps = -1;
+
next_time = 0;
mouse_flag = false;
bUpdateConfigReq = false;
req_draw = true;
}
+ if(bStartRecordMovieReq != false) {
+ if(!prevRecordReq && (record_fps > 0) && (record_fps < 75)) {
+ p_emu->start_record_video(record_fps);
+ prevRecordReq = true;
+ }
+ } else {
+ if(prevRecordReq) {
+ p_emu->stop_record_video();
+ record_fps = -1;
+ prevRecordReq = false;
+ }
+ }
+
+
+
#if defined(USE_MOUSE) // Will fix
emit sig_is_enable_mouse(p_emu->is_mouse_enabled());
#endif
{
bSaveStateReq = true;
}
+
+void EmuThreadClass::doStartRecordVideo(int fps)
+{
+ record_fps = fps;
+ bStartRecordMovieReq = true;
+}
+
+void EmuThreadClass::doStopRecordVideo()
+{
+ bStartRecordMovieReq = false;
+}
+
+
// Debugger
#if defined(USE_DEBUGGER)
extern int debugger_command(debugger_thread_t *p, _TCHAR *command, _TCHAR *prev_command, bool cp932);
bool bUpdateConfigReq;
bool bStartRecordSoundReq;
bool bStopRecordSoundReq;
+ bool bStartRecordMovieReq;
+
bool draw_timing;
bool doing_debug_command;
bool bUpdateVolumeReq[32];
int volume_balance[32];
int volume_avg[32];
-
+ int record_fps;
+
qint64 next_time;
qint64 update_fps_time;
bool prev_skip;
void doUpdateConfig();
void doStartRecordSound();
void doStopRecordSound();
+ void doStartRecordVideo(int fps);
+ void doStopRecordVideo();
+
void doSetDisplaySize(int w, int h, int ww, int wh);
void doUpdateVolumeLevel(int num, int level);
void doUpdateVolumeBalance(int num, int level);
void delete_joy_thread(void);
void do_set_mouse_enable(bool flag);
void do_toggle_mouse(void);
+
//virtual void redraw_status_bar(void);
};
#include <QTextCodec>
#include <QImage>
#include <QImageReader>
+#include <QDateTime>
#include <QDir>
#include "common.h"
#include "menu_disk.h"
#include "menu_bubble.h"
#include "menu_flags.h"
+#include "../avio/movie_saver.h"
// emulation core
EMU* emu;
#endif
}
+void Object_Menu_Control::do_save_as_movie(void)
+{
+ int fps = 0;
+ QDateTime nowTime = QDateTime::currentDateTime();
+ QString tmps = nowTime.toString(QString::fromUtf8("yyyy-MM-dd_hh-mm-ss.zzz."));
+ QString path = QString::fromUtf8("Saved_Movie") + tmps + QString::fromUtf8("mp4");
+ if(emu->get_osd() == NULL) return;
+ path = QString::fromLocal8Bit(emu->get_osd()->get_app_path()) + path;
+
+ int num = getNumber();
+ if((num <= 0) || (num > 75)) return;
+ fps = num;
+ emit sig_start_record_movie(fps);
+ emit sig_save_as_movie(path, fps);
+}
+
+void Object_Menu_Control::do_stop_saving_movie(void)
+{
+ emit sig_stop_record_movie();
+ emit sig_stop_saving_movie();
+}
+
void Ui_MainWindow::LaunchEmuThread(void)
{
QString objNameStr;
hDrawEmu->setObjectName(objNameStr);
hDrawEmu->start();
AGAR_DebugLog(AGAR_LOG_DEBUG, "DrawThread : Launch done.");
+
+ hSaveMovieThread = new MOVIE_SAVER(640, 400, 30, emu->get_osd());
+ for(int i = 0; i < (CSP_MAINWIDGET_SAVE_MOVIE_END - 1); i++) {
+ connect(action_SaveAsMovie[i]->binds, SIGNAL(sig_save_as_movie(QString, int)), hSaveMovieThread, SLOT(do_open(QString, int)));
+ connect(action_SaveAsMovie[i]->binds, SIGNAL(sig_start_record_movie(int)), hRunEmu, SLOT(doStartRecordVideo(int)));
+ connect(action_SaveAsMovie[i], SIGNAL(triggered()), action_SaveAsMovie[i]->binds, SLOT(do_save_as_movie()));
+ //connect(action_SaveAsMovie[i]->binds, SIGNAL(sig_stop_record_movie()), hRunEmu, SLOT(doStopRecordVideo()));
+ //connect(action_SaveAsMovie[i]->binds, SIGNAL(sig_stop_saving_movie()), hSaveMovieThread, SLOT(do_close()));
+ }
+ //connect(action_StopSavingMovie->binds, SIGNAL(sig_start_save_as_movie(QString, int)), hSaveMovieThread, SLOT(do_open(QString, int)));
+ //connect(action_StopSavingMovie->binds, SIGNAL(sig_start_record_movie(int)), hRunEmu, SLOT(doStartRecordVideo(int)));
+ connect(action_StopSavingMovie->binds, SIGNAL(sig_stop_record_movie()), hRunEmu, SLOT(doStopRecordVideo()));
+ connect(action_StopSavingMovie->binds, SIGNAL(sig_stop_saving_movie()), hSaveMovieThread, SLOT(do_close()));
+ connect(action_StopSavingMovie, SIGNAL(triggered()), action_StopSavingMovie->binds, SLOT(do_stop_saving_movie()));
+
+
+
+ connect(emu->get_osd(), SIGNAL(sig_enqueue_audio(QByteArray *)), hSaveMovieThread, SLOT(enqueue_audio(QByteArray *)));
+ connect(emu->get_osd(), SIGNAL(sig_enqueue_video(QByteArray *, int, int)), hSaveMovieThread, SLOT(enqueue_video(QByteArray *, int, int)));
+ connect(this, SIGNAL(sig_quit_movie_thread()), hSaveMovieThread, SLOT(do_exit()));
+
+ objNameStr = QString("EmuMovieThread");
+ hSaveMovieThread->setObjectName(objNameStr);
+ hSaveMovieThread->start();
+ AGAR_DebugLog(AGAR_LOG_DEBUG, "MovieThread : Launch done.");
hRunEmu->start();
AGAR_DebugLog(AGAR_LOG_DEBUG, "EmuThread : Launch done.");
emit quit_draw_thread();
emit quit_joy_thread();
emit quit_emu_thread();
+ emit sig_quit_movie_thread();
emit sig_quit_widgets();
+ if(hSaveMovieThread != NULL) {
+ hSaveMovieThread->wait();
+ delete hSaveMovieThread;
+ }
+
if(hDrawEmu != NULL) {
hDrawEmu->wait();
delete hDrawEmu;
)
set_target_properties(CSPgui PROPERTIES
- SOVERSION 1.2.0
- VERSION 1.2.0
+ SOVERSION 1.2.1
+ VERSION 1.2.1
)
INSTALL(TARGETS CSPgui DESTINATION ${LIBCSP_INSTALL_DIR})
endif()
bool isWriteProtect(void) { return write_protect; }
void setWriteProtect(bool b) {write_protect = b;}
+public slots:
+ void do_save_as_movie(void);
+ void do_stop_saving_movie(void);
+
+signals:
+ int sig_save_as_movie(QString, int);
+ int sig_stop_record_movie();
+ int sig_start_record_movie(int);
+ int sig_stop_saving_movie();
} Object_Menu_Control ;
typedef class Action_Control: public QAction {
#include "qt_main.h"
#define _MAX_DEBUGGER 8
+enum {
+ CSP_MAINWIDGET_SAVE_MOVIE_STOP = 0,
+ CSP_MAINWIDGET_SAVE_MOVIE_15FPS = 1,
+ CSP_MAINWIDGET_SAVE_MOVIE_24FPS,
+ CSP_MAINWIDGET_SAVE_MOVIE_30FPS,
+ CSP_MAINWIDGET_SAVE_MOVIE_60FPS,
+ CSP_MAINWIDGET_SAVE_MOVIE_END,
+};
+
QT_BEGIN_NAMESPACE
class Ui_SoundDialog;
class Menu_BubbleClass;
class Menu_CompactDiscClass;
class USING_FLAGS;
+class MOVIE_SAVER;
extern USING_FLAGS *using_flags;
// Emulator
class Action_Control *action_SetupJoystick;
class Action_Control *action_SetupKeyboard;
+
+ QMenu *menuSaveAsMovie;
+ class Action_Control *action_SaveAsMovie[4]; // 15, 24, 30, 60
+ class Action_Control *action_StopSavingMovie;
+ QActionGroup *actionGroup_SaveAsMovie;
// Menus
QMenu *menuControl;
class EmuThreadClass *hRunEmu;
class DrawThreadClass *hDrawEmu;
class JoyThreadClass *hRunJoy;
+ class MOVIE_SAVER *hSaveMovieThread;
public:
Ui_MainWindowBase(QWidget *parent = 0);
~Ui_MainWindowBase();
virtual void delete_joy_thread(void);
virtual void do_set_window_title(QString s);
virtual void redraw_status_bar(void);
-//#ifdef USE_LED_DEVICE
virtual void redraw_leds(void);
void do_recv_data_led(quint32 d);
-//#endif
void do_update_volume(int level);
void set_screen_aspect(int num);
void set_printer_device(int);
void do_show_about(void);
void do_browse_document(QString);
+
signals:
int message_changed(QString);
int quit_emu_thread();
int call_joy_thread(EMU *);
int quit_joy_thread();
int quit_draw_thread();
+ int sig_quit_movie_thread();
int on_boot_mode(int);
int on_cpu_type(int);
int on_cpu_power(int);
int sig_led_update(QRectF);
int sig_start_auto_key(QString);
int sig_stop_auto_key(void);
+
int quit_debugger_thread(void);
int sig_quit_widgets(void);
};
void Ui_MainWindowBase::retranslateEmulatorMenu(void)
{
-
+ int i;
menuEmulator->setTitle(QApplication::translate("MainWindow", "Emulator", 0));
if(using_flags->is_use_joystick()) {
action_SetupJoystick->setText(QApplication::translate("MainWindow", "Configure Joysticks", 0));
}
action_SetupKeyboard->setText(QApplication::translate("MainWindow", "Configure Keyboard", 0));
action_SetupKeyboard->setIcon(QIcon(":/icon_keyboard.png"));
+ for(int i = 0; i < (CSP_MAINWIDGET_SAVE_MOVIE_END - 1); i++) {
+ switch(i + 1) {
+ case CSP_MAINWIDGET_SAVE_MOVIE_15FPS:
+ action_SaveAsMovie[i]->setText(QApplication::translate("MainWindow", "15fps", 0));
+ break;
+ case CSP_MAINWIDGET_SAVE_MOVIE_24FPS:
+ action_SaveAsMovie[i]->setText(QApplication::translate("MainWindow", "24fps", 0));
+ break;
+ case CSP_MAINWIDGET_SAVE_MOVIE_30FPS:
+ action_SaveAsMovie[i]->setText(QApplication::translate("MainWindow", "30fps", 0));
+ break;
+ case CSP_MAINWIDGET_SAVE_MOVIE_60FPS:
+ action_SaveAsMovie[i]->setText(QApplication::translate("MainWindow", "60fps", 0));
+ break;
+ }
+ }
+ action_StopSavingMovie->setText(QApplication::translate("MainWindow", "Stop Recording", 0));
+ action_StopSavingMovie->setIcon(QIcon(":/icon_process_stop.png"));
+ menuSaveAsMovie->setTitle(QApplication::translate("MainWindow", "Record to Movie", 0));
}
+
void Ui_MainWindowBase::CreateEmulatorMenu(void)
{
if(using_flags->is_use_joystick()) {
menuEmulator->addAction(action_SetupJoystick);
}
menuEmulator->addAction(action_SetupKeyboard);
+ menuEmulator->addAction(menuSaveAsMovie->menuAction());
}
void Ui_MainWindowBase::ConfigEmulatorMenu(void)
{
+ int i;
+ QString tmps;
if(using_flags->is_use_joystick()) {
action_SetupJoystick = new Action_Control(this);
}
action_SetupKeyboard = new Action_Control(this);
+
+ menuSaveAsMovie = new QMenu(this);
+ actionGroup_SaveAsMovie = new QActionGroup(this);
+ for(int i = 0; i < (CSP_MAINWIDGET_SAVE_MOVIE_END - 1); i++) {
+ action_SaveAsMovie[i] = new Action_Control(menuSaveAsMovie);
+ switch(i + 1) {
+ case CSP_MAINWIDGET_SAVE_MOVIE_15FPS:
+ tmps.setNum(15);
+ action_SaveAsMovie[i]->binds->setNumber(15);
+ break;
+ case CSP_MAINWIDGET_SAVE_MOVIE_24FPS:
+ tmps.setNum(24);
+ action_SaveAsMovie[i]->binds->setNumber(24);
+ break;
+ case CSP_MAINWIDGET_SAVE_MOVIE_30FPS:
+ tmps.setNum(30);
+ action_SaveAsMovie[i]->binds->setNumber(30);
+ break;
+ case CSP_MAINWIDGET_SAVE_MOVIE_60FPS:
+ tmps.setNum(60);
+ action_SaveAsMovie[i]->binds->setNumber(60);
+ break;
+ }
+ tmps = QString::fromUtf8("action_SaveAsMovie") + tmps;
+ action_SaveAsMovie[i]->setObjectName(tmps);
+ actionGroup_SaveAsMovie->addAction(action_SaveAsMovie[i]);
+ menuSaveAsMovie->addAction(action_SaveAsMovie[i]);
+ }
+ action_StopSavingMovie = new Action_Control(menuSaveAsMovie);
+ action_StopSavingMovie->setObjectName(QString::fromUtf8("actionStopRecordingMovie"));
+ action_StopSavingMovie->binds->setNumber(0);
+ actionGroup_SaveAsMovie->addAction(action_StopSavingMovie);
+ menuSaveAsMovie->addAction(action_StopSavingMovie);
+
}
void Ui_MainWindowBase::rise_joystick_dialog(void)
}
}
+_TCHAR *OSD_BASE::get_app_path(void)
+{
+ return app_path;
+}
+
_TCHAR* OSD_BASE::bios_path(const _TCHAR* file_name)
{
static _TCHAR file_path[_MAX_PATH];
void get_host_time(cur_time_t* time);
void sleep(uint32_t ms);
void create_date_file_name(_TCHAR *name, int length, const _TCHAR *extension);
-
+ _TCHAR *get_app_path(void);
// common console
void open_console(_TCHAR* title);
void close_console();
rec_video_fps = fps;
rec_video_run_frames = rec_video_frames = 0;
}
+
#if 0
bool show_dialog = (fps > 0);
//SDL_UnlockAudio();
// sound buffer must be updated
Sint16* sound_buffer = (Sint16 *)this->create_sound(extra_frames);
- if(now_record_video) {
- if(sound_samples > rec_sound_buffer_ptr) {
- int samples = sound_samples - rec_sound_buffer_ptr;
- int length = samples * sizeof(int16_t) * 2; // stereo
- //QByteArray *p = new QByteArray((const char *)sound_buffer + rec_sound_buffer_ptr * 2, length);
- //emit sig_enqueue_audio(p);
+ if(now_record_sound || now_record_video) {
+ int samples = sound_samples - rec_sound_buffer_ptr;
+ int length = samples * sizeof(int16_t) * 2; // stereo
+ if(now_record_video) {
+ if(sound_samples > rec_sound_buffer_ptr) {
+ QByteArray *p = new QByteArray((const char *)sound_buffer + rec_sound_buffer_ptr * 2, length);
+ emit sig_enqueue_audio(p);
+ }
}
- }
- if(now_record_sound) {
// record sound
- if(sound_samples > rec_sound_buffer_ptr) {
- int samples = sound_samples - rec_sound_buffer_ptr;
- int length = samples * sizeof(int16_t) * 2; // stereo
- rec_sound_fio->Fwrite(sound_buffer + rec_sound_buffer_ptr * 2, length, 1);
- rec_sound_bytes += length;
-#if 0
- if(now_record_video) {
- // sync video recording
- static double frames = 0;
- static int prev_samples = -1;
- if(this->get_support_variable_timing()) {
- static double prev_fps = -1;
- double fps = this->vm_frame_rate();
- if(prev_samples != samples || prev_fps != fps) {
- prev_samples = samples;
- prev_fps = fps;
- frames = fps * (double)samples / (double)sound_rate;
- }
- } else {
- if(prev_samples != samples) {
- prev_samples = samples;
- frames = vm_frame_rate() * (double)samples / (double)sound_rate;
- }
+ if(now_record_sound) {
+ if(sound_samples > rec_sound_buffer_ptr) {
+ rec_sound_fio->Fwrite(sound_buffer + rec_sound_buffer_ptr * 2, length, 1);
+ rec_sound_bytes += length;
+ }
+ }
+
+#if 1
+ if(now_record_video) {
+ // sync video recording
+ static double frames = 0;
+ static int prev_samples = -1;
+ if(this->get_support_variable_timing()) {
+ static double prev_fps = -1;
+ double fps = this->vm_frame_rate();
+ if(prev_samples != samples || prev_fps != fps) {
+ prev_samples = samples;
+ prev_fps = fps;
+ frames = fps * (double)samples / (double)sound_rate;
}
- rec_video_frames -= frames;
- if(rec_video_frames > 2) {
- rec_video_run_frames -= (rec_video_frames - 2);
- } else if(rec_video_frames < -2) {
- rec_video_run_frames -= (rec_video_frames + 2);
+ } else {
+ if(prev_samples != samples) {
+ prev_samples = samples;
+ frames = vm_frame_rate() * (double)samples / (double)sound_rate;
}
-// rec_video_run_frames -= rec_video_frames;
}
-#endif
-// printf("Wrote %d samples\n", samples);
- rec_sound_buffer_ptr += samples;
- if(rec_sound_buffer_ptr >= sound_samples) rec_sound_buffer_ptr = 0;
+ rec_video_frames -= frames;
+ if(rec_video_frames > 2) {
+ rec_video_run_frames -= (rec_video_frames - 2);
+ } else if(rec_video_frames < -2) {
+ rec_video_run_frames -= (rec_video_frames + 2);
+ }
+// rec_video_run_frames -= rec_video_frames;
}
+#endif
+ //printf("Wrote %d samples ptr=%d\n", samples, rec_sound_buffer_ptr);
+ rec_sound_buffer_ptr += samples;
+ if(rec_sound_buffer_ptr >= sound_samples) rec_sound_buffer_ptr = 0;
}
+
if(sound_buffer) {
int ssize;
CSP_ARCH="x86_64-linux-gnu"
MULTIARCH="Yes"
CSP_PREFIX=/usr/local
-CSP_GUILIB="libCSPgui.so.1.2.0 libCSPosd.so.1.1.1 libCSPemu_utils.so.1.0.0 libCSPavio.1.0.0"
+CSP_GUILIB="libCSPgui.so.1.2.1 libCSPosd.so.1.1.1 libCSPemu_utils.so.1.0.0 libCSPavio.1.0.0"
for i in "$@"; do
case "$1" in