void initializeFilter(ParameterTypes... parameters) { filter.reset(new FilterType(parameters...)); }
void ISNewText( const char *dev, const char *name, char *texts[], char *names[], int num) { scope->ISNewText(dev, name, texts, names, num); }
void ISSnoopDevice (XMLEle *root) { scope->ISSnoopDevice(root); }
bool IsRealTimeStream(void) { return !g_pvr_client->is_timeshifting(); }
void ISGetProperties(const char *dev) { scope->ISGetProperties(dev); }
int GetChannelsAmount(void) { return g_pvr_client->get_channels_num(); }
void CloseLiveStream(void) { if (XBMC) XBMC->Log(LOG_DEBUG, "CloseLiveStream"); g_pvr_client->destroy_session(); }
void VertexManager::DestroyDeviceObjects() { s_vertexBuffer.reset(); s_indexBuffer.reset(); }
explicit Sprite(const std::unique_ptr<Texture> &texture) : Sprite(texture.get()) { }
void Controller::sendRequests() { // Connector::connect() try { connector_ptr_->connect(num_connect_attempts_); } catch (PCPClient::connection_config_error& e) { std::string err_msg { "failed to configure WebSocket: " }; throw controller_error { err_msg + e.what() }; } catch (PCPClient::connection_fatal_error& e) { std::string err_msg { "failed to connect to " + BROKER_URL + " or " + FAILOVER_URL + " after " + std::to_string(num_connect_attempts_) + " attempts: " }; throw controller_error { err_msg + e.what() }; } // Connector::isConnected() if (connector_ptr_->isConnected()) { std::cout << "Successfully connected\n"; } else { // The connection has dropped; we can't send anything throw controller_error { "connection dropped" }; } // Send a valid request - a response is expected leatherman::json_container::JsonContainer track { "{\"artist\" : \"Captain Beefheart\"}" }; leatherman::json_container::JsonContainer valid_request {}; valid_request.set<leatherman::json_container::JsonContainer>("request", track); valid_request.set<std::string>("details", "please send some good music"); std::vector<std::string> endpoints { "pcp://*/" + AGENT_CLIENT_TYPE }; try { auto id = connector_ptr_->send(endpoints, REQUEST_SCHEMA_NAME, MSG_TIMEOUT_S, valid_request); std::cout << "Valid request message sent; message id: " << id << "\n"; } catch (PCPClient::connection_processing_error& e) { std::string err_msg { "failed to send the request message: " }; throw controller_error { err_msg + e.what() }; } // Send an invalid request - an error message should arrive leatherman::json_container::JsonContainer bad_json { "{\"genre\" : \"experimental rock\"}" }; leatherman::json_container::JsonContainer bad_request {}; bad_request.set<leatherman::json_container::JsonContainer>("request", bad_json); bad_request.set<std::string>("details", "I'm not sure about this"); try { auto id = connector_ptr_->send(endpoints, REQUEST_SCHEMA_NAME, MSG_TIMEOUT_S, bad_request); std::cout << "Bad request message sent; message id: " << id << "\n"; } catch (PCPClient::connection_processing_error& e) { std::string err_msg { "failed to send the request message: " }; throw controller_error { err_msg + e.what() }; } // Send an inventory request to the broker leatherman::json_container::JsonContainer inventory_request {}; std::vector<std::string> query { "cth://*/" + AGENT_CLIENT_TYPE }; inventory_request.set<std::vector<std::string>>("query", query); try { // NB: use "cth:///server" with 3 '/' as the broker URI auto id = connector_ptr_->send(std::vector<std::string> { "cth:///server" }, PCPClient::Protocol::INVENTORY_REQ_TYPE, MSG_TIMEOUT_S, inventory_request); std::cout << "Inventory request message sent; message id: " << id << "\n"; } catch (PCPClient::connection_processing_error& e) { std::string err_msg { "failed to send the inventory request message: " }; throw controller_error { err_msg + e.what() }; } // Wait for the response and error messages sleep(2); }
namespace OGL { // This are the initially requested size for the buffers expressed in bytes const u32 MAX_IBUFFER_SIZE = 2 * 1024 * 1024; const u32 MAX_VBUFFER_SIZE = 32 * 1024 * 1024; static std::unique_ptr<StreamBuffer> s_vertexBuffer; static std::unique_ptr<StreamBuffer> s_indexBuffer; static size_t s_baseVertex; static size_t s_index_offset; VertexManager::VertexManager() : m_cpu_v_buffer(MAX_VBUFFER_SIZE), m_cpu_i_buffer(MAX_IBUFFER_SIZE) { CreateDeviceObjects(); } VertexManager::~VertexManager() { DestroyDeviceObjects(); } void VertexManager::CreateDeviceObjects() { s_vertexBuffer = StreamBuffer::Create(GL_ARRAY_BUFFER, MAX_VBUFFER_SIZE); m_vertex_buffers = s_vertexBuffer->m_buffer; s_indexBuffer = StreamBuffer::Create(GL_ELEMENT_ARRAY_BUFFER, MAX_IBUFFER_SIZE); m_index_buffers = s_indexBuffer->m_buffer; m_last_vao = 0; } void VertexManager::DestroyDeviceObjects() { s_vertexBuffer.reset(); s_indexBuffer.reset(); } void VertexManager::PrepareDrawBuffers(u32 stride) { u32 vertex_data_size = IndexGenerator::GetNumVerts() * stride; u32 index_data_size = IndexGenerator::GetIndexLen() * sizeof(u16); s_vertexBuffer->Unmap(vertex_data_size); s_indexBuffer->Unmap(index_data_size); ADDSTAT(stats.thisFrame.bytesVertexStreamed, vertex_data_size); ADDSTAT(stats.thisFrame.bytesIndexStreamed, index_data_size); } void VertexManager::ResetBuffer(u32 stride) { if (m_cull_all) { // This buffer isn't getting sent to the GPU. Just allocate it on the cpu. m_cur_buffer_pointer = m_base_buffer_pointer = m_cpu_v_buffer.data(); m_end_buffer_pointer = m_base_buffer_pointer + m_cpu_v_buffer.size(); IndexGenerator::Start((u16*)m_cpu_i_buffer.data()); } else { auto buffer = s_vertexBuffer->Map(MAXVBUFFERSIZE, stride); m_cur_buffer_pointer = m_base_buffer_pointer = buffer.first; m_end_buffer_pointer = buffer.first + MAXVBUFFERSIZE; s_baseVertex = buffer.second / stride; buffer = s_indexBuffer->Map(MAXIBUFFERSIZE * sizeof(u16)); IndexGenerator::Start((u16*)buffer.first); s_index_offset = buffer.second; } } void VertexManager::Draw(u32 stride) { u32 index_size = IndexGenerator::GetIndexLen(); u32 max_index = IndexGenerator::GetNumVerts(); GLenum primitive_mode = 0; switch (m_current_primitive_type) { case PRIMITIVE_POINTS: primitive_mode = GL_POINTS; glDisable(GL_CULL_FACE); break; case PRIMITIVE_LINES: primitive_mode = GL_LINES; glDisable(GL_CULL_FACE); break; case PRIMITIVE_TRIANGLES: primitive_mode = g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? GL_TRIANGLE_STRIP : GL_TRIANGLES; break; } if (g_ogl_config.bSupportsGLBaseVertex) { glDrawRangeElementsBaseVertex(primitive_mode, 0, max_index, index_size, GL_UNSIGNED_SHORT, (u8*)nullptr + s_index_offset, (GLint)s_baseVertex); } else { glDrawRangeElements(primitive_mode, 0, max_index, index_size, GL_UNSIGNED_SHORT, (u8*)nullptr + s_index_offset); } INCSTAT(stats.thisFrame.numDrawCalls); if (m_current_primitive_type != PRIMITIVE_TRIANGLES) static_cast<Renderer*>(g_renderer.get())->SetGenerationMode(); } void VertexManager::vFlush(bool useDstAlpha) { GLVertexFormat* nativeVertexFmt = (GLVertexFormat*)VertexLoaderManager::GetCurrentVertexFormat(); u32 stride = nativeVertexFmt->GetVertexStride(); if (m_last_vao != nativeVertexFmt->VAO) { glBindVertexArray(nativeVertexFmt->VAO); m_last_vao = nativeVertexFmt->VAO; } PrepareDrawBuffers(stride); // Makes sure we can actually do Dual source blending bool dualSourcePossible = g_ActiveConfig.backend_info.bSupportsDualSourceBlend; // If host supports GL_ARB_blend_func_extended, we can do dst alpha in // the same pass as regular rendering. if (useDstAlpha && dualSourcePossible) { ProgramShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, m_current_primitive_type); } else { ProgramShaderCache::SetShader(DSTALPHA_NONE, m_current_primitive_type); } // upload global constants ProgramShaderCache::UploadConstants(); // setup the pointers nativeVertexFmt->SetupVertexPointers(); Draw(stride); // run through vertex groups again to set alpha if (useDstAlpha && !dualSourcePossible) { ProgramShaderCache::SetShader(DSTALPHA_ALPHA_PASS, m_current_primitive_type); // only update alpha glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); glDisable(GL_BLEND); Draw(stride); // restore color mask g_renderer->SetColorMask(); if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) glEnable(GL_BLEND); } #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { // save the shaders ProgramShaderCache::PCacheEntry prog = ProgramShaderCache::GetShaderProgram(); std::string filename = StringFromFormat( "%sps%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); std::ofstream fps; OpenFStream(fps, filename, std::ios_base::out); fps << prog.shader.strpprog; filename = StringFromFormat("%svs%.3d.txt", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); std::ofstream fvs; OpenFStream(fvs, filename, std::ios_base::out); fvs << prog.shader.strvprog; } if (g_ActiveConfig.iLog & CONF_SAVETARGETS) { std::string filename = StringFromFormat("%starg%.3d.png", File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), g_ActiveConfig.iSaveTargetId); TargetRectangle tr; tr.left = 0; tr.right = Renderer::GetTargetWidth(); tr.top = 0; tr.bottom = Renderer::GetTargetHeight(); g_renderer->SaveScreenshot(filename, tr); } #endif g_Config.iSaveTargetId++; ClearEFBCache(); } } // namespace
ssize_t UdpTransport::SendSinglePacketHelper( Header* header, const uint8_t* tx_data, size_t tx_length, uint8_t* rx_data, size_t rx_length, const int attempts, std::string* error) { ssize_t total_data_bytes = 0; error->clear(); int attempts_left = attempts; while (attempts_left > 0) { if (!socket_->Send({{header->bytes(), kHeaderSize}, {tx_data, tx_length}})) { *error = Socket::GetErrorMessage(); return -1; } // Keep receiving until we get a matching response or we timeout. ssize_t bytes = 0; do { bytes = socket_->Receive(rx_packet_.data(), rx_packet_.size(), kResponseTimeoutMs); if (bytes == -1) { if (socket_->ReceiveTimedOut()) { break; } *error = Socket::GetErrorMessage(); return -1; } else if (bytes < static_cast<ssize_t>(kHeaderSize)) { *error = "protocol error: incomplete header"; return -1; } } while (!header->Matches(rx_packet_.data())); if (socket_->ReceiveTimedOut()) { --attempts_left; continue; } ++sequence_; // Save to |error| or |rx_data| as appropriate. if (rx_packet_[kIndexId] == kIdError) { error->append(rx_packet_.data() + kHeaderSize, rx_packet_.data() + bytes); } else { total_data_bytes += bytes - kHeaderSize; size_t rx_data_bytes = std::min<size_t>(bytes - kHeaderSize, rx_length); if (rx_data_bytes > 0) { memcpy(rx_data, rx_packet_.data() + kHeaderSize, rx_data_bytes); rx_data += rx_data_bytes; rx_length -= rx_data_bytes; } } // If the response has a continuation flag we need to prompt for more data by sending // an empty packet. if (rx_packet_[kIndexFlags] & kFlagContinuation) { // We got a valid response so reset our attempt counter. attempts_left = attempts; header->Set(rx_packet_[kIndexId], sequence_, kFlagNone); tx_data = nullptr; tx_length = 0; continue; } break; } if (attempts_left <= 0) { *error = "no response from target"; return -1; } if (rx_packet_[kIndexId] == kIdError) { *error = "target reported error: " + *error; return -1; } return total_data_bytes; }
std::unique_ptr<T> downcast_unique(std::unique_ptr<U> p) { return std::unique_ptr<T>(dynamic_cast<T*>(p.release())); }
DestinationImageType transformImage() override { return filter->apply(*this->sourceImage); }
static void UpdatePadCallback(u64 userdata, int cycles_late) { SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); if (is_device_reload_pending.exchange(false)) LoadInputDevices(); PadState state; using namespace Settings::NativeButton; state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); state.right.Assign(buttons[Right - BUTTON_HID_BEGIN]->GetStatus()); state.left.Assign(buttons[Left - BUTTON_HID_BEGIN]->GetStatus()); state.up.Assign(buttons[Up - BUTTON_HID_BEGIN]->GetStatus()); state.down.Assign(buttons[Down - BUTTON_HID_BEGIN]->GetStatus()); state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); state.start.Assign(buttons[Start - BUTTON_HID_BEGIN]->GetStatus()); state.select.Assign(buttons[Select - BUTTON_HID_BEGIN]->GetStatus()); // Get current circle pad position and update circle pad direction float circle_pad_x_f, circle_pad_y_f; std::tie(circle_pad_x_f, circle_pad_y_f) = circle_pad->GetStatus(); constexpr int MAX_CIRCLEPAD_POS = 0x9C; // Max value for a circle pad position s16 circle_pad_x = static_cast<s16>(circle_pad_x_f * MAX_CIRCLEPAD_POS); s16 circle_pad_y = static_cast<s16>(circle_pad_y_f * MAX_CIRCLEPAD_POS); const DirectionState direction = GetStickDirectionState(circle_pad_x, circle_pad_y); state.circle_up.Assign(direction.up); state.circle_down.Assign(direction.down); state.circle_left.Assign(direction.left); state.circle_right.Assign(direction.right); mem->pad.current_state.hex = state.hex; mem->pad.index = next_pad_index; next_pad_index = (next_pad_index + 1) % mem->pad.entries.size(); // Get the previous Pad state u32 last_entry_index = (mem->pad.index - 1) % mem->pad.entries.size(); PadState old_state = mem->pad.entries[last_entry_index].current_state; // Compute bitmask with 1s for bits different from the old state PadState changed = {{(state.hex ^ old_state.hex)}}; // Get the current Pad entry PadDataEntry& pad_entry = mem->pad.entries[mem->pad.index]; // Update entry properties pad_entry.current_state.hex = state.hex; pad_entry.delta_additions.hex = changed.hex & state.hex; pad_entry.delta_removals.hex = changed.hex & old_state.hex; pad_entry.circle_pad_x = circle_pad_x; pad_entry.circle_pad_y = circle_pad_y; // If we just updated index 0, provide a new timestamp if (mem->pad.index == 0) { mem->pad.index_reset_ticks_previous = mem->pad.index_reset_ticks; mem->pad.index_reset_ticks = (s64)CoreTiming::GetTicks(); } mem->touch.index = next_touch_index; next_touch_index = (next_touch_index + 1) % mem->touch.entries.size(); // Get the current touch entry TouchDataEntry& touch_entry = mem->touch.entries[mem->touch.index]; bool pressed = false; float x, y; std::tie(x, y, pressed) = touch_device->GetStatus(); touch_entry.x = static_cast<u16>(x * Core::kScreenBottomWidth); touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight); touch_entry.valid.Assign(pressed ? 1 : 0); // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being // converted to pixel coordinates." (http://3dbrew.org/wiki/HID_Shared_Memory#Offset_0xA8). // If we just updated index 0, provide a new timestamp if (mem->touch.index == 0) { mem->touch.index_reset_ticks_previous = mem->touch.index_reset_ticks; mem->touch.index_reset_ticks = (s64)CoreTiming::GetTicks(); } // Signal both handles when there's an update to Pad or touch event_pad_or_touch_1->Signal(); event_pad_or_touch_2->Signal(); // Reschedule recurrent event CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); }
explicit Sprite(const std::unique_ptr<Texture> &texture, int32_t texX, int32_t texY, int32_t width, int32_t height) : Sprite(texture.get(), texX, texY, width, height) { }
namespace HID { // Handle to shared memory region designated to HID_User service static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; // Event handles static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_1; static Kernel::SharedPtr<Kernel::Event> event_pad_or_touch_2; static Kernel::SharedPtr<Kernel::Event> event_accelerometer; static Kernel::SharedPtr<Kernel::Event> event_gyroscope; static Kernel::SharedPtr<Kernel::Event> event_debug_pad; static u32 next_pad_index; static u32 next_touch_index; static u32 next_accelerometer_index; static u32 next_gyroscope_index; static int enable_accelerometer_count; // positive means enabled static int enable_gyroscope_count; // positive means enabled static int pad_update_event; static int accelerometer_update_event; static int gyroscope_update_event; // Updating period for each HID device. These empirical values are measured from a 11.2 3DS. constexpr u64 pad_update_ticks = BASE_CLOCK_RATE_ARM11 / 234; constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE_ARM11 / 104; constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE_ARM11 / 101; constexpr float accelerometer_coef = 512.0f; // measured from hw test result constexpr float gyroscope_coef = 14.375f; // got from hwtest GetGyroscopeLowRawToDpsCoefficient call static std::atomic<bool> is_device_reload_pending; static std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID> buttons; static std::unique_ptr<Input::AnalogDevice> circle_pad; static std::unique_ptr<Input::MotionDevice> motion_device; static std::unique_ptr<Input::TouchDevice> touch_device; DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) { // 30 degree and 60 degree are angular thresholds for directions constexpr float TAN30 = 0.577350269f; constexpr float TAN60 = 1 / TAN30; // a circle pad radius greater than 40 will trigger circle pad direction constexpr int CIRCLE_PAD_THRESHOLD_SQUARE = 40 * 40; DirectionState state{false, false, false, false}; if (circle_pad_x * circle_pad_x + circle_pad_y * circle_pad_y > CIRCLE_PAD_THRESHOLD_SQUARE) { float t = std::abs(static_cast<float>(circle_pad_y) / circle_pad_x); if (circle_pad_x != 0 && t < TAN60) { if (circle_pad_x > 0) state.right = true; else state.left = true; } if (circle_pad_x == 0 || t > TAN30) { if (circle_pad_y > 0) state.up = true; else state.down = true; } } return state; } static void LoadInputDevices() { std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END, buttons.begin(), Input::CreateDevice<Input::ButtonDevice>); circle_pad = Input::CreateDevice<Input::AnalogDevice>( Settings::values.analogs[Settings::NativeAnalog::CirclePad]); motion_device = Input::CreateDevice<Input::MotionDevice>(Settings::values.motion_device); touch_device = Input::CreateDevice<Input::TouchDevice>(Settings::values.touch_device); } static void UnloadInputDevices() { for (auto& button : buttons) { button.reset(); } circle_pad.reset(); motion_device.reset(); touch_device.reset(); } static void UpdatePadCallback(u64 userdata, int cycles_late) { SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); if (is_device_reload_pending.exchange(false)) LoadInputDevices(); PadState state; using namespace Settings::NativeButton; state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus()); state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus()); state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus()); state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus()); state.right.Assign(buttons[Right - BUTTON_HID_BEGIN]->GetStatus()); state.left.Assign(buttons[Left - BUTTON_HID_BEGIN]->GetStatus()); state.up.Assign(buttons[Up - BUTTON_HID_BEGIN]->GetStatus()); state.down.Assign(buttons[Down - BUTTON_HID_BEGIN]->GetStatus()); state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus()); state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus()); state.start.Assign(buttons[Start - BUTTON_HID_BEGIN]->GetStatus()); state.select.Assign(buttons[Select - BUTTON_HID_BEGIN]->GetStatus()); // Get current circle pad position and update circle pad direction float circle_pad_x_f, circle_pad_y_f; std::tie(circle_pad_x_f, circle_pad_y_f) = circle_pad->GetStatus(); constexpr int MAX_CIRCLEPAD_POS = 0x9C; // Max value for a circle pad position s16 circle_pad_x = static_cast<s16>(circle_pad_x_f * MAX_CIRCLEPAD_POS); s16 circle_pad_y = static_cast<s16>(circle_pad_y_f * MAX_CIRCLEPAD_POS); const DirectionState direction = GetStickDirectionState(circle_pad_x, circle_pad_y); state.circle_up.Assign(direction.up); state.circle_down.Assign(direction.down); state.circle_left.Assign(direction.left); state.circle_right.Assign(direction.right); mem->pad.current_state.hex = state.hex; mem->pad.index = next_pad_index; next_pad_index = (next_pad_index + 1) % mem->pad.entries.size(); // Get the previous Pad state u32 last_entry_index = (mem->pad.index - 1) % mem->pad.entries.size(); PadState old_state = mem->pad.entries[last_entry_index].current_state; // Compute bitmask with 1s for bits different from the old state PadState changed = {{(state.hex ^ old_state.hex)}}; // Get the current Pad entry PadDataEntry& pad_entry = mem->pad.entries[mem->pad.index]; // Update entry properties pad_entry.current_state.hex = state.hex; pad_entry.delta_additions.hex = changed.hex & state.hex; pad_entry.delta_removals.hex = changed.hex & old_state.hex; pad_entry.circle_pad_x = circle_pad_x; pad_entry.circle_pad_y = circle_pad_y; // If we just updated index 0, provide a new timestamp if (mem->pad.index == 0) { mem->pad.index_reset_ticks_previous = mem->pad.index_reset_ticks; mem->pad.index_reset_ticks = (s64)CoreTiming::GetTicks(); } mem->touch.index = next_touch_index; next_touch_index = (next_touch_index + 1) % mem->touch.entries.size(); // Get the current touch entry TouchDataEntry& touch_entry = mem->touch.entries[mem->touch.index]; bool pressed = false; float x, y; std::tie(x, y, pressed) = touch_device->GetStatus(); touch_entry.x = static_cast<u16>(x * Core::kScreenBottomWidth); touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight); touch_entry.valid.Assign(pressed ? 1 : 0); // TODO(bunnei): We're not doing anything with offset 0xA8 + 0x18 of HID SharedMemory, which // supposedly is "Touch-screen entry, which contains the raw coordinate data prior to being // converted to pixel coordinates." (http://3dbrew.org/wiki/HID_Shared_Memory#Offset_0xA8). // If we just updated index 0, provide a new timestamp if (mem->touch.index == 0) { mem->touch.index_reset_ticks_previous = mem->touch.index_reset_ticks; mem->touch.index_reset_ticks = (s64)CoreTiming::GetTicks(); } // Signal both handles when there's an update to Pad or touch event_pad_or_touch_1->Signal(); event_pad_or_touch_2->Signal(); // Reschedule recurrent event CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event); } static void UpdateAccelerometerCallback(u64 userdata, int cycles_late) { SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); mem->accelerometer.index = next_accelerometer_index; next_accelerometer_index = (next_accelerometer_index + 1) % mem->accelerometer.entries.size(); Math::Vec3<float> accel; std::tie(accel, std::ignore) = motion_device->GetStatus(); accel *= accelerometer_coef; // TODO(wwylele): do a time stretch like the one in UpdateGyroscopeCallback // The time stretch formula should be like // stretched_vector = (raw_vector - gravity) * stretch_ratio + gravity AccelerometerDataEntry& accelerometer_entry = mem->accelerometer.entries[mem->accelerometer.index]; accelerometer_entry.x = static_cast<s16>(accel.x); accelerometer_entry.y = static_cast<s16>(accel.y); accelerometer_entry.z = static_cast<s16>(accel.z); // Make up "raw" entry // TODO(wwylele): // From hardware testing, the raw_entry values are approximately, but not exactly, as twice as // corresponding entries (or with a minus sign). It may caused by system calibration to the // accelerometer. Figure out how it works, or, if no game reads raw_entry, the following three // lines can be removed and leave raw_entry unimplemented. mem->accelerometer.raw_entry.x = -2 * accelerometer_entry.x; mem->accelerometer.raw_entry.z = 2 * accelerometer_entry.y; mem->accelerometer.raw_entry.y = -2 * accelerometer_entry.z; // If we just updated index 0, provide a new timestamp if (mem->accelerometer.index == 0) { mem->accelerometer.index_reset_ticks_previous = mem->accelerometer.index_reset_ticks; mem->accelerometer.index_reset_ticks = (s64)CoreTiming::GetTicks(); } event_accelerometer->Signal(); // Reschedule recurrent event CoreTiming::ScheduleEvent(accelerometer_update_ticks - cycles_late, accelerometer_update_event); } static void UpdateGyroscopeCallback(u64 userdata, int cycles_late) { SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer()); mem->gyroscope.index = next_gyroscope_index; next_gyroscope_index = (next_gyroscope_index + 1) % mem->gyroscope.entries.size(); GyroscopeDataEntry& gyroscope_entry = mem->gyroscope.entries[mem->gyroscope.index]; Math::Vec3<float> gyro; std::tie(std::ignore, gyro) = motion_device->GetStatus(); double stretch = Core::System::GetInstance().perf_stats.GetLastFrameTimeScale(); gyro *= gyroscope_coef * static_cast<float>(stretch); gyroscope_entry.x = static_cast<s16>(gyro.x); gyroscope_entry.y = static_cast<s16>(gyro.y); gyroscope_entry.z = static_cast<s16>(gyro.z); // Make up "raw" entry mem->gyroscope.raw_entry.x = gyroscope_entry.x; mem->gyroscope.raw_entry.z = -gyroscope_entry.y; mem->gyroscope.raw_entry.y = gyroscope_entry.z; // If we just updated index 0, provide a new timestamp if (mem->gyroscope.index == 0) { mem->gyroscope.index_reset_ticks_previous = mem->gyroscope.index_reset_ticks; mem->gyroscope.index_reset_ticks = (s64)CoreTiming::GetTicks(); } event_gyroscope->Signal(); // Reschedule recurrent event CoreTiming::ScheduleEvent(gyroscope_update_ticks - cycles_late, gyroscope_update_event); } void GetIPCHandles(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = 0; // No error cmd_buff[2] = 0x14000000; // IPC Command Structure translate-header // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling) cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::shared_mem).Unwrap(); cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_1).Unwrap(); cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::event_pad_or_touch_2).Unwrap(); cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::event_accelerometer).Unwrap(); cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::event_gyroscope).Unwrap(); cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::event_debug_pad).Unwrap(); } void EnableAccelerometer(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ++enable_accelerometer_count; // Schedules the accelerometer update event if the accelerometer was just enabled if (enable_accelerometer_count == 1) { CoreTiming::ScheduleEvent(accelerometer_update_ticks, accelerometer_update_event); } cmd_buff[1] = RESULT_SUCCESS.raw; LOG_DEBUG(Service_HID, "called"); } void DisableAccelerometer(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); --enable_accelerometer_count; // Unschedules the accelerometer update event if the accelerometer was just disabled if (enable_accelerometer_count == 0) { CoreTiming::UnscheduleEvent(accelerometer_update_event, 0); } cmd_buff[1] = RESULT_SUCCESS.raw; LOG_DEBUG(Service_HID, "called"); } void EnableGyroscopeLow(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); ++enable_gyroscope_count; // Schedules the gyroscope update event if the gyroscope was just enabled if (enable_gyroscope_count == 1) { CoreTiming::ScheduleEvent(gyroscope_update_ticks, gyroscope_update_event); } cmd_buff[1] = RESULT_SUCCESS.raw; LOG_DEBUG(Service_HID, "called"); } void DisableGyroscopeLow(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); --enable_gyroscope_count; // Unschedules the gyroscope update event if the gyroscope was just disabled if (enable_gyroscope_count == 0) { CoreTiming::UnscheduleEvent(gyroscope_update_event, 0); } cmd_buff[1] = RESULT_SUCCESS.raw; LOG_DEBUG(Service_HID, "called"); } void GetGyroscopeLowRawToDpsCoefficient(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; f32 coef = gyroscope_coef; memcpy(&cmd_buff[2], &coef, 4); } void GetGyroscopeLowCalibrateParam(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); cmd_buff[1] = RESULT_SUCCESS.raw; const s16 param_unit = 6700; // an approximate value taken from hw GyroscopeCalibrateParam param = { {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, {0, param_unit, -param_unit}, }; memcpy(&cmd_buff[2], ¶m, sizeof(param)); LOG_WARNING(Service_HID, "(STUBBED) called"); } void GetSoundVolume(Service::Interface* self) { u32* cmd_buff = Kernel::GetCommandBuffer(); const u8 volume = 0x3F; // TODO(purpasmart): Find out if this is the max value for the volume cmd_buff[1] = RESULT_SUCCESS.raw; cmd_buff[2] = volume; LOG_WARNING(Service_HID, "(STUBBED) called"); } void Init() { using namespace Kernel; AddService(new HID_U_Interface); AddService(new HID_SPVR_Interface); is_device_reload_pending.store(true); using Kernel::MemoryPermission; shared_mem = SharedMemory::Create(nullptr, 0x1000, MemoryPermission::ReadWrite, MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); next_pad_index = 0; next_touch_index = 0; next_accelerometer_index = 0; next_gyroscope_index = 0; enable_accelerometer_count = 0; enable_gyroscope_count = 0; // Create event handles event_pad_or_touch_1 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch1"); event_pad_or_touch_2 = Event::Create(ResetType::OneShot, "HID:EventPadOrTouch2"); event_accelerometer = Event::Create(ResetType::OneShot, "HID:EventAccelerometer"); event_gyroscope = Event::Create(ResetType::OneShot, "HID:EventGyroscope"); event_debug_pad = Event::Create(ResetType::OneShot, "HID:EventDebugPad"); // Register update callbacks pad_update_event = CoreTiming::RegisterEvent("HID::UpdatePadCallback", UpdatePadCallback); accelerometer_update_event = CoreTiming::RegisterEvent("HID::UpdateAccelerometerCallback", UpdateAccelerometerCallback); gyroscope_update_event = CoreTiming::RegisterEvent("HID::UpdateGyroscopeCallback", UpdateGyroscopeCallback); CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); } void Shutdown() { shared_mem = nullptr; event_pad_or_touch_1 = nullptr; event_pad_or_touch_2 = nullptr; event_accelerometer = nullptr; event_gyroscope = nullptr; event_debug_pad = nullptr; UnloadInputDevices(); } void ReloadInputDevices() { is_device_reload_pending.store(true); } } // namespace HID
void locate_controls() { m_base.set_client_dimension(dimension_type{ width_type{ 36 }, height_type{ 10 } }); m_p_application_image->fit_to_content(); m_p_application_image->set_position(position_type{ left_type{ 2 }, top_type{ 1 } }); const auto label_left = left_type{ 2 } + tetengo2::gui::dimension<dimension_type>::width(m_p_application_image->dimension()) + left_type{ 1 }; m_p_title_label->fit_to_content(); m_p_title_label->set_position(position_type{ label_left, top_type{ 1 } }); m_p_copyright_label->fit_to_content(); m_p_copyright_label->set_position(position_type{ label_left, top_type{ 3 } }); m_p_link_label->fit_to_content(); m_p_link_label->set_position(position_type{ label_left, top_type{ 5 } }); m_p_ok_button->set_dimension(dimension_type{ width_type{ 8 }, height_type{ 2 } }); m_p_ok_button->set_position(position_type{ left_type{ 26 }, top_type{ 7 } }); }
int ReadLiveStream(unsigned char *pBuffer, unsigned int iBufferSize) { int ret = g_pvr_client->read_data(pBuffer, iBufferSize); return ret; }
void MetadataManager::refreshActiveMetadata(std::unique_ptr<CollectionMetadata> remoteMetadata) { LOG(1) << "Refreshing the active metadata from " << (_activeMetadataTracker->metadata ? _activeMetadataTracker->metadata->toStringBasic() : "(empty)") << ", to " << (remoteMetadata ? remoteMetadata->toStringBasic() : "(empty)"); stdx::lock_guard<stdx::mutex> scopedLock(_managerLock); // Collection is not sharded anymore if (!remoteMetadata) { log() << "Marking collection as not sharded."; _receivingChunks.clear(); _rangesToClean.clear(); _setActiveMetadata_inlock(nullptr); return; } invariant(!remoteMetadata->getCollVersion().isWriteCompatibleWith(ChunkVersion::UNSHARDED())); invariant(!remoteMetadata->getShardVersion().isWriteCompatibleWith(ChunkVersion::UNSHARDED())); // Collection is not sharded currently if (!_activeMetadataTracker->metadata) { log() << "Marking collection as sharded with " << remoteMetadata->toStringBasic(); invariant(_receivingChunks.empty()); invariant(_rangesToClean.empty()); _setActiveMetadata_inlock(std::move(remoteMetadata)); return; } // If the metadata being installed has a different epoch from ours, this means the collection // was dropped and recreated, so we must entirely reset the metadata state if (_activeMetadataTracker->metadata->getCollVersion().epoch() != remoteMetadata->getCollVersion().epoch()) { log() << "Overwriting collection metadata due to epoch change."; _receivingChunks.clear(); _rangesToClean.clear(); _setActiveMetadata_inlock(std::move(remoteMetadata)); return; } // We already have newer version if (_activeMetadataTracker->metadata->getCollVersion() >= remoteMetadata->getCollVersion()) { LOG(1) << "Attempted to refresh active metadata " << _activeMetadataTracker->metadata->toStringBasic() << " with an older " << remoteMetadata->toStringBasic(); return; } // Resolve any receiving chunks, which might have completed by now for (auto it = _receivingChunks.begin(); it != _receivingChunks.end();) { const BSONObj min = it->first; const BSONObj max = it->second; // Our pending range overlaps at least one chunk if (rangeMapContains(remoteMetadata->getChunks(), min, max)) { // The remote metadata contains a chunk we were earlier in the process of receiving, so // we deem it successfully received. LOG(2) << "Verified chunk " << ChunkRange(min, max).toString() << " was migrated earlier to this shard"; _receivingChunks.erase(it++); continue; } else if (!rangeMapOverlaps(remoteMetadata->getChunks(), min, max)) { ++it; continue; } // Partial overlap indicates that the earlier migration has failed, but the chunk being // migrated underwent some splits and other migrations and ended up here again. In this // case, we will request full reload of the metadata. Currently this cannot happen, because // all migrations are with the explicit knowledge of the recipient shard. However, we leave // the option open so that chunk splits can do empty chunk move without having to notify the // recipient. RangeVector overlappedChunks; getRangeMapOverlap(remoteMetadata->getChunks(), min, max, &overlappedChunks); for (const auto& overlapChunkMin : overlappedChunks) { auto itRecv = _receivingChunks.find(overlapChunkMin.first); invariant(itRecv != _receivingChunks.end()); const ChunkRange receivingRange(itRecv->first, itRecv->second); _receivingChunks.erase(itRecv); // Make sure any potentially partially copied chunks are scheduled to be cleaned up _addRangeToClean_inlock(receivingRange); } // Need to reset the iterator it = _receivingChunks.begin(); } // For compatibility with the current range deleter, which is driven entirely by the contents of // the CollectionMetadata update the pending chunks for (const auto& receivingChunk : _receivingChunks) { ChunkType chunk; chunk.setMin(receivingChunk.first); chunk.setMax(receivingChunk.second); remoteMetadata = remoteMetadata->clonePlusPending(chunk); } _setActiveMetadata_inlock(std::move(remoteMetadata)); }
bool IsTimeshifting(void) { return g_pvr_client->is_timeshifting(); }
void Stage::process(void) { static ProcessingState last_processing_state = ProcessingState::Idle; static std::unique_ptr<StageBuilder> builder; bool done = false; // Have we changed states? if (impl->processing_state_ != last_processing_state) { // Clean up the last state if needed. switch (last_processing_state) { case ProcessingState::SmoothTerrain: impl->UpdateAllColumnData(); break; default: break; } // Update the last processing state. last_processing_state = impl->processing_state_; // Initialize the new state if needed. switch (impl->processing_state_) { case ProcessingState::GenerateTerrain: builder.reset( new StageBuilderTerrain(*this, impl->seed_, Settings::terrainStageHeight, Settings::terrainFeatureHeight, Settings::terrainFrequency, Settings::terrainOctaveCount, Settings::terrainPersistence, Settings::terrainLacunarity)); break; case ProcessingState::AddDeposits: builder.reset(new StageBuilderDeposits(*this, impl->seed_)); break; case ProcessingState::AddLakes: builder.reset( new StageBuilderLakes(*this, impl->seed_, Settings::terrainSeaLevel)); break; case ProcessingState::AddBeaches: builder.reset( new StageBuilderBeaches(*this, impl->seed_, Settings::terrainSeaLevel)); break; case ProcessingState::AddRivers: builder.reset( new StageBuilderRivers(*this, impl->seed_, Settings::terrainSeaLevel)); break; case ProcessingState::AddFlora: builder.reset( new StageBuilderFlora(*this, impl->seed_, Settings::terrainPlainsThreshold, Settings::terrainForestThreshold)); break; case ProcessingState::AddFauna: // TODO: create builder for this! builder.reset(); break; case ProcessingState::SetPlayerKnowledge: builder.reset(new StageBuilderKnownStatus(*this, impl->seed_)); break; default: builder.reset(); break; } } if (builder.get() != nullptr) { done = builder->Build(); } else { done = true; } // Other stuff to do while in the state. switch (impl->processing_state_) { case ProcessingState::Idle: // This is the state prior to world generation. break; case ProcessingState::GenerateTerrain: if (done) { impl->processing_state_ = ProcessingState::AddDeposits; } break; case ProcessingState::AddDeposits: if (done) { impl->UpdateAllColumnData(); impl->processing_state_ = ProcessingState::AddLakes; } break; case ProcessingState::AddLakes: if (done) { impl->processing_state_ = ProcessingState::AddBeaches; } break; case ProcessingState::AddBeaches: if (done) { impl->processing_state_ = ProcessingState::AddRivers; } break; case ProcessingState::AddRivers: if (done) { impl->UpdateAllColumnData(); impl->processing_state_ = ProcessingState::AddFlora; } break; case ProcessingState::AddFlora: if (done) { impl->processing_state_ = ProcessingState::AddFauna; } break; case ProcessingState::AddFauna: impl->processing_state_ = ProcessingState::SetPlayerKnowledge; break; case ProcessingState::SetPlayerKnowledge: if (done) { std::cout << "Terrain generation complete. Moving to PAUSED state." << std::endl; // At this point it's okay to do map rendering. impl->okay_to_render_map_ = true; impl->processing_state_ = ProcessingState::Paused; } break; case ProcessingState::Paused: // This is the state when world processing is paused. break; case ProcessingState::Running: // This is the state when world processing is running. impl->UpdateAllColumnData(); break; case ProcessingState::Halted: // This is the state when world processing is halted. break; default: break; } }
void ADDON_Destroy() { g_pvr_client.reset(); m_bCreated = false; m_CurStatus = ADDON_STATUS_UNKNOWN; }
void CGUIEPGGridContainerModel::Refresh(const std::unique_ptr<CFileItemList> &items, const CDateTime &gridStart, const CDateTime &gridEnd, int iRulerUnit, int iBlocksPerPage, float fBlockSize) { Reset(); //////////////////////////////////////////////////////////////////////// // Create programme & channel items m_programmeItems.reserve(items->Size()); CFileItemPtr fileItem; int iLastChannelID = -1; ItemsPtr itemsPointer; itemsPointer.start = 0; CPVRChannelPtr channel; int j = 0; for (int i = 0; i < items->Size(); ++i) { fileItem = items->Get(i); if (!fileItem->HasEPGInfoTag() || !fileItem->GetEPGInfoTag()->HasChannel()) continue; m_programmeItems.emplace_back(fileItem); channel = fileItem->GetEPGInfoTag()->Channel(); if (!channel) continue; int iCurrentChannelID = channel->ChannelID(); if (iCurrentChannelID != iLastChannelID) { if (j > 0) { itemsPointer.stop = j - 1; m_epgItemsPtr.emplace_back(itemsPointer); itemsPointer.start = j; } iLastChannelID = iCurrentChannelID; m_channelItems.emplace_back(CFileItemPtr(new CFileItem(channel))); } ++j; } if (!m_programmeItems.empty()) { itemsPointer.stop = m_programmeItems.size() - 1; m_epgItemsPtr.emplace_back(itemsPointer); } /* check for invalid start and end time */ if (gridStart >= gridEnd) { // default to start "now minus GRID_START_PADDING minutes" and end "start plus one page". m_gridStart = CDateTime::GetUTCDateTime() - CDateTimeSpan(0, 0, GetGridStartPadding(), 0); m_gridEnd = m_gridStart + CDateTimeSpan(0, 0, iBlocksPerPage * MINSPERBLOCK, 0); } else if (gridStart > (CDateTime::GetUTCDateTime() - CDateTimeSpan(0, 0, GetGridStartPadding(), 0))) { // adjust to start "now minus GRID_START_PADDING minutes". m_gridStart = CDateTime::GetUTCDateTime() - CDateTimeSpan(0, 0, GetGridStartPadding(), 0); m_gridEnd = gridEnd; } else { m_gridStart = gridStart; m_gridEnd = gridEnd; } // roundup m_gridStart = CDateTime(m_gridStart.GetYear(), m_gridStart.GetMonth(), m_gridStart.GetDay(), m_gridStart.GetHour(), m_gridStart.GetMinute() >= 30 ? 30 : 0, 0); m_gridEnd = CDateTime(m_gridEnd.GetYear(), m_gridEnd.GetMonth(), m_gridEnd.GetDay(), m_gridEnd.GetHour(), m_gridEnd.GetMinute() >= 30 ? 30 : 0, 0); //////////////////////////////////////////////////////////////////////// // Create ruler items CDateTime ruler; ruler.SetFromUTCDateTime(m_gridStart); CDateTime rulerEnd; rulerEnd.SetFromUTCDateTime(m_gridEnd); CFileItemPtr rulerItem(new CFileItem(ruler.GetAsLocalizedDate(true))); rulerItem->SetProperty("DateLabel", true); m_rulerItems.emplace_back(rulerItem); const CDateTimeSpan unit(0, 0, iRulerUnit * MINSPERBLOCK, 0); for (; ruler < rulerEnd; ruler += unit) { rulerItem.reset(new CFileItem(ruler.GetAsLocalizedTime("", false))); rulerItem->SetLabel2(ruler.GetAsLocalizedDate(true)); m_rulerItems.emplace_back(rulerItem); } FreeItemsMemory(); //////////////////////////////////////////////////////////////////////// // Create epg grid const CDateTimeSpan blockDuration(0, 0, MINSPERBLOCK, 0); const CDateTimeSpan gridDuration(m_gridEnd - m_gridStart); m_blocks = (gridDuration.GetDays() * 24 * 60 + gridDuration.GetHours() * 60 + gridDuration.GetMinutes()) / MINSPERBLOCK; if (m_blocks >= MAXBLOCKS) m_blocks = MAXBLOCKS; else if (m_blocks < iBlocksPerPage) m_blocks = iBlocksPerPage; m_gridIndex.reserve(m_channelItems.size()); const std::vector<GridItem> blocks(m_blocks); for (size_t channel = 0; channel < m_channelItems.size(); ++channel) { m_gridIndex.emplace_back(blocks); CDateTime gridCursor(m_gridStart); //reset cursor for new channel unsigned long progIdx = m_epgItemsPtr[channel].start; unsigned long lastIdx = m_epgItemsPtr[channel].stop; int iEpgId = m_programmeItems[progIdx]->GetEPGInfoTag()->EpgID(); int itemSize = 1; // size of the programme in blocks int savedBlock = 0; CFileItemPtr item; CPVREpgInfoTagPtr tag; for (int block = 0; block < m_blocks; ++block) { while (progIdx <= lastIdx) { item = m_programmeItems[progIdx]; tag = item->GetEPGInfoTag(); // Note: Start block of an event is start-time-based calculated block + 1, // unless start times matches exactly the begin of a block. if (tag->EpgID() != iEpgId || gridCursor < tag->StartAsUTC() || m_gridEnd <= tag->StartAsUTC()) break; if (gridCursor < tag->EndAsUTC()) { m_gridIndex[channel][block].item = item; m_gridIndex[channel][block].progIndex = progIdx; break; } progIdx++; } gridCursor += blockDuration; if (block == 0) continue; const CFileItemPtr prevItem(m_gridIndex[channel][block - 1].item); const CFileItemPtr currItem(m_gridIndex[channel][block].item); if (block == m_blocks - 1 || prevItem != currItem) { // special handling for last block. int blockDelta = -1; int sizeDelta = 0; if (block == m_blocks - 1 && prevItem == currItem) { itemSize++; blockDelta = 0; sizeDelta = 1; } if (prevItem) { m_gridIndex[channel][savedBlock].item->SetProperty("GenreType", prevItem->GetEPGInfoTag()->GenreType()); } else { CPVREpgInfoTagPtr gapTag(CPVREpgInfoTag::CreateDefaultTag()); gapTag->SetChannel(m_channelItems[channel]->GetPVRChannelInfoTag()); CFileItemPtr gapItem(new CFileItem(gapTag)); for (int i = block + blockDelta; i >= block - itemSize + sizeDelta; --i) { m_gridIndex[channel][i].item = gapItem; } } float fItemWidth = itemSize * fBlockSize; m_gridIndex[channel][savedBlock].originWidth = fItemWidth; m_gridIndex[channel][savedBlock].width = fItemWidth; itemSize = 1; savedBlock = block; // special handling for last block. if (block == m_blocks - 1 && prevItem != currItem) { if (currItem) { m_gridIndex[channel][savedBlock].item->SetProperty("GenreType", currItem->GetEPGInfoTag()->GenreType()); } else { CPVREpgInfoTagPtr gapTag(CPVREpgInfoTag::CreateDefaultTag()); gapTag->SetChannel(m_channelItems[channel]->GetPVRChannelInfoTag()); CFileItemPtr gapItem(new CFileItem(gapTag)); m_gridIndex[channel][block].item = gapItem; } m_gridIndex[channel][savedBlock].originWidth = fBlockSize; // size always 1 block here m_gridIndex[channel][savedBlock].width = fBlockSize; } } else { itemSize++; } } } }
void ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int num) { scope->ISNewSwitch(dev, name, states, names, num); }
bool SetFontByName(const char* name, size_t size) { g_fontptr.reset(new FontManager(name, size)); return true; }
void ISNewNumber(const char *dev, const char *name, double values[], char *names[], int num) { scope->ISNewNumber(dev, name, values, names, num); }
Diagnostics* Diagnostics::Get() { static std::unique_ptr<Diagnostics> singleton = make_unique<Diagnostics>(); return singleton.get(); }
void Enum::appendChild(std::unique_ptr<ConstantAssignment> value) { setAsParent(value.get()); m_children.push_back(std::move(value)); }
NcclCommList(const std::vector<int>& devices) : comms(new ncclComm_t[devices.size()]), ndevices(devices.size()) { CHECK(ncclCommInitAll(comms.get(), devices.size(), devices.data())); }