2017-12-29 08:05:42 +00:00
|
|
|
#include <cstdio>
|
2017-01-07 04:57:28 +00:00
|
|
|
#include "jbus/Listener.hpp"
|
|
|
|
#include "jbus/Endpoint.hpp"
|
2017-01-07 08:24:16 +00:00
|
|
|
#include <functional>
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
static void clientPadComplimentCheck(jbus::u8* buffer) {
|
|
|
|
jbus::u8 check = 0x19;
|
|
|
|
for (int i = 0xa0; i < 0xbd; ++i)
|
|
|
|
check += buffer[i];
|
|
|
|
buffer[0xbd] = -check;
|
2017-01-07 04:57:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static jbus::EJoyReturn BootStatus = jbus::GBA_JOYBOOT_ERR_INVALID;
|
2018-12-08 05:20:55 +00:00
|
|
|
static void JoyBootDone(jbus::ThreadLocalEndpoint& endpoint, jbus::EJoyReturn status) { BootStatus = status; }
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
static bool DonePoll(jbus::Endpoint& endpoint) {
|
|
|
|
jbus::u8 status;
|
|
|
|
if (endpoint.GBAReset(&status) == jbus::GBA_NOT_READY)
|
2017-01-07 04:57:28 +00:00
|
|
|
if (endpoint.GBAReset(&status) == jbus::GBA_NOT_READY)
|
2018-12-08 05:20:55 +00:00
|
|
|
return false;
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
if (endpoint.GBAGetStatus(&status) == jbus::GBA_NOT_READY)
|
|
|
|
return false;
|
|
|
|
if (status != (jbus::GBA_JSTAT_PSF1 | jbus::GBA_JSTAT_SEND))
|
|
|
|
return false;
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
return true;
|
2017-01-07 04:57:28 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
int main(int argc, char** argv) {
|
|
|
|
if (argc < 2) {
|
|
|
|
printf("Usage: joyboot <client_pad.bin>\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
FILE* fp = fopen(argv[1], "rb");
|
|
|
|
if (!fp) {
|
|
|
|
fprintf(stderr, "Unable to open %s\n", argv[1]);
|
|
|
|
return 1;
|
|
|
|
}
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
fseek(fp, 0, SEEK_END);
|
|
|
|
int fsize = ftell(fp);
|
|
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
std::unique_ptr<jbus::u8[]> data(new jbus::u8[fsize]);
|
|
|
|
fread(data.get(), 1, fsize, fp);
|
|
|
|
fclose(fp);
|
|
|
|
if (fsize < 512) {
|
|
|
|
fprintf(stderr, "%s must be at least 512 bytes\n", argv[1]);
|
|
|
|
return 1;
|
|
|
|
}
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
clientPadComplimentCheck(data.get());
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
jbus::Initialize();
|
|
|
|
printf("Listening for client\n");
|
|
|
|
jbus::Listener listener;
|
|
|
|
listener.start();
|
|
|
|
std::unique_ptr<jbus::Endpoint> endpoint;
|
|
|
|
while (true) {
|
|
|
|
jbus::s64 frameStart = jbus::GetGCTicks();
|
|
|
|
endpoint = listener.accept();
|
|
|
|
if (endpoint)
|
|
|
|
break;
|
|
|
|
jbus::s64 frameEnd = jbus::GetGCTicks();
|
|
|
|
jbus::s64 passedTicks = frameEnd - frameStart;
|
|
|
|
jbus::s64 waitTicks = jbus::GetGCTicksPerSec() / 60 - passedTicks;
|
|
|
|
if (waitTicks > 0)
|
|
|
|
jbus::WaitGCTicks(waitTicks);
|
|
|
|
}
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
printf("Waiting 4 sec\n");
|
|
|
|
jbus::WaitGCTicks(jbus::GetGCTicksPerSec() * 4);
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
jbus::u8 status;
|
|
|
|
if (endpoint->GBAJoyBootAsync(2, 2, data.get(), fsize, &status,
|
|
|
|
std::bind(JoyBootDone, std::placeholders::_1, std::placeholders::_2)) !=
|
|
|
|
jbus::GBA_READY) {
|
|
|
|
fprintf(stderr, "Unable to start JoyBoot\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
jbus::s64 start = jbus::GetGCTicks();
|
|
|
|
jbus::u8 percent = 0;
|
|
|
|
jbus::u8 lastpercent = 0;
|
|
|
|
while (endpoint->GBAGetProcessStatus(percent) == jbus::GBA_BUSY) {
|
|
|
|
if (percent != lastpercent) {
|
|
|
|
lastpercent = percent;
|
|
|
|
printf("\rUpload %d%%", percent);
|
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
jbus::s64 curTime = jbus::GetGCTicks();
|
|
|
|
jbus::s64 passedTicks = curTime - start;
|
2019-06-12 02:03:39 +00:00
|
|
|
if (passedTicks > jbus::s64(jbus::GetGCTicksPerSec()) * 10) {
|
2018-12-08 05:20:55 +00:00
|
|
|
fprintf(stderr, "JoyBoot timeout\n");
|
|
|
|
return 1;
|
2017-01-07 04:57:28 +00:00
|
|
|
}
|
2018-12-08 05:20:55 +00:00
|
|
|
jbus::WaitGCTicks(jbus::GetGCTicksPerSec() / 60);
|
|
|
|
}
|
|
|
|
printf("\nJoy Boot finished with %d status\n", status);
|
2017-01-07 04:57:28 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
while (!DonePoll(*endpoint)) {
|
|
|
|
jbus::s64 curTime = jbus::GetGCTicks();
|
|
|
|
jbus::s64 passedTicks = curTime - start;
|
2019-06-12 02:03:39 +00:00
|
|
|
if (passedTicks > jbus::s64(jbus::GetGCTicksPerSec()) * 15) {
|
2018-12-08 05:20:55 +00:00
|
|
|
fprintf(stderr, "JoyBoot timeout\n");
|
|
|
|
return 1;
|
2017-01-07 04:57:28 +00:00
|
|
|
}
|
2018-12-08 05:20:55 +00:00
|
|
|
jbus::WaitGCTicks(jbus::GetGCTicksPerSec() / 60);
|
|
|
|
}
|
2017-01-07 03:13:23 +00:00
|
|
|
|
2018-12-08 05:20:55 +00:00
|
|
|
return 0;
|
2017-01-07 03:13:23 +00:00
|
|
|
}
|