diff --git a/jctool/FormJoy.h b/jctool/FormJoy.h index 5acf86e..f096669 100644 --- a/jctool/FormJoy.h +++ b/jctool/FormJoy.h @@ -275,6 +275,10 @@ public ref class FormJoy : public System::Windows::Forms::Form private: System::Windows::Forms::RadioButton^ radioBtn_IR60p; private: System::Windows::Forms::RadioButton^ radioBtn_IR120p; private: System::Windows::Forms::RadioButton^ radioBtn_IR240p; + private: System::Windows::Forms::GroupBox^ grpBox_IRMode; + private: System::Windows::Forms::RadioButton^ radioBtn_IRModeCapture; + private: System::Windows::Forms::RadioButton^ radioBtn_IRModeClustering; + private: System::Windows::Forms::RadioButton^ radioBtn_IRModePointing; private: System::Windows::Forms::TrackBar^ trackBar_IRGain; private: System::Windows::Forms::CheckBox^ chkBox_IRDimLeds; private: System::Windows::Forms::CheckBox^ chkBox_IRBrightLeds; @@ -359,7 +363,7 @@ public ref class FormJoy : public System::Windows::Forms::Form private: System::Windows::Forms::Label^ lbl_mainStickHelp; private: System::Windows::Forms::NumericUpDown^ numeric_StickParamRangeRatio2; private: System::Windows::Forms::NumericUpDown^ numeric_StickParamDeadzone2; - public: System::Windows::Forms::TextBox^ txtBox_NFCTag; + private: System::ComponentModel::ComponentResourceManager^ resources = (gcnew System::ComponentModel::ComponentResourceManager(images::typeid)); @@ -516,8 +520,11 @@ public ref class FormJoy : public System::Windows::Forms::Form this->radioBtn_IR60p = (gcnew System::Windows::Forms::RadioButton()); this->radioBtn_IR120p = (gcnew System::Windows::Forms::RadioButton()); this->radioBtn_IR240p = (gcnew System::Windows::Forms::RadioButton()); + this->grpBox_IRMode = (gcnew System::Windows::Forms::GroupBox()); + this->radioBtn_IRModeCapture = (gcnew System::Windows::Forms::RadioButton()); + this->radioBtn_IRModeClustering = (gcnew System::Windows::Forms::RadioButton()); + this->radioBtn_IRModePointing = (gcnew System::Windows::Forms::RadioButton()); this->grpBox_nfc = (gcnew System::Windows::Forms::GroupBox()); - this->txtBox_NFCTag = (gcnew System::Windows::Forms::TextBox()); this->txtBox_nfcUid = (gcnew System::Windows::Forms::TextBox()); this->btn_NFC = (gcnew System::Windows::Forms::Button()); this->lbl_nfcHelp = (gcnew System::Windows::Forms::Label()); @@ -611,6 +618,7 @@ public ref class FormJoy : public System::Windows::Forms::Form (cli::safe_cast(this->numeric_IRCustomRegAddr))->BeginInit(); this->grpBox_IRColorize->SuspendLayout(); this->grpBox_IRRes->SuspendLayout(); + this->grpBox_IRMode->SuspendLayout(); this->grpBox_nfc->SuspendLayout(); (cli::safe_cast(this->numeric_leftUserCal_y_plus))->BeginInit(); (cli::safe_cast(this->numeric_leftUserCal_y_center))->BeginInit(); @@ -2535,7 +2543,7 @@ public ref class FormJoy : public System::Windows::Forms::Form this->pictureBoxIR->Location = System::Drawing::Point(5, 21); this->pictureBoxIR->Margin = System::Windows::Forms::Padding(0); this->pictureBoxIR->Name = L"pictureBoxIR"; - this->pictureBoxIR->Size = System::Drawing::Size(242, 322); + this->pictureBoxIR->Size = System::Drawing::Size(242, 322); this->pictureBoxIR->SizeMode = System::Windows::Forms::PictureBoxSizeMode::StretchImage; this->pictureBoxIR->TabIndex = 2; this->pictureBoxIR->TabStop = false; @@ -2651,9 +2659,9 @@ public ref class FormJoy : public System::Windows::Forms::Form this->grpBox_IRColorize->FlatStyle = System::Windows::Forms::FlatStyle::Flat; this->grpBox_IRColorize->ForeColor = System::Drawing::Color::FromArgb(static_cast(static_cast(9)), static_cast(static_cast(255)), static_cast(static_cast(206))); - this->grpBox_IRColorize->Location = System::Drawing::Point(138, 20); + this->grpBox_IRColorize->Location = System::Drawing::Point(88/*138*/, 20); this->grpBox_IRColorize->Name = L"grpBox_IRColorize"; - this->grpBox_IRColorize->Size = System::Drawing::Size(125, 130); + this->grpBox_IRColorize->Size = System::Drawing::Size(95/*125*/, 130); this->grpBox_IRColorize->TabIndex = 4; this->grpBox_IRColorize->TabStop = false; this->grpBox_IRColorize->Text = L"Colorize"; @@ -2690,7 +2698,7 @@ public ref class FormJoy : public System::Windows::Forms::Form this->radioBtn_IRColorGreen->Name = L"radioBtn_IRColorGreen"; this->radioBtn_IRColorGreen->Size = System::Drawing::Size(95, 21); this->radioBtn_IRColorGreen->TabIndex = 2; - this->radioBtn_IRColorGreen->Text = L"Night vision"; + this->radioBtn_IRColorGreen->Text = L"Night vis"; this->radioBtn_IRColorGreen->UseVisualStyleBackColor = false; // // radioBtn_IRColorRed @@ -2769,7 +2777,7 @@ public ref class FormJoy : public System::Windows::Forms::Form static_cast(static_cast(206))); this->grpBox_IRRes->Location = System::Drawing::Point(10, 20); this->grpBox_IRRes->Name = L"grpBox_IRRes"; - this->grpBox_IRRes->Size = System::Drawing::Size(125, 130); + this->grpBox_IRRes->Size = System::Drawing::Size(85/*125*/, 130); this->grpBox_IRRes->TabIndex = 3; this->grpBox_IRRes->TabStop = false; this->grpBox_IRRes->Text = L"Resolution"; @@ -2789,7 +2797,7 @@ public ref class FormJoy : public System::Windows::Forms::Form this->radioBtn_IR30p->Name = L"radioBtn_IR30p"; this->radioBtn_IR30p->Size = System::Drawing::Size(68, 21); this->radioBtn_IR30p->TabIndex = 3; - this->radioBtn_IR30p->Text = L"30 x 40"; + this->radioBtn_IR30p->Text = L"30x40"; this->radioBtn_IR30p->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; this->radioBtn_IR30p->UseVisualStyleBackColor = false; // @@ -2808,7 +2816,7 @@ public ref class FormJoy : public System::Windows::Forms::Form this->radioBtn_IR60p->Name = L"radioBtn_IR60p"; this->radioBtn_IR60p->Size = System::Drawing::Size(68, 21); this->radioBtn_IR60p->TabIndex = 2; - this->radioBtn_IR60p->Text = L"60 x 80"; + this->radioBtn_IR60p->Text = L"60x80"; this->radioBtn_IR60p->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; this->radioBtn_IR60p->UseVisualStyleBackColor = false; // @@ -2827,7 +2835,7 @@ public ref class FormJoy : public System::Windows::Forms::Form this->radioBtn_IR120p->Name = L"radioBtn_IR120p"; this->radioBtn_IR120p->Size = System::Drawing::Size(82, 21); this->radioBtn_IR120p->TabIndex = 1; - this->radioBtn_IR120p->Text = L"120 x 160"; + this->radioBtn_IR120p->Text = L"120x160"; this->radioBtn_IR120p->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; this->radioBtn_IR120p->UseVisualStyleBackColor = false; // @@ -2849,15 +2857,86 @@ public ref class FormJoy : public System::Windows::Forms::Form this->radioBtn_IR240p->Size = System::Drawing::Size(82, 21); this->radioBtn_IR240p->TabIndex = 0; this->radioBtn_IR240p->TabStop = true; - this->radioBtn_IR240p->Text = L"240 x 320"; + this->radioBtn_IR240p->Text = L"240x320"; this->radioBtn_IR240p->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; this->radioBtn_IR240p->UseVisualStyleBackColor = false; // + // grpBox_IRMode + // + this->grpBox_IRMode->Controls->Add(this->radioBtn_IRModeCapture); + this->grpBox_IRMode->Controls->Add(this->radioBtn_IRModeClustering); + this->grpBox_IRMode->Controls->Add(this->radioBtn_IRModePointing); + this->grpBox_IRMode->FlatStyle = System::Windows::Forms::FlatStyle::Flat; + this->grpBox_IRMode->ForeColor = System::Drawing::Color::FromArgb(static_cast(static_cast(9)), static_cast(static_cast(255)), + static_cast(static_cast(206))); + this->grpBox_IRMode->Location = System::Drawing::Point(175, 20); + this->grpBox_IRMode->Name = L"grpBox_IRMode"; + this->grpBox_IRMode->Size = System::Drawing::Size(95, 130); + this->grpBox_IRMode->TabIndex = 4; + this->grpBox_IRMode->TabStop = false; + this->grpBox_IRMode->Text = L"Mode"; + // + // radioBtn_IRModeCapture + // + this->radioBtn_IRModeCapture->AutoSize = true; + this->radioBtn_IRModeCapture->Checked = true; + this->radioBtn_IRModeCapture->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(70)), static_cast(static_cast(70)), + static_cast(static_cast(70))); + this->radioBtn_IRModeCapture->FlatAppearance->BorderSize = 0; + this->radioBtn_IRModeCapture->Font = (gcnew System::Drawing::Font(L"Segoe UI", 9.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, + static_cast(161))); + this->radioBtn_IRModeCapture->ForeColor = System::Drawing::Color::FromArgb(static_cast(static_cast(255)), static_cast(static_cast(188)), + static_cast(static_cast(0))); + this->radioBtn_IRModeCapture->Location = System::Drawing::Point(10, 21); + this->radioBtn_IRModeCapture->Margin = System::Windows::Forms::Padding(0); + this->radioBtn_IRModeCapture->Name = L"radioBtn_IRModeCapture"; + this->radioBtn_IRModeCapture->Size = System::Drawing::Size(68, 21); + this->radioBtn_IRModeCapture->TabIndex = 3; + this->radioBtn_IRModeCapture->Text = L"Capture"; + this->radioBtn_IRModeCapture->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; + this->radioBtn_IRModeCapture->UseVisualStyleBackColor = false; + // + // radioBtn_IRModeClustering + // + this->radioBtn_IRModeClustering->AutoSize = true; + this->radioBtn_IRModeClustering->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(70)), static_cast(static_cast(70)), + static_cast(static_cast(70))); + this->radioBtn_IRModeClustering->FlatAppearance->BorderSize = 0; + this->radioBtn_IRModeClustering->Font = (gcnew System::Drawing::Font(L"Segoe UI", 9.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, + static_cast(161))); + this->radioBtn_IRModeClustering->ForeColor = System::Drawing::Color::FromArgb(static_cast(static_cast(255)), static_cast(static_cast(188)), + static_cast(static_cast(0))); + this->radioBtn_IRModeClustering->Location = System::Drawing::Point(10, 75); + this->radioBtn_IRModeClustering->Margin = System::Windows::Forms::Padding(0); + this->radioBtn_IRModeClustering->Name = L"radioBtn_IRModeClustering"; + this->radioBtn_IRModeClustering->Size = System::Drawing::Size(68, 21); + this->radioBtn_IRModeClustering->TabIndex = 2; + this->radioBtn_IRModeClustering->Text = L"Cluster"; + this->radioBtn_IRModeClustering->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; + this->radioBtn_IRModeClustering->UseVisualStyleBackColor = false; + // + // radioBtn_IRModePointing + // + this->radioBtn_IRModePointing->AutoSize = true; + this->radioBtn_IRModePointing->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(70)), static_cast(static_cast(70)), + static_cast(static_cast(70))); + this->radioBtn_IRModePointing->FlatAppearance->BorderSize = 0; + this->radioBtn_IRModePointing->Font = (gcnew System::Drawing::Font(L"Segoe UI", 9.75F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, + static_cast(161))); + this->radioBtn_IRModePointing->ForeColor = System::Drawing::Color::FromArgb(static_cast(static_cast(255)), static_cast(static_cast(188)), + static_cast(static_cast(0))); + this->radioBtn_IRModePointing->Location = System::Drawing::Point(10, 48); + this->radioBtn_IRModePointing->Margin = System::Windows::Forms::Padding(0); + this->radioBtn_IRModePointing->Name = L"radioBtn_IRModePointing"; + this->radioBtn_IRModePointing->Size = System::Drawing::Size(82, 21); + this->radioBtn_IRModePointing->TabIndex = 1; + this->radioBtn_IRModePointing->Text = L"Pointing"; + this->radioBtn_IRModePointing->TextAlign = System::Drawing::ContentAlignment::MiddleCenter; + // // grpBox_nfc // this->grpBox_nfc->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(70)), static_cast(static_cast(70)), static_cast(static_cast(70))); - this->grpBox_nfc->Controls->Add(this->txtBox_NFCTag); this->grpBox_nfc->Controls->Add(this->txtBox_nfcUid); this->grpBox_nfc->Controls->Add(this->btn_NFC); this->grpBox_nfc->Controls->Add(this->lbl_nfcHelp); @@ -2867,31 +2946,11 @@ public ref class FormJoy : public System::Windows::Forms::Form this->grpBox_nfc->Location = System::Drawing::Point(724, 445); this->grpBox_nfc->Margin = System::Windows::Forms::Padding(0, 0, 14, 0); this->grpBox_nfc->Name = L"grpBox_nfc"; - this->grpBox_nfc->Size = System::Drawing::Size(220, 399); + this->grpBox_nfc->Size = System::Drawing::Size(220, 215); this->grpBox_nfc->TabIndex = 35; this->grpBox_nfc->TabStop = false; this->grpBox_nfc->Text = L"NFC Simple Tag Info"; // - // txtBox_NFCTag - // - this->txtBox_NFCTag->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(70)), static_cast(static_cast(70)), - static_cast(static_cast(70))); - this->txtBox_NFCTag->BorderStyle = System::Windows::Forms::BorderStyle::None; - this->txtBox_NFCTag->Font = (gcnew System::Drawing::Font(L"Lucida Console", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, - static_cast(161))); - this->txtBox_NFCTag->ForeColor = System::Drawing::Color::FromArgb(static_cast(static_cast(9)), static_cast(static_cast(255)), - static_cast(static_cast(206))); - this->txtBox_NFCTag->Location = System::Drawing::Point(8, 218); - this->txtBox_NFCTag->Margin = System::Windows::Forms::Padding(0); - this->txtBox_NFCTag->Multiline = true; - this->txtBox_NFCTag->Name = L"txtBox_NFCTag"; - this->txtBox_NFCTag->ReadOnly = true; - this->txtBox_NFCTag->ScrollBars = System::Windows::Forms::ScrollBars::Vertical; - this->txtBox_NFCTag->Size = System::Drawing::Size(203, 165); - this->txtBox_NFCTag->TabIndex = 37; - this->txtBox_NFCTag->TabStop = false; - this->txtBox_NFCTag->Text = L"Tag contents"; - // // txtBox_nfcUid // this->txtBox_nfcUid->BackColor = System::Drawing::Color::FromArgb(static_cast(static_cast(70)), static_cast(static_cast(70)), @@ -2908,7 +2967,7 @@ public ref class FormJoy : public System::Windows::Forms::Form this->txtBox_nfcUid->Size = System::Drawing::Size(203, 37); this->txtBox_nfcUid->TabIndex = 36; this->txtBox_nfcUid->TabStop = false; - this->txtBox_nfcUid->Text = L"UID:\r\nType:"; + this->txtBox_nfcUid->Text = L"Type:\r\nUID:"; // // btn_NFC // @@ -3287,6 +3346,7 @@ public ref class FormJoy : public System::Windows::Forms::Form this->grpBox_IRSettings->Controls->Add(this->btn_IRConfigLive); this->grpBox_IRSettings->Controls->Add(this->grpBox_IRRes); this->grpBox_IRSettings->Controls->Add(this->grpBox_IRColorize); + this->grpBox_IRSettings->Controls->Add(this->grpBox_IRMode); this->grpBox_IRSettings->Controls->Add(this->numeric_IRCustomRegVal); this->grpBox_IRSettings->Controls->Add(this->numeric_IRCustomRegAddr); this->grpBox_IRSettings->Controls->Add(this->lbl_exposure); @@ -4013,6 +4073,8 @@ public ref class FormJoy : public System::Windows::Forms::Form this->grpBox_IRColorize->PerformLayout(); this->grpBox_IRRes->ResumeLayout(false); this->grpBox_IRRes->PerformLayout(); + this->grpBox_IRMode->ResumeLayout(false); + this->grpBox_IRMode->PerformLayout(); this->grpBox_nfc->ResumeLayout(false); this->grpBox_nfc->PerformLayout(); (cli::safe_cast(this->numeric_leftUserCal_y_plus))->EndInit(); @@ -4251,20 +4313,20 @@ public ref class FormJoy : public System::Windows::Forms::Form // Apply body color switch (handle_ok) { - case 1: - MyImage = (cli::safe_cast(resources->GetObject(L"base64_l_joy_body"))); - break; - case 2: - MyImage = (cli::safe_cast(resources->GetObject(L"base64_r_joy_body"))); - break; - case 3: - MyImage = (cli::safe_cast(resources->GetObject(L"base64_pro_body"))); - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_grips_l"))); - MyImageLayer2 = (cli::safe_cast(resources->GetObject(L"base64_pro_grips_r"))); - break; - default: - MyImage = (cli::safe_cast(resources->GetObject(L"base64_pro_body"))); - break; + case 1: + MyImage = (cli::safe_cast(resources->GetObject(L"base64_l_joy_body"))); + break; + case 2: + MyImage = (cli::safe_cast(resources->GetObject(L"base64_r_joy_body"))); + break; + case 3: + MyImage = (cli::safe_cast(resources->GetObject(L"base64_pro_body"))); + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_grips_l"))); + MyImageLayer2 = (cli::safe_cast(resources->GetObject(L"base64_pro_grips_r"))); + break; + default: + MyImage = (cli::safe_cast(resources->GetObject(L"base64_pro_body"))); + break; } // Skip slow SetPixel(). Reduce latency pixel set latency from 842us -> 260ns. System::Drawing::Imaging::BitmapData^ bmd = MyImage->LockBits(System::Drawing::Rectangle(0, 0, MyImage->Width, MyImage->Height), System::Drawing::Imaging::ImageLockMode::ReadOnly, MyImage->PixelFormat); @@ -4350,19 +4412,19 @@ public ref class FormJoy : public System::Windows::Forms::Form // Apply buttons color switch (handle_ok) { - case 1: - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_l_joy_buttons"))); - break; - case 2: - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_r_joy_buttons"))); - break; - case 3: - MyImage = drawLayeredImage(MyImage, MyImageLayer); // Apply grips layer - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_buttons"))); - break; - default: - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_buttons"))); - break; + case 1: + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_l_joy_buttons"))); + break; + case 2: + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_r_joy_buttons"))); + break; + case 3: + MyImage = drawLayeredImage(MyImage, MyImageLayer); // Apply grips layer + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_buttons"))); + break; + default: + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_buttons"))); + break; } // Skip slow SetPixel(). Reduce latency pixel set latency from 842us -> 260ns. bmd = MyImageLayer->LockBits(System::Drawing::Rectangle(0, 0, MyImageLayer->Width, MyImageLayer->Height), System::Drawing::Imaging::ImageLockMode::ReadOnly, MyImageLayer->PixelFormat); @@ -4380,18 +4442,18 @@ public ref class FormJoy : public System::Windows::Forms::Form // Apply outlines switch (handle_ok) { - case 1: - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_l_joy_lines"))); - break; - case 2: - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_r_joy_lines"))); - break; - case 3: - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_lines"))); - break; - default: - MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_lines"))); - break; + case 1: + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_l_joy_lines"))); + break; + case 2: + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_r_joy_lines"))); + break; + case 3: + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_lines"))); + break; + default: + MyImageLayer = (cli::safe_cast(resources->GetObject(L"base64_pro_lines"))); + break; } MyImage = drawLayeredImage(MyImage, MyImageLayer); @@ -6129,6 +6191,20 @@ public ref class FormJoy : public System::Windows::Forms::Form ir_new_config.ir_res_reg = 0b01101001; // Sensor Binning [4 x 2] and Skipping [2 x 4] ir_max_frag_no = 0x03; } + + if (this->radioBtn_IRModeCapture->Checked) { + ir_new_config.ir_mode = 0x07; + } + else if (this->radioBtn_IRModePointing->Checked) { + ir_new_config.ir_mode = 0x04; + ir_image_width = 320; + ir_image_height = 240; + } + else if (this->radioBtn_IRModeClustering->Checked) { + ir_new_config.ir_mode = 0x06; + ir_image_width = 320; + ir_image_height = 240; + } else { return 8; } @@ -6192,35 +6268,35 @@ public ref class FormJoy : public System::Windows::Forms::Form // Get error switch (res) { - case 1: - error_msg = "1ID31"; - break; - case 2: - error_msg = "2MCUON"; - break; - case 3: - error_msg = "3MCUONBUSY"; - break; - case 4: - error_msg = "4MCUMODESET"; - break; - case 5: - error_msg = "5MCUSETBUSY"; - break; - case 6: - error_msg = "6IRMODESET"; - break; - case 7: - error_msg = "7IRSETBUSY"; - break; - case 8: - error_msg = "8IRCFG"; - break; - case 9: - error_msg = "9IRFCFG"; - break; - default: - break; + case 1: + error_msg = "1ID31"; + break; + case 2: + error_msg = "2MCUON"; + break; + case 3: + error_msg = "3MCUONBUSY"; + break; + case 4: + error_msg = "4MCUMODESET"; + break; + case 5: + error_msg = "5MCUSETBUSY"; + break; + case 6: + error_msg = "6IRMODESET"; + break; + case 7: + error_msg = "7IRSETBUSY"; + break; + case 8: + error_msg = "8IRCFG"; + break; + case 9: + error_msg = "9IRFCFG"; + break; + default: + break; } if (res > 0) this->lbl_IRStatus->Text = "Status: Error " + error_msg + "!"; @@ -6289,9 +6365,9 @@ public ref class FormJoy : public System::Windows::Forms::Form graphicsHandle->InterpolationMode = System::Drawing::Drawing2D::InterpolationMode::HighQualityBicubic; graphicsHandle->DrawImage(rotatedImage, 0, 0, 240, 320); + this->pictureBoxIR->ClientSize = System::Drawing::Size(240*1.5, 320*1.5); this->pictureBoxIR->Image = resizedImage; - this->pictureBoxIR->ClientSize = System::Drawing::Size(240, 320); - this->AutoScaleDimensions = System::Drawing::SizeF(96, 96); + //this->AutoScaleDimensions = System::Drawing::SizeF(96, 96); } private: System::Void btn_getImage_Click(System::Object^ sender, System::EventArgs^ e) { @@ -6369,32 +6445,30 @@ public ref class FormJoy : public System::Windows::Forms::Form // Get error switch (res) { - case 1: - error_msg = "1ID31"; - break; - case 2: - error_msg = "2MCUON"; - break; - case 3: - error_msg = "3MCUONBUSY"; - break; - case 4: - error_msg = "4MCUMODESET"; - break; - case 5: - error_msg = "5MCUSETBUSY"; - break; - case 6: - error_msg = "6NFCPOLL"; - break; - default: - break; + case 1: + error_msg = "1ID31"; + break; + case 2: + error_msg = "2MCUON"; + break; + case 3: + error_msg = "3MCUONBUSY"; + break; + case 4: + error_msg = "4MCUMODESET"; + break; + case 5: + error_msg = "5MCUSETBUSY"; + break; + case 6: + error_msg = "6NFCPOLL"; + break; + default: + break; } if (res > 0) this->txtBox_nfcUid->Text = "Error " + error_msg + "!"; } - this->btn_NFC->Text = "Scan"; - enable_NFCScanning = false; } @@ -6647,53 +6721,6 @@ public ref class FormJoy : public System::Windows::Forms::Form else return false; } - - - public: System::Void show_ntag_contents(u8* ntag_buf, u8 ntag_pages) { - String^ ntag_temp_string = ""; - for (int i = 0; i < ntag_pages; i++) { - ntag_temp_string += String::Format("{0:X2}: ", i); - for (int j = 0; j < 4; j++) - ntag_temp_string += String::Format("{0:X2} ", ntag_buf[i * 4 + j]); - ntag_temp_string += "|"; - for (int j = 0; j < 4; j++) { - if (ntag_buf[i * 4 + j] < 0x20 || ntag_buf[i * 4 + j] > 0x7e) - ntag_temp_string += "."; - else - ntag_temp_string += String::Format("{0:S}", Convert::ToChar(ntag_buf[i * 4 + j])); - } - ntag_temp_string += "|"; - if (i != (ntag_pages - 1)) - ntag_temp_string += "\r\n"; - if (i == 4) { - switch (ntag_pages) { - case 45: - this->txtBox_nfcUid->Text += "213 "; - break; - case 135: - this->txtBox_nfcUid->Text += "215 "; - break; - case 231: - this->txtBox_nfcUid->Text += "216 "; - break; - default: - this->txtBox_nfcUid->Text += "???"; - break; - } - switch (ntag_buf[16]) { - case 0xA5: - this->txtBox_nfcUid->Text += "(Amiibo)"; - break; - case 0x01: - this->txtBox_nfcUid->Text += "(NDEF)"; - break; - default: - break; - } - } - } - this->txtBox_NFCTag->Text = ntag_temp_string; - } }; } diff --git a/jctool/jctool.cpp b/jctool/jctool.cpp index 57a2dd8..d83f418 100644 --- a/jctool/jctool.cpp +++ b/jctool/jctool.cpp @@ -760,6 +760,7 @@ int send_custom_command(u8* arg) { return 0; } +int get_raw_ir_image(u8 mode, u8 show_status); int button_test() { int res; @@ -1391,8 +1392,42 @@ int ir_sensor_auto_exposure(int white_pixels_percent) { return res; } +void hline(u8* buffer, u16 x0, u16 x1, u16 y, u8 brightness) { + u8* line = buffer + y * 320; + for (u16 x = x0; x <= x1; x++) + line[x] = brightness; +} + +void vline(u8* buffer, u16 x, u16 y0, u16 y1, u8 brightness) { + u8* line = buffer + x; + for (u16 y = y0; y <= y1; y++) + line[y*320] = brightness; +} -int get_raw_ir_image(u8 show_status) { +void drawCluster(u8* buffer, u16* data) { + u8 brightness = data[1]; + u16 x0 = data[4]; + u16 x1 = data[5]; + u16 y0 = data[6]; + u16 y1 = data[7]; + u16 cx = (data[2] + 32) / 64; + u16 cy = (data[3] + 32) / 64; + if (x1 < x0 || y1 < y0 || x1 >= 320 || y1 >= 240 || cx < x0 || cx > x1 || cy < y0 || cy > y1) { + printf("err: "); + for (int i = 0; i < 16; i++) + printf("%02x", ((u8*)data)[i]); + printf("\n"); + return; + } + hline(buffer, x0, x1, y0, brightness); + hline(buffer, x0, x1, y1, brightness); + hline(buffer, x0, x1, cy, brightness); + vline(buffer, x0, y0, y1, brightness); + vline(buffer, x1, y0, y1, brightness); + vline(buffer, cx, y0, y1, brightness); +} + +int get_raw_ir_image(u8 mode, u8 show_status) { std::stringstream ir_status; int elapsed_time = 0; @@ -1438,10 +1473,9 @@ int get_raw_ir_image(u8 show_status) { hid_read_timeout(handle, buf_reply, sizeof(buf_reply), 200); //Check if new packet - if (buf_reply[0] == 0x31 && buf_reply[49] == 0x03) { + if (buf_reply[0] == 0x31 && buf_reply[49] == 0x03 && buf_reply[51] == mode) { got_frag_no = buf_reply[52]; - if (got_frag_no == (previous_frag_no + 1) % (ir_max_frag_no + 1)) { - + if (got_frag_no == (previous_frag_no + 1) % (ir_max_frag_no + 1) || mode != 0x07) { previous_frag_no = got_frag_no; // ACK for fragment @@ -1451,38 +1485,60 @@ int get_raw_ir_image(u8 show_status) { buf[47] = mcu_crc8_calc(buf + 11, 36); hid_write(handle, buf, sizeof(buf)); - memcpy(buf_image + (300 * got_frag_no), buf_reply + 59, 300); - - // Auto exposure. - // TODO: Fix placement, so it doesn't drop next fragment. - if (enable_IRAutoExposure && initialization < 2 && got_frag_no == 0){ - white_pixels_percent = (int)((*(u16*)&buf_reply[55] * 100) / max_pixels); - ir_sensor_auto_exposure(white_pixels_percent); + if (mode == 0x06) { + memset(buf_image, 0, 320 * 240); + for (int i = 61; i + 16 <= 59+300; i += 16) { + if (buf_reply[i] != 0 || buf_reply[i + 1] != 0) { + drawCluster(buf_image, (u16*)(buf_reply + i)); + } + } + } + else if (mode == 0x04) + { + // weird data arrangement! + memset(buf_image, 0, 320 * 240); + for (int i = 61; i + 16 <= 59+300; i += 16) { + if (i == 61 + 48 || i == 61 + 97 || i == 61 + 146 || i == 61 + 195 || i == 61 + 244) + i++; + if (buf_reply[i] != 0 || buf_reply[i + 1] != 0) { + drawCluster(buf_image, (u16*)(buf_reply + i)); + } + } } + else if (mode == 0x07) { + memcpy(buf_image + (300 * got_frag_no), buf_reply + 59, 300); - // Status percentage - ir_status.str(""); - ir_status.clear(); - if (initialization < 2) { - if (show_status == 2) - ir_status << "Status: Streaming.. "; + // Auto exposure. + // TODO: Fix placement, so it doesn't drop next fragment. + if (enable_IRAutoExposure && initialization < 2 && got_frag_no == 0) { + white_pixels_percent = (int)((*(u16*)&buf_reply[55] * 100) / max_pixels); + ir_sensor_auto_exposure(white_pixels_percent); + } + + // Status percentage + ir_status.str(""); + ir_status.clear(); + if (initialization < 2) { + if (show_status == 2) + ir_status << "Status: Streaming.. "; + else + ir_status << "Status: Receiving.. "; + } else - ir_status << "Status: Receiving.. "; - } - else - ir_status << "Status: Initializing.. "; - ir_status << std::setfill(' ') << std::setw(3); - ir_status << std::fixed << std::setprecision(0) << (float)got_frag_no / (float)(ir_max_frag_no + 1) * 100.0f; - ir_status << "% - "; + ir_status << "Status: Initializing.. "; + ir_status << std::setfill(' ') << std::setw(3); + ir_status << std::fixed << std::setprecision(0) << (float)got_frag_no / (float)(ir_max_frag_no + 1) * 100.0f; + ir_status << "% - "; - //debug - // printf("%02X Frag: Copy\n", got_frag_no); + //debug + // printf("%02X Frag: Copy\n", got_frag_no); - FormJoy::myform1->lbl_IRStatus->Text = gcnew String(ir_status.str().c_str()) + (sw->ElapsedMilliseconds - elapsed_time).ToString() + "ms"; - elapsed_time = sw->ElapsedMilliseconds; + FormJoy::myform1->lbl_IRStatus->Text = gcnew String(ir_status.str().c_str()) + (sw->ElapsedMilliseconds - elapsed_time).ToString() + "ms"; + elapsed_time = sw->ElapsedMilliseconds; + } // Check if final fragment. Draw the frame. - if (got_frag_no == ir_max_frag_no) { + if (got_frag_no == ir_max_frag_no || mode != 0x07) { // Update Viewport elapsed_time2 = sw->ElapsedMilliseconds - elapsed_time2; FormJoy::myform1->setIRPictureWindow(buf_image, true); @@ -1852,7 +1908,7 @@ int ir_sensor(ir_image_config &ir_cfg) { pkt->subcmd = 0x21; pkt->subcmd_21_23_01.mcu_cmd = 0x23; pkt->subcmd_21_23_01.mcu_subcmd = 0x01; // Set IR mode cmd - pkt->subcmd_21_23_01.mcu_ir_mode = 0x07; // IR mode - 2: No mode/Disable?, 3: Moment, 4: Dpd (Wii-style pointing), 6: Clustering, + pkt->subcmd_21_23_01.mcu_ir_mode = ir_cfg.ir_mode; // IR mode - 2: No mode/Disable?, 3: Moment, 4: Dpd (Wii-style pointing), 6: Clustering, // 7: Image transfer, 8-10: Hand analysis (Silhouette, Image, Silhouette/Image), 0,1/5/10+: Unknown pkt->subcmd_21_23_01.no_of_frags = ir_max_frag_no; // Set number of packets to output per buffer pkt->subcmd_21_23_01.mcu_major_v = 0x0500; // Set required IR MCU FW v5.18. Major 0x0005. @@ -1863,6 +1919,7 @@ int ir_sensor(ir_image_config &ir_cfg) { int retries = 0; while (1) { res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (buf[0] == 0x21) { // Mode set Ack if (buf[15] == 0x0b) @@ -1901,7 +1958,8 @@ int ir_sensor(ir_image_config &ir_cfg) { res = hid_read_timeout(handle, buf, sizeof(buf), 64); if (buf[0] == 0x31) { // mode set to 7: Image transfer - if (buf[49] == 0x13 && *(u16*)&buf[50] == 0x0700) + + if (buf[49] == 0x13 && buf[50] == 0 && buf[51] == ir_cfg.ir_mode) goto step7; } retries++; @@ -1969,7 +2027,7 @@ int ir_sensor(ir_image_config &ir_cfg) { res = hid_read_timeout(handle, buf, sizeof(buf), 64); if (buf[0] == 0x21) { // Registers for mode 7: Image transfer set - if (buf[15] == 0x13 && *(u16*)&buf[16] == 0x0700) + if (buf[15] == 0x13 && buf[16] == 0 && buf[17] == (ir_cfg.ir_mode == 0x04 ? 0x02 : ir_cfg.ir_mode)) goto step8; } retries++; @@ -2027,7 +2085,7 @@ int ir_sensor(ir_image_config &ir_cfg) { res = hid_read_timeout(handle, buf, sizeof(buf), 64); if (buf[0] == 0x21) { // Registers for mode 7: Image transfer set - if (buf[15] == 0x13 && *(u16*)&buf[16] == 0x0700) + if (buf[15] == 0x13 && buf[50] == 0 && buf[51] == ir_cfg.ir_mode) goto step9; // If the Joy-Con gets to reply to the previous x11 - x03 02 cmd before sending the above, // it will reply with the following if we do not send x11 - x03 02 again: @@ -2048,9 +2106,9 @@ int ir_sensor(ir_image_config &ir_cfg) { step9: // Stream or Capture images from NIR Camera if (enable_IRVideoPhoto) - res_get = get_raw_ir_image(2); + res_get = get_raw_ir_image(ir_cfg.ir_mode, 2); else - res_get = get_raw_ir_image(1); + res_get = get_raw_ir_image(ir_cfg.ir_mode, 1); ////// // TODO: Should we send subcmd x21 with 'x230102' to disable IR mode before disabling MCU? @@ -2243,515 +2301,371 @@ int nfc_tag_info() { // Kudos to Eric Betts (https://github.com/bettse) // // for nfc comm starters // ///////////////////////////////////////////////////// - int res; - u8 buf[0x170]; - u8 buf2[0x170]; - static int output_buffer_length = 49; - int error_reading = 0; - int res_get = 0; - u8 tag_uid_buf[10]; - u8 tag_uid_size = 0; - u8 ntag_buffer[924]; - u16 ntag_buffer_pos = 0; - u8 ntag_pages = 0; // Max 231 - u8 tag_type = 0; - u16 payload_size = 0; - bool ntag_init_done = false; - - memset(tag_uid_buf, 0, sizeof(tag_uid_buf)); - memset(ntag_buffer, 0, sizeof(ntag_buffer)); - - // Set input report to x31 - while (1) { - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 1; - hdr->timer = timming_byte & 0xF; - timming_byte++; - pkt->subcmd = 0x03; - pkt->subcmd_arg.arg1 = 0x31; - res = hid_write(handle, buf, output_buffer_length); - int retries = 0; + while (enable_NFCScanning) { + int res; + u8 buf[0x170]; + u8 buf2[0x170]; + static int output_buffer_length = 49; + int error_reading = 0; + int res_get = 0; + // Set input report to x31 while (1) { - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (*(u16*)&buf[0xD] == 0x0380) - goto step1; + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 1; + hdr->timer = timming_byte & 0xF; + timming_byte++; + pkt->subcmd = 0x03; + pkt->subcmd_arg.arg1 = 0x31; + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (*(u16*)&buf[0xD] == 0x0380) + goto step1; - retries++; - if (retries > 8 || res == 0) - break; - } - error_reading++; - if (error_reading > 7) { - res_get = 1; - goto step9; + retries++; + if (retries > 8 || res == 0) + break; + } + error_reading++; + if (error_reading > 7) { + res_get = 1; + goto step9; + } } - } -step1: - // Enable MCU - error_reading = 0; - while (1) { - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 1; - hdr->timer = timming_byte & 0xF; - timming_byte++; - pkt->subcmd = 0x22; - pkt->subcmd_arg.arg1 = 0x1; - res = hid_write(handle, buf, output_buffer_length); - int retries = 0; + step1: + // Enable MCU + error_reading = 0; while (1) { - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (*(u16*)&buf[0xD] == 0x2280) - goto step2; - - retries++; - if (retries > 8 || res == 0) - break; - } - error_reading++; - if (error_reading > 7) { - res_get = 2; - goto step9; - } - } + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 1; + hdr->timer = timming_byte & 0xF; + timming_byte++; + pkt->subcmd = 0x22; + pkt->subcmd_arg.arg1 = 0x1; + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (*(u16*)&buf[0xD] == 0x2280) + goto step2; -step2: - // Request MCU mode status - error_reading = 0; - while (1) { - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 0x11; - hdr->timer = timming_byte & 0xF; - timming_byte++; - pkt->subcmd = 0x01; - res = hid_write(handle, buf, output_buffer_length); - int retries = 0; - while (1) { - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (buf[0] == 0x31) { - //if (buf[49] == 0x01 && buf[56] == 0x06) // MCU state is Initializing - // *(u16*)buf[52]LE x04 in lower than 3.89fw, x05 in 3.89 - // *(u16*)buf[54]LE x12 in lower than 3.89fw, x18 in 3.89 - // buf[56]: mcu mode state - if (buf[49] == 0x01 && buf[56] == 0x01) // Mcu mode is Standby - goto step3; + retries++; + if (retries > 8 || res == 0) + break; + } + error_reading++; + if (error_reading > 7) { + res_get = 2; + goto step9; } - retries++; - if (retries > 8 || res == 0) - break; - } - error_reading++; - if (error_reading > 7) { - res_get = 3; - goto step9; } - } -step3: - // Set MCU mode - error_reading = 0; - while (1) { - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 0x01; - hdr->timer = timming_byte & 0xF; - timming_byte++; - pkt->subcmd = 0x21; - - pkt->subcmd_21_21.mcu_cmd = 0x21; // Set MCU mode cmd - pkt->subcmd_21_21.mcu_subcmd = 0x00; // Set MCU mode cmd - pkt->subcmd_21_21.mcu_mode = 0x04; // MCU mode - 1: Standby, 4: NFC, 5: IR, 6: Initializing/FW Update? - - buf[48] = mcu_crc8_calc(buf + 12, 36); - res = hid_write(handle, buf, output_buffer_length); - int retries = 0; + step2: + // Request MCU mode status + error_reading = 0; while (1) { - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (buf[0] == 0x21) { - // *(u16*)buf[18]LE x04 in lower than 3.89fw, x05 in 3.89 - // *(u16*)buf[20]LE x12 in lower than 3.89fw, x18 in 3.89 - if (buf[15] == 0x01 && buf[22] == 0x01) // Mcu mode is standby - goto step4; + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 0x11; + hdr->timer = timming_byte & 0xF; + timming_byte++; + pkt->subcmd = 0x01; + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (buf[0] == 0x31) { + //if (buf[49] == 0x01 && buf[56] == 0x06) // MCU state is Initializing + // *(u16*)buf[52]LE x04 in lower than 3.89fw, x05 in 3.89 + // *(u16*)buf[54]LE x12 in lower than 3.89fw, x18 in 3.89 + // buf[56]: mcu mode state + if (buf[49] == 0x01 && buf[56] == 0x01) // Mcu mode is Standby + goto step3; + } + retries++; + if (retries > 8 || res == 0) + break; + } + error_reading++; + if (error_reading > 7) { + res_get = 3; + goto step9; } - retries++; - if (retries > 8 || res == 0) - break; - } - error_reading++; - if (error_reading > 7) { - res_get = 4; - goto step9; } - } -step4: - // Request MCU mode status - error_reading = 0; - while (1) { - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 0x11; - hdr->timer = timming_byte & 0xF; - timming_byte++; - pkt->subcmd = 0x01; - res = hid_write(handle, buf, output_buffer_length); - int retries = 0; + step3: + // Set MCU mode + error_reading = 0; while (1) { - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (buf[0] == 0x31) { - // *(u16*)buf[52]LE x04 in lower than 3.89fw, x05 in 3.89 - // *(u16*)buf[54]LE x12 in lower than 3.89fw, x18 in 3.89 - if (buf[49] == 0x01 && buf[56] == 0x04) // Mcu mode is NFC - goto step5; - } - retries++; - if (retries > 8 || res == 0) - break; - } - error_reading++; - if (error_reading > 7) { - res_get = 5; - goto step9; - } - } + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 0x01; + hdr->timer = timming_byte & 0xF; + timming_byte++; + pkt->subcmd = 0x21; -step5: - // Request NFC mode status - error_reading = 0; - while (1) { - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 0x11; - hdr->timer = timming_byte & 0xF; - timming_byte++; + pkt->subcmd_21_21.mcu_cmd = 0x21; // Set MCU mode cmd + pkt->subcmd_21_21.mcu_subcmd = 0x00; // Set MCU mode cmd + pkt->subcmd_21_21.mcu_mode = 0x04; // MCU mode - 1: Standby, 4: NFC, 5: IR, 6: Initializing/FW Update? - pkt->subcmd = 0x02; - pkt->subcmd_arg.arg1 = 0x04; // 0: Cancel all, 4: StartWaitingReceive - pkt->subcmd_arg.arg2 = 0x00; // Count of the currecnt packet if the cmd is a series of packets. - buf[13] = 0x00; - buf[14] = 0x08; // 8: Last cmd packet, 0: More cmd packet should be expected - buf[15] = 0x00; // Length of data after cmd header - - buf[47] = mcu_crc8_calc(buf + 11, 36); //Without the last byte - res = hid_write(handle, buf, output_buffer_length - 1); - int retries = 0; - while (1) { - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (buf[0] == 0x31) { - if (buf[49] == 0x2a && *(u16*)&buf[50] == 0x0500 && buf[55] == 0x31 && buf[56] == 0x0b)// buf[56] == 0x0b: Initializing/Busy + buf[48] = mcu_crc8_calc(buf + 12, 36); + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (buf[0] == 0x21) { + // *(u16*)buf[18]LE x04 in lower than 3.89fw, x05 in 3.89 + // *(u16*)buf[20]LE x12 in lower than 3.89fw, x18 in 3.89 + if (buf[15] == 0x01 && buf[22] == 0x01) // Mcu mode is standby + goto step4; + } + retries++; + if (retries > 8 || res == 0) break; - if (buf[49] == 0x2a && *(u16*)&buf[50] == 0x0500 && buf[55] == 0x31 && buf[56] == 0x00) // buf[56] == 0x00: Awaiting cmd - goto step6; } - retries++; - if (retries > 4 || res == 0) - break; - } - error_reading++; - if (error_reading > 9) { - res_get = 6; - goto step9; + error_reading++; + if (error_reading > 7) { + res_get = 4; + goto step9; + } } - } -step6: - // Request NFC mode status - error_reading = 0; - while (1) { - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 0x11; - hdr->timer = timming_byte & 0xF; - timming_byte++; - - pkt->subcmd = 0x02; - pkt->subcmd_arg.arg1 = 0x01; // 1: Start polling, 2: Stop polling, - pkt->subcmd_arg.arg2 = 0x00; // Count of the currecnt packet if the cmd is a series of packets. - buf[13] = 0x00; - buf[14] = 0x08; // 8: Last cmd packet, 0: More cmd packet should be expected - buf[15] = 0x05; // Length of data after cmd header - buf[16] = 0x01; // 1: Enable Mifare support - buf[17] = 0x00; // Unknown. - buf[18] = 0x00; // Unknown. - buf[19] = 0x2c; // Unknown. Some values work (0x07) other don't. - buf[20] = 0x01; // Unknown. This is not needed but Switch sends it. - - buf[47] = mcu_crc8_calc(buf + 11, 36); //Without the last byte - res = hid_write(handle, buf, output_buffer_length - 1); - int retries = 0; + step4: + // Request MCU mode status + error_reading = 0; while (1) { - if (!enable_NFCScanning) - goto step7; - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (buf[0] == 0x31) { - // buf[49] == 0x2a: NFC MCU input report - // buf[50] shows when there's error? - // buf[51] == 0x05: NFC - // buf[54] always 9? - // buf[55] always x31? - // buf[56]: MCU/NFC state - // buf[62]: nfc tag IC - // buf[63]: nfc tag Type - // buf[64]: size of following data and it's the last NFC header byte - if (buf[49] == 0x2a && *(u16*)&buf[50] == 0x0500 && buf[56] == 0x09) { // buf[56] == 0x09: Tag detected - tag_uid_size = buf[64]; - FormJoy::myform1->txtBox_nfcUid->Text = "UID: "; - for (int i = 0; i < tag_uid_size; i++) { - if (i < tag_uid_size - 1) { - tag_type = buf[62]; // Save tag type - tag_uid_buf[i] = buf[65 + i]; // Save UID - FormJoy::myform1->txtBox_nfcUid->Text += String::Format("{0:X2}:", buf[65 + i]); - } - else { - FormJoy::myform1->txtBox_nfcUid->Text += String::Format("{0:X2}", buf[65 + i]); - } - } - FormJoy::myform1->txtBox_nfcUid->Text += String::Format("\r\nType: {0:s}", buf[62] == 0x2 ? "NTAG" : "MIFARE"); - Application::DoEvents(); - goto step7; + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 0x11; + hdr->timer = timming_byte & 0xF; + timming_byte++; + pkt->subcmd = 0x01; + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (buf[0] == 0x31) { + // *(u16*)buf[52]LE x04 in lower than 3.89fw, x05 in 3.89 + // *(u16*)buf[54]LE x12 in lower than 3.89fw, x18 in 3.89 + if (buf[49] == 0x01 && buf[56] == 0x04) // Mcu mode is NFC + goto step5; } - else if (buf[49] == 0x2a) + retries++; + if (retries > 8 || res == 0) break; } - retries++; - if (retries > 4 || res == 0) { - Application::DoEvents(); - break; + error_reading++; + if (error_reading > 7) { + res_get = 5; + goto step9; } } - error_reading++; - if (error_reading > 100) { - res_get = 7; - if (ntag_init_done) - FormJoy::myform1->txtBox_NFCTag->Text = String::Format("Tag lost!"); - else - FormJoy::myform1->txtBox_NFCTag->Text = String::Format("No Tag detected!"); - goto step9; - } - } - -step7: - // Read NTAG contents - error_reading = 0; - while (1) { - memset(buf2, 0, sizeof(buf2)); - auto hdr = (brcm_hdr *)buf2; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 0x11; - hdr->timer = timming_byte & 0xF; - timming_byte++; - pkt->subcmd = 0x02; - pkt->subcmd_arg.arg1 = 0x06; // 6: Read Ntag data, 0xf: Read mifare data - buf2[12] = 0x00; - buf2[13] = 0x00; - buf2[14] = 0x08; - buf2[15] = 0x13; // Length of data after cmd header - - buf2[16] = 0xd0; // Unknown - buf2[17] = 0x07; // Unknown or UID lentgh? - buf2[18] = 0x00; // Only for Mifare cmds or should have a UID? - - buf2[19] = 0x00; //should have a UID? - buf2[20] = 0x00; //should have a UID? - buf2[21] = 0x00; //should have a UID? - buf2[22] = 0x00; //should have a UID? - buf2[23] = 0x00; //should have a UID? - buf2[24] = 0x00; //should have a UID? - - buf2[25] = 0x00; // 1: Ntag215 only. 0: All tags, otherwise error x48 (Invalid format error) - - // https://www.tagnfc.com/en/info/11-nfc-tags-specs - - // If the following is selected wrongly, error x3e (Read error) - switch (ntag_pages) { - case 0: - buf2[26] = 0x01; - break; - // Ntag213 - case 45: - // The following 7 bytes should be decided with max the current ntag pages and what we want to read. - buf2[26] = 0x01; // How many blocks to read. Each block should be <= 60 pages (240 bytes)? Min/Max values are 1/4, otherwise error x40 (Argument error) - - buf2[27] = 0x00; // Block 1 starting page - buf2[28] = 0x2C; // Block 1 ending page - buf2[29] = 0x00; // Block 2 starting page - buf2[30] = 0x00; // Block 2 ending page - buf2[31] = 0x00; // Block 3 starting page - buf2[32] = 0x00; // Block 3 ending page - buf2[33] = 0x00; // Block 4 starting page - buf2[34] = 0x00; // Block 4 ending page - break; - // Ntag215 - case 135: - // The following 7 bytes should be decided with max the current ntag pages and what we want to read. - buf2[26] = 0x03; // How many page ranges to read. Each range should be <= 60 pages (240 bytes)? Max value is 4. - - buf2[27] = 0x00; // Block 1 starting page - buf2[28] = 0x3b; // Block 1 ending page - buf2[29] = 0x3c; // Block 2 starting page - buf2[30] = 0x77; // Block 2 ending page - buf2[31] = 0x78; // Block 3 starting page - buf2[32] = 0x86; // Block 3 ending page - buf2[33] = 0x00; // Block 4 starting page - buf2[34] = 0x00; // Block 4 ending page - break; - case 231: - // The following 7 bytes should be decided with max the current ntag pages and what we want to read. - buf2[26] = 0x04; // How many page ranges to read. Each range should be <= 60 pages (240 bytes)? Max value is 4. - - buf2[27] = 0x00; // Block 1 starting page - buf2[28] = 0x3b; // Block 1 ending page - buf2[29] = 0x3c; // Block 2 starting page - buf2[30] = 0x77; // Block 2 ending page - buf2[31] = 0x78; // Block 3 starting page - buf2[32] = 0xB3; // Block 3 ending page - buf2[33] = 0xB4; // Block 4 starting page - buf2[34] = 0xE6; // Block 4 ending page - break; - default: - break; - } + step5: + // Request NFC mode status + error_reading = 0; + while (1) { + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 0x11; + hdr->timer = timming_byte & 0xF; + timming_byte++; - buf2[47] = mcu_crc8_calc(buf2 + 11, 36); + pkt->subcmd = 0x02; + pkt->subcmd_arg.arg1 = 0x04; // 0: Cancel all, 4: StartWaitingReceive + pkt->subcmd_arg.arg2 = 0x00; // Count of the currecnt packet if the cmd is a series of packets. + buf[13] = 0x00; + buf[14] = 0x08; // 8: Last cmd packet, 0: More cmd packet should be expected + buf[15] = 0x00; // Length of data after cmd header - res = hid_write(handle, buf2, output_buffer_length - 1); + buf[47] = mcu_crc8_calc(buf + 11, 36); //Without the last byte + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (buf[0] == 0x31) { + //if (buf[49] == 0x2a && *(u16*)&buf[50] == 0x0500 && buf[55] == 0x31 && buf[56] == 0x0b)// buf[56] == 0x0b: Initializing/Busy + if (buf[49] == 0x2a && *(u16*)&buf[50] == 0x0500 && buf[55] == 0x31 && buf[56] == 0x00) // buf[56] == 0x00: Awaiting cmd + goto step6; + } + retries++; + if (retries > 4 || res == 0) + break; + } + error_reading++; + if (error_reading > 9) { + res_get = 6; + goto step9; + } + } - int retries = 0; + step6: + // Request NFC mode status while (1) { - res = hid_read_timeout(handle, buf2, sizeof(buf2), 64); - if (buf2[0] == 0x31) { - if ((buf2[49] == 0x3a || buf2[49] == 0x2a) && buf2[56] == 0x07) { - FormJoy::myform1->txtBox_NFCTag->Text = String::Format("Error {0:X2}!", buf2[50]); - goto step9;/////////// - } - else if (buf2[49] == 0x3a && buf2[51] == 0x07) { - if (ntag_init_done) { - payload_size = (buf2[54] << 8 | buf2[55]) & 0x7FF; - if (buf2[52] == 0x01) { - memcpy(ntag_buffer + ntag_buffer_pos, buf2 + 116, payload_size - 60); - ntag_buffer_pos += payload_size - 60; - } - else { - memcpy(ntag_buffer + ntag_buffer_pos, buf2 + 56, payload_size); - } - } - else if (buf2[52] == 0x01) { - if (tag_type == 2) { - switch (buf2[74]) { - case 0: - ntag_pages = 135; - break; - case 3: - ntag_pages = 45; - break; - case 4: - ntag_pages = 231; - break; - default: - goto step9;/////////// - break; + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 0x11; + hdr->timer = timming_byte & 0xF; + timming_byte++; + + pkt->subcmd = 0x02; + pkt->subcmd_arg.arg1 = 0x01; // 1: Start polling, 2: Stop polling, + pkt->subcmd_arg.arg2 = 0x00; // Count of the currecnt packet if the cmd is a series of packets. + buf[13] = 0x00; + buf[14] = 0x08; // 8: Last cmd packet, 0: More cmd packet should be expected + buf[15] = 0x05; // Length of data after cmd header + buf[16] = 0x01; // Enable Mifare support + //buf[17] = 0x00; + //buf[18] = 0x00; + buf[19] = 0x2c; // Some values work (0x07) other don't. + //buf[20] = 0x01; + + buf[47] = mcu_crc8_calc(buf + 11, 36); //Without the last byte + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + if (!enable_NFCScanning) + goto step7; + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (buf[0] == 0x31) { + // buf[49] == 0x2a: NFC MCU input report + // buf[50] shows when there's error? + // buf[51] == 0x05: NFC + // buf[54] always 9? + // buf[55] always x31? + // buf[56]: MCU/NFC state + // buf[62]: nfc tag type + // buf[62]: MSB size? + // buf[64]: size of following data and it's the last NFC header byte + if (buf[49] == 0x2a && *(u16*)&buf[50] == 0x0500 && buf[56] == 0x09) { // buf[56] == 0x09: Tag detected + //for (int i = 0; i < 8; i++) { + // printf("%02X ", buf[57 + i]); + //} + //printf(" | "); + //FormJoy::myform1->txtBox_nfcUid->Text = String::Format("{0:d},{1:d},{2:d},{3:d},{4:d}, Type: {5:d}, {6:d}\r\nUID: ", buf[57], buf[58], buf[59], buf[60], buf[61], buf[62], buf[63]); + FormJoy::myform1->txtBox_nfcUid->Text = String::Format("Type: {0:s}\r\nUID: ", buf[62] == 0x2 ? "NTAG" : "MIFARE"); + for (int i = 0; i < buf[64]; i++) { + if (i < buf[64] - 1) { + //printf("%02X:", buf[65 + i]); + FormJoy::myform1->txtBox_nfcUid->Text += String::Format("{0:X2}:", buf[65 + i]); + } + else { + //printf("%02X", buf[65 + i]); + FormJoy::myform1->txtBox_nfcUid->Text += String::Format("{0:X2}", buf[65 + i]); } } + //printf("\n"); + Application::DoEvents(); + goto step7; } + } + retries++; + if (retries > 4 || res == 0) { + Application::DoEvents(); break; } - else if (buf2[49] == 0x2a && buf2[56] == 0x04) { // finished - if (ntag_init_done) { - FormJoy::myform1->show_ntag_contents(ntag_buffer, ntag_pages); - Application::DoEvents(); - goto step9;/////////// - } - ntag_init_done = true; - - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 0x11; - hdr->timer = timming_byte & 0xF; - timming_byte++; + } + } - pkt->subcmd = 0x02; - pkt->subcmd_arg.arg1 = 0x02; // 0: Cancel all, 4: StartWaitingReceive - pkt->subcmd_arg.arg2 = 0x00; // Count of the currecnt packet if the cmd is a series of packets. - buf[13] = 0x00; - buf[14] = 0x08; // 8: Last cmd packet, 0: More cmd packet should be expected - buf[15] = 0x00; // Length of data after cmd header + step7: + // Read NTAG contents + // TODO: + while (0) { + memset(buf2, 0, sizeof(buf2)); + auto hdr = (brcm_hdr *)buf2; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 0x11; + hdr->timer = timming_byte & 0xF; + timming_byte++; - buf[47] = mcu_crc8_calc(buf + 11, 36); //Without the last byte - res = hid_write(handle, buf, output_buffer_length - 1); - Sleep(200); - goto step5; + pkt->subcmd = 0x02; + pkt->subcmd_arg.arg1 = 0x06; // 6: Read Ntag data, 0xf: Read mifare data + pkt->subcmd_arg.arg2 = 0x00; + buf2[13] = 0x00; + buf2[14] = 0x08; + buf2[15] = 0x0D; // Length of data after cmd header + buf2[16] = 0xd0; + buf2[17] = 0x07; + for (int i = 0; i < 7; i++) + buf2[18 + i] = buf[65 + i]; + buf2[25] = 0x00; //val != 0 + buf2[26] = 0x01; //block count + buf2[27] = 0x05; //block + buf2[28] = 0x13; //? + + buf2[47] = mcu_crc8_calc(buf2 + 11, 36); + buf2[48] = 0xFF; + res = hid_write(handle, buf2, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf2, sizeof(buf2), 64); + if (buf2[0] == 0x31) { + // mode set to 7: Image transfer + if (buf2[49] == 0x2a && buf2[51] == 0x05 && buf[56] == 0x00) + goto step9;//////////////////////// } - else if (buf2[49] == 0x2a) + retries++; + if (retries > 4 || res == 0) break; } - retries++; - if (retries > 4 || res == 0) - break; - } - error_reading++; - if (error_reading > 9) { - res_get = 8; - if (buf[62] == 0x4) - FormJoy::myform1->txtBox_NFCTag->Text = String::Format("Mifare reading is not supported for now.."); - goto step9; } - } -step9: - // Disable MCU - memset(buf, 0, sizeof(buf)); - auto hdr = (brcm_hdr *)buf; - auto pkt = (brcm_cmd_01 *)(hdr + 1); - hdr->cmd = 1; - hdr->timer = timming_byte & 0xF; - timming_byte++; - pkt->subcmd = 0x22; - pkt->subcmd_arg.arg1 = 0x00; - res = hid_write(handle, buf, output_buffer_length); - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - - - // Set input report to x3f - while (1) { + step9: + // Disable MCU memset(buf, 0, sizeof(buf)); auto hdr = (brcm_hdr *)buf; auto pkt = (brcm_cmd_01 *)(hdr + 1); hdr->cmd = 1; hdr->timer = timming_byte & 0xF; timming_byte++; - pkt->subcmd = 0x03; - pkt->subcmd_arg.arg1 = 0x3f; + pkt->subcmd = 0x22; + pkt->subcmd_arg.arg1 = 0x00; res = hid_write(handle, buf, output_buffer_length); - int retries = 0; + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + + + // Set input report to x3f while (1) { - res = hid_read_timeout(handle, buf, sizeof(buf), 64); - if (*(u16*)&buf[0xD] == 0x0380) - goto stepf; + memset(buf, 0, sizeof(buf)); + auto hdr = (brcm_hdr *)buf; + auto pkt = (brcm_cmd_01 *)(hdr + 1); + hdr->cmd = 1; + hdr->timer = timming_byte & 0xF; + timming_byte++; + pkt->subcmd = 0x03; + pkt->subcmd_arg.arg1 = 0x3f; + res = hid_write(handle, buf, output_buffer_length); + int retries = 0; + while (1) { + res = hid_read_timeout(handle, buf, sizeof(buf), 64); + if (*(u16*)&buf[0xD] == 0x0380) + goto stepf; - retries++; - if (retries > 8 || res == 0) - break; - } - error_reading++; - if (error_reading > 7) { - goto stepf; + retries++; + if (retries > 8 || res == 0) + break; + } + error_reading++; + if (error_reading > 7) { + goto stepf; + } } + stepf: + if (res_get > 0) + return res_get; + Sleep(30); } -stepf: - if (res_get > 0) - return res_get; return 0; } @@ -2918,17 +2832,17 @@ int device_connection(){ // Joy-Con (L) if (handle = hid_open(0x57e, 0x2006, nullptr)) { handle_ok = 1; - return handle_ok; + return 1; } // Joy-Con (R) if (handle = hid_open(0x57e, 0x2007, nullptr)) { handle_ok = 2; - return handle_ok; + return 2; } // Pro Controller if (handle = hid_open(0x57e, 0x2009, nullptr)) { handle_ok = 3; - return handle_ok; + return 3; } // Nothing found else { @@ -2958,12 +2872,11 @@ int device_connection(){ [STAThread] int Main(array^ args) { - /* - BOOL chk = AllocConsole(); - if (chk) { - freopen("CONOUT$", "w", stdout); - } - */ + //BOOL chk = AllocConsole(); + //if (chk) { + // freopen("CONOUT$", "w", stdout); + //} + check_connection_ok = true; while (!device_connection()) { if (MessageBox::Show( diff --git a/jctool/jctool.h b/jctool/jctool.h index 3d14b7f..c61b8ea 100644 --- a/jctool/jctool.h +++ b/jctool/jctool.h @@ -93,6 +93,7 @@ struct ir_image_config { u8 ir_hand_analysis_threshold; u32 ir_denoise; // MSByte: Enable/Disable, Middle Byte: Edge smoothing, LSB: Color interpolation u8 ir_flip; + u8 ir_mode; }; #pragma pack(pop) @@ -115,6 +116,7 @@ extern int send_custom_command(u8* arg); extern int device_connection(); extern int set_led_busy(); extern int button_test(); +extern int get_raw_ir_image(u8 mode, u8 show_status); extern int ir_sensor(ir_image_config &ir_cfg); extern int ir_sensor_config_live(ir_image_config &ir_cfg); extern int nfc_tag_info();