Commit 4699542f authored by Jack Andersen's avatar Jack Andersen

Add Doxygen comments

parent a3fe0a3a
JBus Documentation {#mainpage}
==============================
JBus functions as a server for acceping connections from GBA emulator clients.
The jbus::Listener class may be constructed and [started](@ref jbus::Listener::start)
to enque incoming jbus::Endpoint instances.
Once an Endpoint has been [accepted](@ref jbus::Listener::accept), it's ready to use.
Refer to the jbus::Endpoint class for the main interface.
This source diff could not be displayed because it is too large. You can view the blob instead.
The MIT License
Copyright (c) 2016-2017 JBus Contributors
Original Authors: Jack Andersen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## JBus
This is a library for communicating with emulated GameBoy Advance instances
using the JoyBus protocol, linked over TCP.
using the JoyBus protocol linked over TCP.
Currently, only [VBA-M](https://github.com/visualboyadvance-m/visualboyadvance-m)
is known to function. It uses the same networking method as the
[Dolphin](https://github.com/dolphin-emu/dolphin) GameCube emulator.
### Documentation
[Doxygen docs are available!](http://axiodl.github.io/jbus)
### Example
[Refer to the `joyboot.cpp`](https://github.com/AxioDL/jbus/blob/master/tools/joyboot.cpp)
implementation for a good usage example.
......@@ -17,6 +17,8 @@ using u32 = uint32_t;
using s64 = int64_t;
using u64 = uint64_t;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#undef bswap16
#undef bswap32
#undef bswap64
......@@ -139,6 +141,8 @@ static inline double SBig(double val) {return val;}
class Endpoint;
class ThreadLocalEndpoint;
#endif
enum EJStatFlags
{
GBA_JSTAT_MASK = 0x3a,
......@@ -159,11 +163,24 @@ enum EJoyReturn
GBA_JOYBOOT_ERR_INVALID = 4
};
/** @brief Standard callback for asynchronous jbus::Endpoint APIs.
* @param endpoint Thread-local Endpoint interface for optionally issuing next command in sequence.
* @param status GBA_READY if connection is still open, GBA_NOT_READY if connection lost. */
using FGBACallback = std::function<void(ThreadLocalEndpoint& endpoint, EJoyReturn status)>;
/** @brief Get host system's timebase scaled into Dolphin ticks.
* @return Scaled ticks from host timebase. */
u64 GetGCTicks();
/** @brief Wait an approximate Dolphin tick duration (avoid using, it's rather inaccurate).
* @param ticks CPU ticks to wait. */
void WaitGCTicks(u64 ticks);
/** @brief Obtain CPU ticks per second of Dolphin hardware (clock speed).
* @return 486Mhz - always. */
static constexpr u64 GetGCTicksPerSec() { return 486000000ull; }
/** @brief Initialize platform specifics of JBus library */
void Initialize();
}
......
This diff is collapsed.
......@@ -10,6 +10,7 @@
namespace jbus
{
/** Server interface for accepting incoming connections from GBA emulator instances. */
class Listener
{
net::Socket m_dataServer = {false};
......@@ -25,9 +26,16 @@ class Listener
void listenerProc();
public:
/** @brief Start listener thread. */
void start();
/** @brief Request stop of listener thread and block until joined. */
void stop();
/** @brief Pop jbus::Endpoint off Listener's queue.
* @return Endpoint instance, ready to issue commands. */
std::unique_ptr<Endpoint> accept();
~Listener();
};
......
......@@ -5,11 +5,11 @@
namespace jbus
{
void KawasedoChallenge::F23(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_0Reset(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status != GBA_READY ||
(status = endpoint.GBAResetAsync(x10_statusPtr,
bindThis(&KawasedoChallenge::F25))) != GBA_READY)
bindThis(&KawasedoChallenge::_1GetStatus))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -20,7 +20,7 @@ void KawasedoChallenge::F23(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
void KawasedoChallenge::F25(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_1GetStatus(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status == GBA_READY)
if (*x10_statusPtr != GBA_JSTAT_SEND)
......@@ -28,7 +28,7 @@ void KawasedoChallenge::F25(ThreadLocalEndpoint& endpoint, EJoyReturn status)
if (status != GBA_READY ||
(status = endpoint.GBAGetStatusAsync(x10_statusPtr,
bindThis(&KawasedoChallenge::F27))) != GBA_READY)
bindThis(&KawasedoChallenge::_2ReadChallenge))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -39,7 +39,7 @@ void KawasedoChallenge::F25(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
void KawasedoChallenge::F27(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_2ReadChallenge(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status == GBA_READY)
if (*x10_statusPtr != (GBA_JSTAT_PSF0 | GBA_JSTAT_SEND))
......@@ -47,7 +47,7 @@ void KawasedoChallenge::F27(ThreadLocalEndpoint& endpoint, EJoyReturn status)
if (status != GBA_READY ||
(status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
bindThis(&KawasedoChallenge::F29))) != GBA_READY)
bindThis(&KawasedoChallenge::_3DSPCrypto))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -58,7 +58,7 @@ void KawasedoChallenge::F27(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
void KawasedoChallenge::F29(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_3DSPCrypto(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status != GBA_READY)
{
......@@ -71,12 +71,12 @@ void KawasedoChallenge::F29(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
else
{
GBAX02();
GBAX01(endpoint);
_DSPCryptoInit();
_DSPCryptoDone(endpoint);
}
}
void KawasedoChallenge::GBAX02()
void Endpoint::KawasedoChallenge::_DSPCryptoInit()
{
xf8_dspHmac.x0_gbaChallenge = reinterpret_cast<u32&>(x18_readBuf);
xf8_dspHmac.x4_logoPalette = x0_pColor;
......@@ -85,7 +85,7 @@ void KawasedoChallenge::GBAX02()
xf8_dspHmac.ProcessGBACrypto();
}
void KawasedoChallenge::GBAX01(ThreadLocalEndpoint& endpoint)
void Endpoint::KawasedoChallenge::_DSPCryptoDone(ThreadLocalEndpoint& endpoint)
{
x58_currentKey = xf8_dspHmac.x20_publicKey;
x5c_initMessage = xf8_dspHmac.x24_authInitCode;
......@@ -107,7 +107,7 @@ void KawasedoChallenge::GBAX01(ThreadLocalEndpoint& endpoint)
EJoyReturn status;
if ((status = endpoint.GBAWriteAsync(x1c_writeBuf, x10_statusPtr,
bindThis(&KawasedoChallenge::F31))) != GBA_READY)
bindThis(&KawasedoChallenge::_4TransmitProgram))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -118,7 +118,7 @@ void KawasedoChallenge::GBAX01(ThreadLocalEndpoint& endpoint)
}
}
void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_4TransmitProgram(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status != GBA_READY)
{
......@@ -240,7 +240,7 @@ void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
if ((status = endpoint.GBAWriteAsync(x1c_writeBuf, x10_statusPtr,
bindThis(&KawasedoChallenge::F31))) != GBA_READY)
bindThis(&KawasedoChallenge::_4TransmitProgram))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -253,7 +253,7 @@ void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
else // x34_bytesWritten > x64_totalBytes
{
if ((status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
bindThis(&KawasedoChallenge::F33))) != GBA_READY)
bindThis(&KawasedoChallenge::_5StartBootPoll))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -265,11 +265,11 @@ void KawasedoChallenge::F31(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
void KawasedoChallenge::F33(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_5StartBootPoll(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status != GBA_READY ||
(status = endpoint.GBAGetStatusAsync(x10_statusPtr,
bindThis(&KawasedoChallenge::F35))) != GBA_READY)
bindThis(&KawasedoChallenge::_6BootPoll))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -280,7 +280,7 @@ void KawasedoChallenge::F33(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_6BootPoll(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status == GBA_READY)
if (*x10_statusPtr & (GBA_JSTAT_FLAGS_MASK | GBA_JSTAT_RECV))
......@@ -300,7 +300,7 @@ void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
if (*x10_statusPtr != GBA_JSTAT_SEND)
{
if ((status = endpoint.GBAGetStatusAsync(x10_statusPtr,
bindThis(&KawasedoChallenge::F35))) != GBA_READY)
bindThis(&KawasedoChallenge::_6BootPoll))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -313,7 +313,7 @@ void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
if ((status = endpoint.GBAReadAsync(x18_readBuf, x10_statusPtr,
bindThis(&KawasedoChallenge::F37))) != GBA_READY)
bindThis(&KawasedoChallenge::_7BootAcknowledge))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -324,11 +324,11 @@ void KawasedoChallenge::F35(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
void KawasedoChallenge::F37(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_7BootAcknowledge(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status != GBA_READY ||
(status = endpoint.GBAWriteAsync(x18_readBuf, x10_statusPtr,
bindThis(&KawasedoChallenge::F39))) != GBA_READY)
bindThis(&KawasedoChallenge::_8BootDone))) != GBA_READY)
{
x28_ticksAfterXf = 0;
if (x14_callback)
......@@ -339,7 +339,7 @@ void KawasedoChallenge::F37(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
void KawasedoChallenge::F39(ThreadLocalEndpoint& endpoint, EJoyReturn status)
void Endpoint::KawasedoChallenge::_8BootDone(ThreadLocalEndpoint& endpoint, EJoyReturn status)
{
if (status == GBA_READY)
*x10_statusPtr = 0;
......@@ -353,50 +353,19 @@ void KawasedoChallenge::F39(ThreadLocalEndpoint& endpoint, EJoyReturn status)
}
}
KawasedoChallenge::KawasedoChallenge(Endpoint& endpoint, s32 paletteColor, s32 paletteSpeed,
u8* programp, s32 length, u8* status, FGBACallback&& callback)
Endpoint::KawasedoChallenge::KawasedoChallenge(Endpoint& endpoint, s32 paletteColor, s32 paletteSpeed,
const u8* programp, s32 length, u8* status, FGBACallback&& callback)
: x0_pColor(paletteColor), x4_pSpeed(paletteSpeed), x8_progPtr(programp), xc_progLen(length),
x10_statusPtr(status), x14_callback(std::move(callback)), x34_bytesSent(0)
{
if (endpoint.GBAGetStatusAsync(x10_statusPtr,
bindThis(&KawasedoChallenge::F23)) != GBA_READY)
bindThis(&KawasedoChallenge::_0Reset)) != GBA_READY)
{
x14_callback = {};
m_started = false;
}
}
u64 Endpoint::getTransferTime(u8 cmd)
{
u64 bytes = 0;
switch (cmd)
{
case CMD_RESET:
case CMD_STATUS:
{
bytes = 4;
break;
}
case CMD_READ:
{
bytes = 6;
break;
}
case CMD_WRITE:
{
bytes = 1;
break;
}
default:
{
bytes = 1;
break;
}
}
return bytes * GetGCTicksPerSec() / BYTES_PER_SECOND;
}
void Endpoint::clockSync()
{
if (!m_clockSocket)
......@@ -598,12 +567,12 @@ void Endpoint::stop()
m_transferThread.join();
}
EJoyReturn Endpoint::GBAGetProcessStatus(u8* percentp)
EJoyReturn Endpoint::GBAGetProcessStatus(u8& percentOut)
{
std::unique_lock<std::mutex> lk(m_syncLock);
if (m_joyBoot)
{
*percentp = m_joyBoot->percentComplete();
percentOut = m_joyBoot->percentComplete();
if (!m_joyBoot->isDone())
return GBA_BUSY;
}
......@@ -753,7 +722,7 @@ EJoyReturn Endpoint::GBAWrite(const u8* src, u8* status)
}
EJoyReturn Endpoint::GBAJoyBootAsync(s32 paletteColor, s32 paletteSpeed,
u8* programp, s32 length, u8* status,
const u8* programp, s32 length, u8* status,
FGBACallback&& callback)
{
if (m_chan > 3)
......
......@@ -95,7 +95,7 @@ int main(int argc, char** argv)
jbus::s64 start = jbus::GetGCTicks();
jbus::u8 percent = 0;
jbus::u8 lastpercent = 0;
while (endpoint->GBAGetProcessStatus(&percent) == jbus::GBA_BUSY)
while (endpoint->GBAGetProcessStatus(percent) == jbus::GBA_BUSY)
{
if (percent != lastpercent)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment