NicoHood / Nintendo

Use Nintendo Controllers with Arduino
http://www.nicohood.de
MIT License
278 stars 55 forks source link

Added support for different reading modes #34

Closed NicoHood closed 3 years ago

NicoHood commented 3 years ago

Replaces #25 and #31

The idea or this PR is to arrange the sending data in the Gamecube_Report_t itself and accept all reading modes (0-7) by default. The data structure represents reading mode 3, the other modes must be implemented on your own. It is possible, that most of the time the sending will work with 0x00 data if you do not care about the changed triggers.

mizuyoukanao commented 3 years ago

This is a way to do it without adding any additional definitions. I'm sorry, but other than mode0 and mode3, I haven't tested this method yet because I don't have the software to use it. (in Gamecube.c)

    else if (receivedBytes == 3 && command[0] == 0x40 && command[1] <= 0x07)
    {
        if (command[1] == 0x03)
        {
        gc_n64_send(report->raw8, sizeof(Gamecube_Report_t), modePort, outPort, bitMask);
        ret = 3;
        }
        else if (command[1] == 0x01)
        {
            report->cxAxis = (report->cxAxis >> 4) << 4 | report->cyAxis >> 4;
            report->cyAxis = report->left;
            report->left = report->right;
            report->right = 0x00;
            gc_n64_send(report->raw8, sizeof(Gamecube_Report_t), modePort, outPort, bitMask);
            ret = 3;
        }
        else if (command[1] == 0x02)
        {
            report->cxAxis = (report->cxAxis >> 4) << 4 | report->cyAxis >> 4;
            report->cyAxis = (report->left >> 4) << 4 | report->right >> 4;
            report->left = 0x00;
            report->right = 0x00;
            gc_n64_send(report->raw8, sizeof(Gamecube_Report_t), modePort, outPort, bitMask);
            ret = 3;
        }
        else if (command[1] == 0x04)
        {
            report->left = 0x00;
            report->right = 0x00;
            gc_n64_send(report->raw8, sizeof(Gamecube_Report_t), modePort, outPort, bitMask);
            ret = 3;
        }
        else
        {
            report->left = (report->left >> 4) << 4 | report->right >> 4;
            report->right = 0x00;
            gc_n64_send(report->raw8, sizeof(Gamecube_Report_t), modePort, outPort, bitMask);
            ret = 3;
        }
NicoHood commented 3 years ago

@mizuyoukanao thanks for sharing. I am not sure if this is the way to go, as it would rearrange the data in the current report. Meaning you cannot simply send it twice. I would prefer to have the additional union types to define different modes. We could then write converter functions like your code above that converts modes. This can be used if you are reading the controller in a different mode than the console requests it.

On the other side we do not know which mode the console might request, so your idea might be still a valid solution. Maybe we should use an additional array to cache the data, so all modifications will be only taken on this temporary array, not the real data? Not sure if it has a performance impact as well.

Uuuf really unsure about that on.e

mizuyoukanao commented 3 years ago

Sorry, I'm not very familiar with the C language... This may not be the code you think it is. 4f1eb28f32d395d034ab2c80567ffebc070fce72 596da5f53e52488512c15a3625102f504710c642

NicoHood commented 3 years ago

Great work! I've added some comments to your PR.

NicoHood commented 3 years ago

@mizuyoukanao Do you think it would make sense to add the reading mode request to the read function as well? It could be an optional parameter which defaults to 0x03? https://github.com/NicoHood/Nintendo/blob/596da5f53e52488512c15a3625102f504710c642/src/Gamecube.c#L63-L66

Not sure if it consumes more memory/flash then...

NicoHood commented 3 years ago

Closing in favor of: https://github.com/NicoHood/Nintendo/pull/42