Skip to content

Commit ca1711c

Browse files
committed
Support repeated pb_scanControllers() calls
Also remove extra newlines in debug output
1 parent d6e326f commit ca1711c

1 file changed

Lines changed: 26 additions & 12 deletions

File tree

src/plugin_back.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* mupen64plus-input-raphnetraw
22
*
3-
* Copyright (C) 2016 Raphael Assenat
3+
* Copyright (C) 2016-2017 Raphael Assenat
44
*
55
* An input plugin that lets the game under emulation communicate with
66
* the controllers directly using the direct controller communication
@@ -34,6 +34,7 @@
3434
*/
3535

3636
#include <stdio.h>
37+
#include <string.h>
3738
#include "plugin_back.h"
3839
#include "gcn64.h"
3940
#include "gcn64lib.h"
@@ -83,6 +84,7 @@ struct rawChannel {
8384
struct adapter *adapter;
8485
int chn;
8586
};
87+
8688
/* Multiple adapters are supported, some are single player, others
8789
* two-player. As they are discovered during scan, their
8890
* channels (corresponding to physical controller ports) are added
@@ -100,7 +102,7 @@ int pb_init(pb_debugFunc debugFn)
100102
return 0;
101103
}
102104

103-
int pb_shutdown(void)
105+
static void pb_freeAllAdapters(void)
104106
{
105107
int i;
106108

@@ -109,14 +111,20 @@ int pb_shutdown(void)
109111
/* RomClosed() should have done this, but just
110112
in case it is not always called, do this again here. */
111113
gcn64lib_suspendPolling(g_adapters[i].handle, 0);
112-
113114
gcn64_closeDevice(g_adapters[i].handle);
114115
}
115116
}
116117

117-
gcn64_shutdown();
118118
g_n_channels = 0;
119119
g_n_adapters = 0;
120+
memset(g_adapters, 0, sizeof(g_adapters));
121+
memset(g_channels, 0, sizeof(g_channels));
122+
}
123+
124+
int pb_shutdown(void)
125+
{
126+
pb_freeAllAdapters();
127+
gcn64_shutdown();
120128

121129
return 0;
122130
}
@@ -132,24 +140,30 @@ int pb_scanControllers(void)
132140

133141
lctx = gcn64_allocListCtx();
134142
if (!lctx) {
135-
DebugMessage(PB_MSG_ERROR, "Could not allocate gcn64 list context\n");
143+
DebugMessage(PB_MSG_ERROR, "Could not allocate gcn64 list context");
136144
return 0;
137145
}
138146

147+
/* This may be called many times in the plugin's lifetime. For instance, each
148+
* time a new game is selected from the PJ64 menu. Freeing previously found
149+
* adapters here and creating a new list makes it possible to disconnect/replace
150+
* USB adapters without having to restart PJ64. */
151+
pb_freeAllAdapters();
152+
139153
/* Pass 1: Fill g_adapters[] with the adapters present on the system. */
140154
g_n_adapters = 0;
141155
adap = &g_adapters[g_n_adapters];
142156
while (gcn64_listDevices(&adap->inf, lctx)) {
143157

144158
adap->handle = gcn64_openDevice(&adap->inf);
145159
if (!adap->handle) {
146-
DebugMessage(PB_MSG_ERROR, "Could not open gcn64 device serial '%ls'. Skipping it.\n", adap->inf.str_serial);
160+
DebugMessage(PB_MSG_ERROR, "Could not open gcn64 device serial '%ls'. Skipping it.", adap->inf.str_serial);
147161
continue;
148162
}
149163

150164
DebugMessage(PB_MSG_INFO, "Found USB device 0x%04x:0x%04x serial '%ls' name '%ls'",
151165
adap->inf.usb_vid, adap->inf.usb_pid, adap->inf.str_serial, adap->inf.str_prodname);
152-
DebugMessage(PB_MSG_INFO, "Adapter supports %d raw channels", adap->inf.caps.n_raw_channels);
166+
DebugMessage(PB_MSG_INFO, "Adapter supports %d raw channel(s)", adap->inf.caps.n_raw_channels);
153167

154168
g_n_adapters++;
155169
if (g_n_adapters >= MAX_ADAPTERS)
@@ -160,7 +174,7 @@ int pb_scanControllers(void)
160174
gcn64_freeListCtx(lctx);
161175

162176
/* Pass 2: Fill the g_channel[] array with the available raw channels.
163-
* For instance, if there are adapter A, B and C (where A and C are single-player
177+
* For instance, if there are adapters A, B and C (where A and C are single-player
164178
* and B is dual-player), we get this:
165179
*
166180
* [0] = Adapter A, raw channel 0
@@ -355,12 +369,12 @@ static int pb_performIo(void)
355369
static int pb_commandIsValid(int Control, unsigned char *Command)
356370
{
357371
if (Control < 0 || Control >= g_n_channels) {
358-
DebugMessage(PB_MSG_WARNING, "pb_readController called with Control=%d\n", Control);
372+
DebugMessage(PB_MSG_WARNING, "pb_readController called with Control=%d", Control);
359373
return 0;
360374
}
361375

362376
if (!Command) {
363-
DebugMessage(PB_MSG_WARNING, "pb_readController called with NULL Command pointer\n");
377+
DebugMessage(PB_MSG_WARNING, "pb_readController called with NULL Command pointer");
364378
return 0;
365379
}
366380

@@ -381,7 +395,7 @@ static int pb_commandIsValid(int Control, unsigned char *Command)
381395
// against this condition...
382396
//
383397
if (Control == 2 && Command[2] > 0x03) {
384-
DebugMessage(PB_MSG_WARNING, "Invalid controller command\n");
398+
DebugMessage(PB_MSG_WARNING, "Invalid controller command");
385399
return 0;
386400
}
387401

@@ -438,7 +452,7 @@ int pb_readController(int Control, unsigned char *Command)
438452
adap = channel->adapter;
439453

440454
if (adap->n_ops >= MAX_OPS) {
441-
DebugMessage(PB_MSG_ERROR, "Too many io ops\n");
455+
DebugMessage(PB_MSG_ERROR, "Too many io ops");
442456
} else {
443457
biops = adap->biops;
444458

0 commit comments

Comments
 (0)