mirror of
https://github.com/Lorenzooone/cc3dsfs.git
synced 2026-09-11 18:15:24 -05:00
Separate CaptureData and CaptureStatus
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "hw_defs.hpp"
|
||||
#include "capture_structs.hpp"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define FTD3XX_STATIC
|
||||
@@ -15,51 +16,21 @@
|
||||
|
||||
#define REAL_SERIAL_NUMBER_SIZE 16
|
||||
#define SERIAL_NUMBER_SIZE (REAL_SERIAL_NUMBER_SIZE+1)
|
||||
#define MAX_SAMPLES_IN 1096
|
||||
|
||||
// Max value supported by old FTD3XX versions...
|
||||
// Max value (Due to support of old FTD3XX versions...)
|
||||
#define NUM_CONCURRENT_DATA_BUFFERS 8
|
||||
|
||||
// When is_bad_ftd3xx is true, it may happen that a frame is lost.
|
||||
// This value prevents showing a black frame for that.
|
||||
#define MAX_ALLOWED_BLANKS 1
|
||||
|
||||
#define FIX_PARTIAL_FIRST_FRAME_NUM 3
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct PACKED VideoInputData {
|
||||
uint8_t screen_data[IN_VIDEO_SIZE][3];
|
||||
};
|
||||
|
||||
struct PACKED CaptureReceived {
|
||||
VideoInputData video_data;
|
||||
uint16_t audio_data[MAX_SAMPLES_IN];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct CaptureData {
|
||||
FT_HANDLE handle;
|
||||
char chosen_serial_number[SERIAL_NUMBER_SIZE];
|
||||
std::string error_text;
|
||||
bool new_error_text;
|
||||
CaptureReceived capture_buf[NUM_CONCURRENT_DATA_BUFFERS];
|
||||
ULONG read[NUM_CONCURRENT_DATA_BUFFERS];
|
||||
CaptureReceived capture_buf[NUM_CONCURRENT_DATA_BUFFERS];
|
||||
double time_in_buf[NUM_CONCURRENT_DATA_BUFFERS];
|
||||
volatile int curr_in = 0;
|
||||
volatile int cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM;
|
||||
volatile bool connected = false;
|
||||
volatile bool running = true;
|
||||
volatile bool close_success = true;
|
||||
ConsumerMutex video_wait;
|
||||
ConsumerMutex audio_wait;
|
||||
};
|
||||
|
||||
struct DevicesList {
|
||||
int numAllocedDevices;
|
||||
int numValidDevices;
|
||||
char *serialNumbers;
|
||||
char chosen_serial_number[SERIAL_NUMBER_SIZE];
|
||||
CaptureStatus status;
|
||||
};
|
||||
|
||||
bool connect(bool print_failed, CaptureData* capture_data);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "audio_data.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "audio.hpp"
|
||||
#include "3dscapture.hpp"
|
||||
#include "capture_structs.hpp"
|
||||
#include "hw_defs.hpp"
|
||||
|
||||
struct Sample {
|
||||
|
||||
42
include/capture_structs.hpp
Executable file
42
include/capture_structs.hpp
Executable file
@@ -0,0 +1,42 @@
|
||||
#ifndef __CAPTURESTRUCTS_HPP
|
||||
#define __CAPTURESTRUCTS_HPP
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "hw_defs.hpp"
|
||||
#include <string>
|
||||
|
||||
#define MAX_SAMPLES_IN 1096
|
||||
|
||||
#define FIX_PARTIAL_FIRST_FRAME_NUM 3
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct PACKED VideoInputData {
|
||||
uint8_t screen_data[IN_VIDEO_SIZE][3];
|
||||
};
|
||||
|
||||
struct PACKED CaptureReceived {
|
||||
VideoInputData video_data;
|
||||
uint16_t audio_data[MAX_SAMPLES_IN];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
struct CaptureStatus {
|
||||
std::string error_text;
|
||||
bool new_error_text;
|
||||
volatile int curr_in = 0;
|
||||
volatile int cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM;
|
||||
volatile bool connected = false;
|
||||
volatile bool running = true;
|
||||
volatile bool close_success = true;
|
||||
ConsumerMutex video_wait;
|
||||
ConsumerMutex audio_wait;
|
||||
};
|
||||
|
||||
struct DevicesList {
|
||||
int numAllocedDevices;
|
||||
int numValidDevices;
|
||||
char *serialNumbers;
|
||||
};
|
||||
#endif
|
||||
@@ -2,7 +2,7 @@
|
||||
#define __CONVERSIONS_HPP
|
||||
|
||||
#include <SFML/Audio.hpp>
|
||||
#include "3dscapture.hpp"
|
||||
#include "capture_structs.hpp"
|
||||
#include "frontend.hpp"
|
||||
|
||||
void convertVideoToOutput(VideoInputData *p_in, VideoOutputData *p_out);
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <chrono>
|
||||
#include "utils.hpp"
|
||||
#include "audio_data.hpp"
|
||||
#include "3dscapture.hpp"
|
||||
#include "capture_structs.hpp"
|
||||
#include "hw_defs.hpp"
|
||||
|
||||
enum Crop { DEFAULT_3DS, SPECIAL_DS, SCALED_DS, NATIVE_DS, SCALED_GBA, NATIVE_GBA, SCALED_GB, NATIVE_GB, NATIVE_SNES, NATIVE_NES, CROP_END };
|
||||
@@ -134,7 +135,7 @@ public:
|
||||
void poll();
|
||||
void close();
|
||||
void display_call(bool is_main_thread);
|
||||
void display_thread(CaptureData* capture_data);
|
||||
void display_thread(CaptureStatus* capture_status);
|
||||
void end();
|
||||
void after_thread_join();
|
||||
void draw(double frame_time, VideoOutputData* out_buf);
|
||||
@@ -231,5 +232,5 @@ private:
|
||||
};
|
||||
|
||||
void update_output(WindowScreen &top_screen, WindowScreen &bot_screen, WindowScreen &joint_screen, bool &reload, bool split, double frame_time, VideoOutputData *out_buf);
|
||||
void screen_display_thread(WindowScreen *screen, CaptureData* capture_data);
|
||||
void screen_display_thread(WindowScreen *screen, CaptureStatus* capture_status);
|
||||
#endif
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
#include "utils.hpp"
|
||||
#include "3dscapture.hpp"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define FTD3XX_STATIC
|
||||
#include <FTD3XX.h>
|
||||
#define FT_ASYNC_CALL FT_ReadPipeEx
|
||||
#else
|
||||
#include <ftd3xx.h>
|
||||
#define FT_ASYNC_CALL FT_ReadPipeAsync
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
@@ -72,16 +62,16 @@ static void preemptive_close_connection(CaptureData* capture_data) {
|
||||
}
|
||||
|
||||
bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
capture_data->new_error_text = false;
|
||||
if (capture_data->connected) {
|
||||
capture_data->close_success = false;
|
||||
capture_data->status.new_error_text = false;
|
||||
if (capture_data->status.connected) {
|
||||
capture_data->status.close_success = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!capture_data->close_success) {
|
||||
if(!capture_data->status.close_success) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "Previous device still closing...";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Previous device still closing...";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -91,8 +81,8 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
|
||||
if(devices_list.numValidDevices <= 0) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "No device was found";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "No device was found";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
if(devices_list.numAllocedDevices > 0)
|
||||
delete []devices_list.serialNumbers;
|
||||
@@ -102,8 +92,8 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
int chosen_device = choose_device(devices_list);
|
||||
if(chosen_device == -1) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "No device was selected";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "No device was selected";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
delete []devices_list.serialNumbers;
|
||||
return false;
|
||||
@@ -115,8 +105,8 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
|
||||
if (FT_Create(capture_data->chosen_serial_number, FT_OPEN_BY_SERIAL_NUMBER, &capture_data->handle)) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "Create failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Create failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -126,8 +116,8 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
|
||||
if (FT_WritePipe(capture_data->handle, BULK_OUT, buf, 4, &written, 0)) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "Write failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Write failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
@@ -137,8 +127,8 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
|
||||
if (FT_WritePipe(capture_data->handle, BULK_OUT, buf, 4, &written, 0)) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "Write failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Write failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
@@ -146,8 +136,8 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
|
||||
if (FT_SetStreamPipe(capture_data->handle, false, false, BULK_IN, sizeof(CaptureReceived))) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "Stream failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Stream failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
@@ -155,8 +145,8 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
|
||||
if(FT_AbortPipe(capture_data->handle, BULK_IN)) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "Abort failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Abort failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
@@ -164,16 +154,16 @@ bool connect(bool print_failed, CaptureData* capture_data) {
|
||||
|
||||
if (FT_SetStreamPipe(capture_data->handle, false, false, BULK_IN, sizeof(CaptureReceived))) {
|
||||
if(print_failed) {
|
||||
capture_data->error_text = "Stream failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Stream failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
preemptive_close_connection(capture_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Avoid having old open locks
|
||||
capture_data->video_wait.try_lock();
|
||||
capture_data->audio_wait.try_lock();
|
||||
capture_data->status.video_wait.try_lock();
|
||||
capture_data->status.audio_wait.try_lock();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -184,8 +174,8 @@ static void fast_capture_call(CaptureData* capture_data, OVERLAPPED overlap[NUM_
|
||||
for (inner_curr_in = 0; inner_curr_in < NUM_CONCURRENT_DATA_BUFFERS; ++inner_curr_in) {
|
||||
ftStatus = FT_InitializeOverlapped(capture_data->handle, &overlap[inner_curr_in]);
|
||||
if (ftStatus) {
|
||||
capture_data->error_text = "Disconnected: Initialize failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: Initialize failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -193,8 +183,8 @@ static void fast_capture_call(CaptureData* capture_data, OVERLAPPED overlap[NUM_
|
||||
for (inner_curr_in = 0; inner_curr_in < NUM_CONCURRENT_DATA_BUFFERS - 1; ++inner_curr_in) {
|
||||
ftStatus = FT_ASYNC_CALL(capture_data->handle, FIFO_CHANNEL, (UCHAR*)&capture_data->capture_buf[inner_curr_in], sizeof(CaptureReceived), &capture_data->read[inner_curr_in], &overlap[inner_curr_in]);
|
||||
if (ftStatus != FT_IO_PENDING) {
|
||||
capture_data->error_text = "Disconnected: Read failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: Read failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -203,12 +193,12 @@ static void fast_capture_call(CaptureData* capture_data, OVERLAPPED overlap[NUM_
|
||||
|
||||
auto clock_start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
while (capture_data->connected && capture_data->running) {
|
||||
while (capture_data->status.connected && capture_data->status.running) {
|
||||
|
||||
ftStatus = FT_ASYNC_CALL(capture_data->handle, FIFO_CHANNEL, (UCHAR*)&capture_data->capture_buf[inner_curr_in], sizeof(CaptureReceived), &capture_data->read[inner_curr_in], &overlap[inner_curr_in]);
|
||||
if (ftStatus != FT_IO_PENDING) {
|
||||
capture_data->error_text = "Disconnected: Read failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: Read failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -216,8 +206,8 @@ static void fast_capture_call(CaptureData* capture_data, OVERLAPPED overlap[NUM_
|
||||
|
||||
ftStatus = FT_GetOverlappedResult(capture_data->handle, &overlap[inner_curr_in], &capture_data->read[inner_curr_in], true);
|
||||
if(FT_FAILED(ftStatus)) {
|
||||
capture_data->error_text = "Disconnected: USB error";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: USB error";
|
||||
capture_data->status.new_error_text = true;
|
||||
return;
|
||||
}
|
||||
const auto curr_time = std::chrono::high_resolution_clock::now();
|
||||
@@ -225,12 +215,12 @@ static void fast_capture_call(CaptureData* capture_data, OVERLAPPED overlap[NUM_
|
||||
capture_data->time_in_buf[inner_curr_in] = diff.count();
|
||||
clock_start = curr_time;
|
||||
|
||||
capture_data->curr_in = (inner_curr_in + 1) % NUM_CONCURRENT_DATA_BUFFERS;
|
||||
if(capture_data->cooldown_curr_in)
|
||||
capture_data->cooldown_curr_in--;
|
||||
capture_data->status.curr_in = (inner_curr_in + 1) % NUM_CONCURRENT_DATA_BUFFERS;
|
||||
if(capture_data->status.cooldown_curr_in)
|
||||
capture_data->status.cooldown_curr_in--;
|
||||
// Signal that there is data available
|
||||
capture_data->video_wait.unlock();
|
||||
capture_data->audio_wait.unlock();
|
||||
capture_data->status.video_wait.unlock();
|
||||
capture_data->status.audio_wait.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,14 +228,14 @@ static void fast_capture_call(CaptureData* capture_data, OVERLAPPED overlap[NUM_
|
||||
static bool safe_capture_call(CaptureData* capture_data) {
|
||||
int inner_curr_in = 0;
|
||||
|
||||
while (capture_data->connected && capture_data->running) {
|
||||
while (capture_data->status.connected && capture_data->status.running) {
|
||||
|
||||
auto clock_start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
FT_STATUS ftStatus = FT_ReadPipeEx(capture_data->handle, FIFO_CHANNEL, (UCHAR*)&capture_data->capture_buf[inner_curr_in], sizeof(CaptureReceived), &capture_data->read[inner_curr_in], 1000);
|
||||
if(FT_FAILED(ftStatus)) {
|
||||
capture_data->error_text = "Disconnected: Read failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: Read failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -254,11 +244,11 @@ static bool safe_capture_call(CaptureData* capture_data) {
|
||||
capture_data->time_in_buf[inner_curr_in] = diff.count();
|
||||
|
||||
inner_curr_in = (inner_curr_in + 1) % NUM_CONCURRENT_DATA_BUFFERS;
|
||||
capture_data->curr_in = inner_curr_in;
|
||||
if(capture_data->cooldown_curr_in)
|
||||
capture_data->cooldown_curr_in--;
|
||||
capture_data->video_wait.unlock();
|
||||
capture_data->audio_wait.unlock();
|
||||
capture_data->status.curr_in = inner_curr_in;
|
||||
if(capture_data->status.cooldown_curr_in)
|
||||
capture_data->status.cooldown_curr_in--;
|
||||
capture_data->status.video_wait.unlock();
|
||||
capture_data->status.audio_wait.unlock();
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -269,8 +259,8 @@ void captureCall(CaptureData* capture_data) {
|
||||
OVERLAPPED overlap[NUM_CONCURRENT_DATA_BUFFERS];
|
||||
FT_STATUS ftStatus;
|
||||
int inner_curr_in = 0;
|
||||
capture_data->curr_in = inner_curr_in;
|
||||
capture_data->cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM;
|
||||
capture_data->status.curr_in = inner_curr_in;
|
||||
capture_data->status.cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM;
|
||||
bool is_bad_ftd3xx = false;
|
||||
DWORD ftd3xx_lib_version;
|
||||
|
||||
@@ -281,8 +271,8 @@ void captureCall(CaptureData* capture_data) {
|
||||
is_bad_ftd3xx = true;
|
||||
}
|
||||
|
||||
while(capture_data->running) {
|
||||
if (!capture_data->connected) {
|
||||
while(capture_data->status.running) {
|
||||
if (!capture_data->status.connected) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000/USB_CHECKS_PER_SECOND));
|
||||
continue;
|
||||
}
|
||||
@@ -298,37 +288,37 @@ void captureCall(CaptureData* capture_data) {
|
||||
fast_capture_call(capture_data, overlap);
|
||||
#endif
|
||||
|
||||
capture_data->close_success = false;
|
||||
capture_data->connected = false;
|
||||
capture_data->cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM;
|
||||
capture_data->status.close_success = false;
|
||||
capture_data->status.connected = false;
|
||||
capture_data->status.cooldown_curr_in = FIX_PARTIAL_FIRST_FRAME_NUM;
|
||||
// Needed in case the threads went in the connected loop
|
||||
// before it is set right above, and they are waiting on the locks!
|
||||
capture_data->video_wait.unlock();
|
||||
capture_data->audio_wait.unlock();
|
||||
capture_data->status.video_wait.unlock();
|
||||
capture_data->status.audio_wait.unlock();
|
||||
|
||||
if(!is_bad_ftd3xx) {
|
||||
for (inner_curr_in = 0; inner_curr_in < NUM_CONCURRENT_DATA_BUFFERS; ++inner_curr_in) {
|
||||
ftStatus = FT_GetOverlappedResult(capture_data->handle, &overlap[inner_curr_in], &capture_data->read[inner_curr_in], true);
|
||||
if (FT_ReleaseOverlapped(capture_data->handle, &overlap[inner_curr_in])) {
|
||||
capture_data->error_text = "Disconnected: Release failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: Release failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(FT_AbortPipe(capture_data->handle, BULK_IN)) {
|
||||
capture_data->error_text = "Disconnected: Abort failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: Abort failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
|
||||
if (FT_Close(capture_data->handle)) {
|
||||
capture_data->error_text = "Disconnected: Close failed";
|
||||
capture_data->new_error_text = true;
|
||||
capture_data->status.error_text = "Disconnected: Close failed";
|
||||
capture_data->status.new_error_text = true;
|
||||
}
|
||||
|
||||
capture_data->close_success = false;
|
||||
capture_data->connected = false;
|
||||
capture_data->status.close_success = false;
|
||||
capture_data->status.connected = false;
|
||||
|
||||
capture_data->close_success = true;
|
||||
capture_data->status.close_success = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include "frontend.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#define BASE_PIXEL_FONT_HEIGHT 24
|
||||
|
||||
TextRectangle::TextRectangle(bool font_load_success, sf::Font &text_font) {
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "hw_defs.hpp"
|
||||
#include "3dscapture.hpp"
|
||||
#include "frontend.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include "font_ttf.h"
|
||||
|
||||
static int top_screen_crop_widths[] = {TOP_WIDTH_3DS, TOP_SPECIAL_DS_WIDTH_3DS, TOP_SCALED_DS_WIDTH_3DS, WIDTH_DS, WIDTH_SCALED_GBA, WIDTH_GBA, WIDTH_SCALED_GB, WIDTH_GB, WIDTH_SNES, WIDTH_NES};
|
||||
@@ -341,10 +334,10 @@ void WindowScreen::display_call(bool is_main_thread) {
|
||||
this->done_display = true;
|
||||
}
|
||||
|
||||
void WindowScreen::display_thread(CaptureData* capture_data) {
|
||||
while(capture_data->running) {
|
||||
void WindowScreen::display_thread(CaptureStatus* capture_status) {
|
||||
while(capture_status->running) {
|
||||
this->display_lock.lock();
|
||||
if(!capture_data->running)
|
||||
if(!capture_status->running)
|
||||
break;
|
||||
this->free_ownership_of_window(false);
|
||||
this->is_thread_done = true;
|
||||
|
||||
@@ -136,12 +136,12 @@ void soundCall(AudioData *audio_data, CaptureData* capture_data) {
|
||||
const bool endianness = is_big_endian();
|
||||
volatile int loaded_samples;
|
||||
|
||||
while (capture_data->running) {
|
||||
if(capture_data->connected) {
|
||||
bool timed_out = !capture_data->audio_wait.timed_lock();
|
||||
curr_out = (capture_data->curr_in - 1 + NUM_CONCURRENT_DATA_BUFFERS) % NUM_CONCURRENT_DATA_BUFFERS;
|
||||
while (capture_data->status.running) {
|
||||
if(capture_data->status.connected) {
|
||||
bool timed_out = !capture_data->status.audio_wait.timed_lock();
|
||||
curr_out = (capture_data->status.curr_in - 1 + NUM_CONCURRENT_DATA_BUFFERS) % NUM_CONCURRENT_DATA_BUFFERS;
|
||||
|
||||
if((!capture_data->cooldown_curr_in) && (curr_out != prev_out)) {
|
||||
if((!capture_data->status.cooldown_curr_in) && (curr_out != prev_out)) {
|
||||
loaded_samples = audio.samples.size();
|
||||
if((capture_data->read[curr_out] > sizeof(VideoInputData)) && (loaded_samples < AUDIO_LATENCY_LIMIT)) {
|
||||
int n_samples = (capture_data->read[curr_out] - sizeof(VideoInputData)) / 2;
|
||||
@@ -222,9 +222,6 @@ void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) {
|
||||
WindowScreen bot_screen(WindowScreen::ScreenType::BOTTOM, &display_data, audio_data, &events_access);
|
||||
WindowScreen joint_screen(WindowScreen::ScreenType::JOINT, &display_data, audio_data, &events_access);
|
||||
|
||||
if(capture_data->connected)
|
||||
ConnectedOutTextGenerator(out_text_data, capture_data);
|
||||
|
||||
if(!skip_io) {
|
||||
load(base_path, base_name, top_screen.m_info, bot_screen.m_info, joint_screen.m_info, display_data, audio_data, out_text_data);
|
||||
}
|
||||
@@ -233,17 +230,21 @@ void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) {
|
||||
bot_screen.build();
|
||||
joint_screen.build();
|
||||
|
||||
std::thread top_thread(screen_display_thread, &top_screen, capture_data);
|
||||
std::thread bot_thread(screen_display_thread, &bot_screen, capture_data);
|
||||
std::thread joint_thread(screen_display_thread, &joint_screen, capture_data);
|
||||
std::thread top_thread(screen_display_thread, &top_screen, &capture_data->status);
|
||||
std::thread bot_thread(screen_display_thread, &bot_screen, &capture_data->status);
|
||||
std::thread joint_thread(screen_display_thread, &joint_screen, &capture_data->status);
|
||||
|
||||
while (capture_data->running) {
|
||||
capture_data->status.connected = connect(true, capture_data);
|
||||
if(capture_data->status.connected)
|
||||
ConnectedOutTextGenerator(out_text_data, capture_data);
|
||||
|
||||
if(capture_data->connected) {
|
||||
bool timed_out = !capture_data->video_wait.timed_lock();
|
||||
curr_out = (capture_data->curr_in - 1 + NUM_CONCURRENT_DATA_BUFFERS) % NUM_CONCURRENT_DATA_BUFFERS;
|
||||
while (capture_data->status.running) {
|
||||
|
||||
if ((!capture_data->cooldown_curr_in) && (curr_out != prev_out)) {
|
||||
if(capture_data->status.connected) {
|
||||
bool timed_out = !capture_data->status.video_wait.timed_lock();
|
||||
curr_out = (capture_data->status.curr_in - 1 + NUM_CONCURRENT_DATA_BUFFERS) % NUM_CONCURRENT_DATA_BUFFERS;
|
||||
|
||||
if ((!capture_data->status.cooldown_curr_in) && (curr_out != prev_out)) {
|
||||
double frame_time = capture_data->time_in_buf[curr_out];
|
||||
if(capture_data->read[curr_out] >= sizeof(VideoInputData)) {
|
||||
convertVideoToOutput(&capture_data->capture_buf[curr_out].video_data, out_buf);
|
||||
@@ -268,7 +269,7 @@ void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) {
|
||||
}
|
||||
else {
|
||||
VideoOutputData *chosen_buf = out_buf;
|
||||
if(capture_data->cooldown_curr_in) {
|
||||
if(capture_data->status.cooldown_curr_in) {
|
||||
last_frame_time = 0;
|
||||
chosen_buf = null_buf;
|
||||
}
|
||||
@@ -292,7 +293,7 @@ void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) {
|
||||
for(int i = 0; i < available_fps; i++)
|
||||
fps_sum += curr_fps_array[i];
|
||||
|
||||
if(!capture_data->connected)
|
||||
if(!capture_data->status.connected)
|
||||
update_output(top_screen, bot_screen, joint_screen, reload, display_data.split, 0, null_buf);
|
||||
|
||||
int load_index = 0;
|
||||
@@ -302,13 +303,13 @@ void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) {
|
||||
joint_screen.poll();
|
||||
|
||||
if(top_screen.open_capture() || bot_screen.open_capture() || joint_screen.open_capture()) {
|
||||
capture_data->connected = connect(true, capture_data);
|
||||
if(capture_data->connected)
|
||||
capture_data->status.connected = connect(true, capture_data);
|
||||
if(capture_data->status.connected)
|
||||
ConnectedOutTextGenerator(out_text_data, capture_data);
|
||||
}
|
||||
|
||||
if(top_screen.close_capture() || bot_screen.close_capture() || joint_screen.close_capture()) {
|
||||
capture_data->running = false;
|
||||
capture_data->status.running = false;
|
||||
}
|
||||
|
||||
if((load_index = top_screen.load_data()) || (load_index = bot_screen.load_data()) || (load_index = joint_screen.load_data())) {
|
||||
@@ -334,9 +335,9 @@ void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) {
|
||||
UpdateOutText(out_text_data, "", audio_data->text_to_print(), TEXT_KIND_NORMAL);
|
||||
}
|
||||
|
||||
if(capture_data->new_error_text) {
|
||||
UpdateOutText(out_text_data, capture_data->error_text, capture_data->error_text, TEXT_KIND_ERROR);
|
||||
capture_data->new_error_text = false;
|
||||
if(capture_data->status.new_error_text) {
|
||||
UpdateOutText(out_text_data, capture_data->status.error_text, capture_data->status.error_text, TEXT_KIND_ERROR);
|
||||
capture_data->status.new_error_text = false;
|
||||
}
|
||||
|
||||
if(!out_text_data.consumed) {
|
||||
@@ -382,7 +383,6 @@ int main(int argc, char **argv) {
|
||||
audio_data.reset();
|
||||
CaptureData* capture_data = new CaptureData;
|
||||
|
||||
capture_data->connected = connect(true, capture_data);
|
||||
std::thread capture_thread(captureCall, capture_data);
|
||||
std::thread audio_thread(soundCall, &audio_data, capture_data);
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include <SFML/Audio.hpp>
|
||||
#include "3dscapture.hpp"
|
||||
#include "frontend.hpp"
|
||||
#include "conversions.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#include "utils.hpp"
|
||||
#include "3dscapture.hpp"
|
||||
#include "frontend.hpp"
|
||||
|
||||
void reset_screen_info(ScreenInfo &info) {
|
||||
@@ -157,6 +155,6 @@ void update_output(WindowScreen &top_screen, WindowScreen &bot_screen, WindowScr
|
||||
joint_screen.draw(frame_time, out_buf);
|
||||
}
|
||||
|
||||
void screen_display_thread(WindowScreen *screen, CaptureData* capture_data) {
|
||||
screen->display_thread(capture_data);
|
||||
void screen_display_thread(WindowScreen *screen, CaptureStatus* capture_status) {
|
||||
screen->display_thread(capture_status);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user