olivieryuyu
New member
there is a demo in the N64 SDK with source using the VRU. May be it could help to develop a HLE solution.
Hey You, Pikachu! Mic Test
Wow, that's incredible! It's really good at voice recognition, but it also picks up environment noise as unrelated words, and it rarely registers "Pikachu" correctly...but whatever, I've waited years for a HYP! emulator, it's really crazy to see something like that and it's close enough.
Thanks for your work man, I don't know how soon you plan to continue work on this but it's really cool to see that kind of progress; for someone to potentially make that game playable for people without the VRU.
it says it all in the tittle of this commentYeah, my hope is that by having this side of things essentially completed that people who are more skilled than me at reverse-engineering, or someone who owns an Adaptoid will take up the other side of the issue, communicating with the game itself.
I figure the original game likely also had major issues with background noise, but since you only turn it on right when you need it that should make it less of a problem, the issue is that it's currently trying to constantly detect phrases, and only does the output when it hears silence, that'll of course be different in the final implementation.
Hey You, Pikachu! Mic Test
So I went ahead and built a dictionary for Hey You! Pikachu using PocketSphinx, it works pretty well (about as well as the original game did). Needs some tweaking for commonly used words and Pokemon names (Pikachu is hit and miss), but otherwise it's actually quite good.
Run the batch file and say any of the in-game commands into your mic to see if it properly detects it.
I just need to look into tweaking the dictionary to be more precise for certain words and stop it from attempting to find more than one phrase used at once. Of course, still needing someone to find the VRU output for each phrase to pair it with this setup.
The VRU was tech designed originally to be compatible for use with future games.
It's been a while since I've been involved in the Hey You Pikachu project but I reckon you must have come across the research I had once published back when I was trying to reverse engineer it.
I see someone is trying to do achieve what I was once hoping to do.
Here's the deal... Anything I had done was surface fluff. All that I know is theoretical based on interpreting developer data I found online regarding the VRU.
Regarding the VRU... you have 4 very basic concepts.
1. When instructed by the game (any game), the VRU hardware begins writing and translating analogue data taken from the mic itself.
2. The VRU goes through a matching process inside the VRU and not the game. This word or phrase is translated into instructional code back to the game.
3. The word phrase is calculated as a probability of match. I forget if this happens in the VRU or the game itself.
4. The game has a "tolerance" range of probability it is willing to accept depending on a difficulty setting.
Basically, the VRU turned out to be a psuedo voice recognition unit. It isn't true recognition. thats why I stopped doing research on it. To emulate the VRU would involve learning how to make a true voice recognition unit and trying to water it down to a simple set of instructions. IMO a complete waste of time. But if you are ambitious enough to do this, hats off to you.
A feasible means to emulate the VRU would likely be forcing a probability range that is accepted by the game. you could theoretically play the game to the end but you would loose the value of actually playing it. It would be as if someone is playing it for you.
Or, you could offer a solution specific to the game where the player can select input based on random options of words (like multiple choice),therefore adding the possibility of more involvement with the player. but the real magic would still be lost.
s32 osVoiceInit(OSMesgQueue *siMessageQ, OSVoiceHandle *hd, int channel);
typedef struct {
OSMesgQueue *__mq; /* SI message queue */
int __channel; /* Controller port No. */
s32 __mode; /* Used within the OS */
u8 cmd_status; /* Command status */
} OSVoiceHandle;
s32 osVoiceSetWord(OSVoiceHandle *hd, u8 *word);
s32 osVoiceClearDictionary(OSVoiceHandle *hd, us words);
s32 osVoiceSetWord(OSVoiceHandle *hd, u8 *word);
s32 osVoiceStartReadData(OSVoiceHandle *hd);
s32 osVoiceGetReadData(OSVoiceHandle *hd, OSVoiceData *result);
typedef struct {
u16 warning; /* Warning */
u16 answer_num; /* Candidate number (0~5) */
u16 voice_level; /* Voice input level */
u16 voice_sn; /* Relative voice level */
u16 voice_time; /* Voice input time */
u16 answer[5]; /* Candidate word number */
u16 distance[5]; /* Distance value */
} OSVoiceData;
s32 osVoiceStopReadData(OSVoiceHandle *hd);
//Registered Words:
u8 *registration_word[] = {
"yakiniku",
"mario",
.
.
.
"pikachu"
};
1. When instructed by the game (any game), the VRU hardware begins writing and translating analogue data taken from the mic itself.
2. The VRU goes through a matching process inside the VRU and not the game. This word or phrase is translated into instructional code back to the game.
3. The word phrase is calculated as a probability of match. I forget if this happens in the VRU or the game itself.
4. The game has a "tolerance" range of probability it is willing to accept depending on a difficulty setting.
Oh absolutely. The Bliss-Box uses custom rumble to send API commands. Like memory pack transfers and such. The unfortunate thing is that no devs have tried to use it. For example I use this very same thing for DC emulation, like sending LCD data. You can see pictures of that on the Bliss-Box pages. The possibilities are simply endless and the best part is no friggen drivers.So you think the custom rumble feature in NRage is sufficient to send the dictionary to the VRU during initialization?
This is not Unachievable. The latency from VRU to game (emulator) is 16 ms. The Eye can detect near 17ms latency but the ear is much much greater. From game to VRU (via FFB custom) and depending on data will be significantly more (maybe 50ms). but again this is not really that bad when it comes to speech. IMO the data the game needs to send to the VRU is going to be a byte or maybe two bytes and in that case the latency will be 8ms. So round trip in my estimation (allowing for hiccups) is about 32ms tops and 16ms on average. As for sending the dictionary, latency is a non issue so it can take its time, but the Bliss-Box API will allow unlimited data transfers.My only other concern is that the game appears to recieve live feedback from the VRU while you are speaking, an undocumented feature as far as I've seen.
Oh absolutely. The Bliss-Box uses custom rumble to send API commands. Like memory pack transfers and such. The unfortunate thing is that no devs have tried to use it. For example I use this very same thing for DC emulation, like sending LCD data. You can see pictures of that on the Bliss-Box pages. The possibilities are simply endless and the best part is no friggen drivers.
This is not Unachievable. The latency from VRU to game (emulator) is 16 ms. The Eye can detect near 17ms latency but the ear is much much greater. From game to VRU (via FFB custom) and depending on data will be significantly more (maybe 50ms). but again this is not really that bad when it comes to speech. IMO the data the game needs to send to the VRU is going to be a byte or maybe two bytes and in that case the latency will be 8ms. So round trip in my estimation (allowing for hiccups) is about 32ms tops and 16ms on average. As for sending the dictionary, latency is a non issue so it can take its time, but the Bliss-Box API will allow unlimited data transfers.
typedef struct {
u16type; /*Controller type*/
u8status; /*Controller Pak status*/
u8errno; /*Error from SI device
}OSContStatus;
Voice Recognition System Errors
No SI device inserted
CONT_ERR_NO_CONTROLLER
Nothing is connected to the controller port.
Different SI Device is inserted
CONT_ERR_DEVICE
Something other than the Voice Recognition System is connected to the controller port.
Data transfer failure
CONT_ERR_CONTRFAIL
There was a data transmission failure. There is a problem in the Voice Recognition System connection.
Errors specific to this particular SI device
CONT_ERR_VOICE_WORD
A word containing improper characters has been registered. The set word is invalidated and the word number is not incremented.
CONT_ERR_VOICE_MEMORY
Dictionary memory overflow. However, if the recognition command is executed in this condition, normal recognition processing can be performed even if the number of words which have been set is less than the number of words set by the osVoiceClearDictionary() function.
CONT_ERR_NOT_READY
Either no voice has been input, or results cannot be acquired for some reason, such as that processing is still underway, etc.
Fatal error
CONT_ERR_INVALID
There is an error in the function call method or in the argument.
CONT_ERR_VOICE_NO_RESPONSE
There was no response from the Voice Recognition System. There may be a problem with the hardware.
/*---------------------------------------------------------------------
Copyright (C) 1998 Nintendo.
File main.c
Coded by Tetsuyuki Ootsuka. July, 1998.
Comments Voice Recognition System Demo Program
$Id: main.c,v 1.4 1999/04/16 10:14:40 yoshida Exp $
---------------------------------------------------------------------*/
/**************************************************************************
*
* $Revision: 1.4 $
* $Date: 1999/04/16 10:14:40 $
* $Source:
*
**************************************************************************/
#include <ultra64.h>
#include "nu64sys.h"
#include "graph.h"
#include "action.h"
#include "siproc.h"
#include "mes.h"
#define TITLE_MES_X 40
#define TITLE_MES_Y 20
#define STATUS_X 40
#define STATUS_Y 60
#define WORD_X 48
#define WORD_Y 64
#define READY_X 40
#define READY_Y 180
#define ERR_X 8
#define ERR_Y 100
#define WARN_X 40
#define WARN_Y 200
OSVoiceData result;
OSVoiceHandle vhd;
u16 *gp;
u8 draw_buffer = 1;
static OSThread siThread;
static u64 siStack[STACKSIZE/sizeof(u64)];
static OSMesg sendMsgBuf[SI_MSG_NUM];
OSMesgQueue sendMsgQ;
/*---------------------------------------------------------------------
main
---------------------------------------------------------------------*/
void
mainproc(void) {
u32 i;
u8 mode, si_mode;
s32 ret;
u16 color;
u16 delta_x;
u8 tmp[16];
sendMsg sendMesgBuff;
sendMsg *sendMesg = &sendMesgBuff;
retMsg dummyBuff;
retMsg *dummy = &dummyBuff;
/*-- Initializing SI thread --*/
osCreateMesgQueue(&sendMsgQ, sendMsgBuf, SI_MSG_NUM);
osCreateThread(&siThread, 8, (void *)siproc, 0,
siStack+STACKSIZE/sizeof(u64), 12);
osStartThread(&siThread);
ret = 0;
mode = InitMode;
si_mode = VOICE_END;
delta_x = 0;
result.answer_num = 0;
vhd.cmd_status = 0xff;
/*-- Main Loop --*/
while(1){
/*-- Writing back frame buffer --*/
osWritebackDCache(cfb[draw_buffer], 2*SCREEN_WD*SCREEN_HT);
/*-- Registering pointer on frame buffer --*/
osViSwapBuffer(cfb[draw_buffer]);
/*-- Waiting for vertical re-trace --*/
while(osRecvMesg(&retraceMessageQ, NULL, OS_MESG_NOBLOCK) == 0);
osRecvMesg(&retraceMessageQ, NULL, OS_MESG_BLOCK);
/*-- Setting frame buffer pointer --*/
draw_buffer ^= 1;
gp = (u16 *)cfb[draw_buffer];
gcls(gp);
/***** Obtaining controller data (executing SI thread) *****/
if((si_mode == VOICE_END) || (mode == NoContMode && si_mode == CONTR_END)){
si_mode = CONTR_START;
sendMesg->mode = mode;
sendMesg->si_mode = si_mode;
osSendMesg(&sendMsgQ, (OSMesg)sendMesg, OS_MESG_NOBLOCK);
}
/*-- Obtaining controller status --*/
if(si_mode == CONTR_START){
if(osRecvMesg(&retMsgQ, (OSMesg *)&dummy, OS_MESG_NOBLOCK) == 0){
si_mode = dummy->si_mode;
}
}
if(si_mode == CONTR_END){
for(i = 0;i < MAXCONTROLLERS;i++){
/*-- Retrying from initialization --*/
if(Ac.pad[i].push & A_BUTTON){
mode = InitMode;
result.answer_num = 0;
break;
}
/*-- Halt the recognition process --*/
if((Ac.pad[i].push & B_BUTTON) && (mode == GetReadMode)){
mode = StopReadMode;
break;
}
}
}
/***** Starting voice recognition process (executing SI thread) *****/
if((si_mode == CONTR_END) && (mode != NoContMode)){
si_mode = VOICE_START;
sendMesg->mode = mode;
sendMesg->si_mode = si_mode;
osSendMesg(&sendMsgQ, (OSMesg)sendMesg, OS_MESG_NOBLOCK);
}
/*-- Completing voice recognition process --*/
if(si_mode == VOICE_START){
if(osRecvMesg(&retMsgQ, (OSMesg *)&dummy, OS_MESG_NOBLOCK) == 0){
ret = dummy->ret;
mode = dummy->mode;
si_mode = dummy->si_mode;
}
}
/***** Display recognized result *****/
printkanji(gp, TITLE_MES_X, TITLE_MES_Y, WHITE, mes0);
/*-- Display process halt status --*/
if(mode == NoContMode){
printkanji(gp, WARN_X, WARN_Y, YELLOW, mes1);
prints(WARN_X+16*4, WARN_Y+16, RED, "-- Push A Button ! --");
}
/*-- Display error result --*/
if(ret == CONT_ERR_NO_CONTROLLER){
printkanji(gp, ERR_X+80, ERR_Y, RED, mes2);
printkanji(gp, ERR_X+80, ERR_Y+16, RED, mes3);
prints(ERR_X+56, ERR_Y+48, RED, "(CONT_ERR_NO_CONTROLLER)");
mode = NoContMode;
continue;
}
else if(ret == CONT_ERR_DEVICE){
printkanji(gp, ERR_X+40, ERR_Y, RED, mes4);
printkanji(gp, ERR_X+88, ERR_Y+16, RED, mes5);
prints(ERR_X+84, ERR_Y+48, RED, "(CONT_ERR_DEVICE)");
mode = NoContMode;
continue;
}
else if(ret == CONT_ERR_VOICE_NO_RESPONSE){
printkanji(gp, ERR_X+64, ERR_Y, RED, mes6);
printkanji(gp, ERR_X+88, ERR_Y+16, RED, mes7);
prints(ERR_X+40, ERR_Y+48, RED, "(CONT_ERR_VOICE_NO_RESPONSE)");
mode = NoContMode;
continue;
}
else if(ret == CONT_ERR_CONTRFAIL){
printkanji(gp, ERR_X+72, ERR_Y, RED, mes8);
prints(ERR_X+72, ERR_Y+32, RED, "(CONT_ERR_CONTRFAIL)");
mode = NoContMode;
continue;
}
else if(ret == CONT_ERR_INVALID){
printkanji(gp, ERR_X+80, ERR_Y, RED, mes9);
prints(ERR_X+80, ERR_Y+32, RED, "(CONT_ERR_INVALID)");
mode = NoContMode;
continue;
}
else if(ret == CONT_ERR_VOICE_WORD){
printkanji(gp, ERR_X+80, ERR_Y, RED, mes10);
printkanji(gp, ERR_X+72, ERR_Y+16, RED, mes11);
prints(ERR_X+68, ERR_Y+48, RED, "(CONT_ERR_VOICE_WORD)");
mode = NoContMode;
continue;
}
else if(ret == CONT_ERR_VOICE_MEMORY){
printkanji(gp, ERR_X+48, ERR_Y, RED, mes12);
prints(ERR_X+60, ERR_Y+32, RED, "(CONT_ERR_VOICE_MEMORY)");
mode = NoContMode;
}
else if(ret == CONT_ERR_NOT_READY){
if((vhd.cmd_status == VOICE_STATUS_START) || (vhd.cmd_status == VOICE_STATUS_CANCEL)){
printkanji(gp, READY_X, READY_Y, CYAN, mes13);
mode = GetReadMode;
}
}
/*-- Display recognized result --*/
if(result.answer_num != 0){
/*-- Warning --*/
if(result.warning != 0){
delta_x = 0;
if(result.warning & VOICE_WARN_TOO_NOISY){
printkanji(gp, WARN_X, WARN_Y, YELLOW, mes14);
delta_x += 64;
}
if(result.warning & VOICE_WARN_NOT_FIT){
printkanji(gp, WARN_X+delta_x, WARN_Y, YELLOW, mes15);
delta_x += 64;
}
if(result.warning & VOICE_WARN_TOO_LARGE){
printkanji(gp, WARN_X+delta_x, WARN_Y, YELLOW, mes16);
delta_x += 64;
}
if(result.warning & VOICE_WARN_TOO_SMALL){
printkanji(gp, WARN_X+delta_x, WARN_Y, YELLOW, mes17);
}
}
/*-- Display recognized words --*/
color = WHITE;
for(i = 0;i < 5;i++){
if(result.answer[i] == 0x7fff){
break;
}
if(i >= result.answer_num){
color = YELLOW;
}
printkanji(gp, WORD_X, (int)(WORD_Y+16*(i+1)), color, mes[result.answer[i]]);
sprintf(tmp, "%4d", result.distance[i]);
prints(WORD_X+16*12, (int)(WORD_Y+16*(i+1)), color, tmp);
}
}
/*-- Display status --*/
switch(vhd.cmd_status){
case VOICE_STATUS_READY:
printkanji(gp, STATUS_X, STATUS_Y, WHITE, mes18);
break;
case VOICE_STATUS_START:
printkanji(gp, STATUS_X, STATUS_Y, WHITE, mes19);
break;
case VOICE_STATUS_CANCEL:
result.answer_num = 0;
printkanji(gp, STATUS_X, STATUS_Y, WHITE, mes20);
break;
case VOICE_STATUS_BUSY:
printkanji(gp, STATUS_X, STATUS_Y, WHITE, mes21);
break;
case VOICE_STATUS_END:
printkanji(gp, STATUS_X, STATUS_Y, WHITE, mes22);
break;
}
}
}
/*---------------------------------------------------------------------
Copyright (C) 1998 Nintendo.
File siproc.c
Coded by Tetsuyuki Ootsuka. July, 1998.
Comments SI Device Procedure
$Id:
---------------------------------------------------------------------*/
/**************************************************************************
*
* $Revision: 1.3 $
* $Date: 1998/10/02 09:02:38 $
* $Source:
*
**************************************************************************/
#include <ultra64.h>
#include "nu64sys.h"
#include "siproc.h"
#include "action.h"
#include "message.c"
static OSMesg retMsgBuf[RET_MSG_NUM];
OSMesgQueue retMsgQ;
OSContStatus contStatus[MAXCONTROLLERS];
OSContPad contPad[MAXCONTROLLERS];
u8 contExist;
u8 contNo = 0;
u8 voice_size = sizeof(voice_data)/sizeof(u8 *);
/*---------------------------------------------------------------------
Serial Interface Procedure
---------------------------------------------------------------------*/
void
siproc(void)
{
u32 i;
u8 mode, si_mode;
s32 ret;
retMsg retMesgBuff;
retMsg *retMesg = &retMesgBuff;
sendMsg dummyBuff;
sendMsg *dummy = &dummyBuff;
osCreateMesgQueue(&retMsgQ, retMsgBuf, RET_MSG_NUM);
/*-- Initializing Controller --*/
osContInit(&siMessageQ, &contExist, contStatus);
actionInit();
while(1){
osRecvMesg(&sendMsgQ, (OSMesg *)&dummy, OS_MESG_BLOCK);
mode = dummy->mode;
si_mode = dummy->si_mode;
if(si_mode == CONTR_START){
/***** Obtaining Controller Data *****/
osContStartReadData(&siMessageQ);
osRecvMesg(&siMessageQ, NULL, OS_MESG_BLOCK);
osContGetReadData(contPad);
actionUpdate();
si_mode = CONTR_END;
}
else if(si_mode == VOICE_START){
/***** Starting Voice Recognition Process *****/
switch(mode){
/*-- Initialization --*/
case InitMode:
osContStartQuery(&siMessageQ);
osRecvMesg(&siMessageQ, NULL, OS_MESG_BLOCK);
osContGetQuery(contStatus);
for(i = 0; i < MAXCONTROLLERS; i++){
if((contStatus[i].errno == 0) && ((contStatus[i].type & CONT_TYPE_MASK) == CONT_TYPE_VOICE)){
contNo = i;
break;
}
}
ret = osVoiceInit(&siMessageQ, &vhd, contNo);
#ifdef CHECKGAIN
ret = osVoiceControlGain(&vhd, 1, 7);
#endif
mode = ClrDicMode;
break;
/*-- Clearing Dictionary --*/
case ClrDicMode:
ret = osVoiceClearDictionary(&vhd, voice_size);
mode = SetWordMode;
break;
/*-- Setting Words for Dictionary --*/
case SetWordMode:
i = 0;
while(i < voice_size){
#ifdef CHECKWORD
if((ret = osVoiceCheckWord(voice_data[i])) != 0){
break;
}
#endif
if((ret = osVoiceSetWord(&vhd, voice_data[i])) != 0){
break;
}
i++;
}
mode = StartReadMode;
break;
/*-- Start Voice Recognition --*/
case StartReadMode:
ret = osVoiceStartReadData(&vhd);
mode = GetReadMode;
break;
/*-- Obtaining Recognition Result --*/
case GetReadMode:
ret = osVoiceGetReadData(&vhd, &result);
if(ret == 0){
mode = StartReadMode;
}
break;
/*-- Halt the Process --*/
case StopReadMode:
ret = osVoiceStopReadData(&vhd);
mode = NoContMode;
result.warning = 0;
break;
}
si_mode = VOICE_END;
}
retMesg->ret = ret;
retMesg->mode = mode;
retMesg->si_mode = si_mode;
osSendMesg(&retMsgQ, (OSMesg)retMesg, OS_MESG_BLOCK);
}
}
/*---------------------------------------------------------------------*
Copyright (C) 1998 Nintendo.
$RCSfile: message.c,v $
$Revision: 1.2 $
$Date: 1998/09/25 21:51:51 $
*---------------------------------------------------------------------*/u8 *voice_data[] = {
"Yakiniku", /*B.B.Q.*/
"Nintendo",
"Pikachu",
"Genkidechu", /*I'm fine*/
"Uchu", /*Universe*/
"MoshiMoshi",
"Konnichiwa", /*Good afternoon*/
"Konbanwa", /*Good eveninig*/
"Sayounara", /*Good bye*/
"Oyasumi", /*Good night*/
"ByeBye",
"Mario",
"Zelda",
"Bento", /*Lunch Box*/
"Tendon", /*Tempra rice bowl*/
"Katudon", /*Pork rice bowl*/
"Ramen", /*Noodle*/
"Kyabetsu", /*Cabbage*/
"Tomato",
"Daikon", /*Radish*/
"Ninjin", /*Carrot*/
"Peaman", /*Green pepper*/
"Tamanegi", /*Onion*/
"Jyagaimo", /*Potato*/
"Satsumaimo", /*Sweet potato*/
"Renkon", /*Lotus root*/
"Cocoa", /*Hot chocolate*/
"Sutoro", /*Straw*/
"Ozon", /*Ozone*/
"Gobou", /*Burdock*/
"Udon", /*Thick Noodle*/
"Hoon", /*Heat retaining*/
"Budou", /*Grape*/
"Futon",
"Ringo", /*Apple*/
"Melon",
"Ichigo", /*Strawberry*/
"Fonto", /*Font*/
"Hontou", /*Real*/
"Daibouken", /*Adventure*/
"Fax",
"Fox",
"Ue", /*Up*/
"****a", /*Down*/
"Hidari", /*Left*/
"Migi", /*Right*/
};
/*----------------------------------------------------------------
[voice recognition testing program
----------------------------------------------------------------*/
short int mes0[]={0,128,256,384,512,640,768,896,1024,1152,1280,1408,1536,1664,-1};
/*----------------------------------------------------------------
Halt
----------------------------------------------------------------*/
short int mes1[]={1792,1920,-1};
/*----------------------------------------------------------------
Voice recognition system is not
----------------------------------------------------------------*/
short int mes2[]={128,256,384,512,2048,768,640,1536,2176,-1};
/*----------------------------------------------------------------
connected
----------------------------------------------------------------*/
short int mes3[]={2304,2432,2560,2688,2816,2944,3072,3200,3328,-1};
/*----------------------------------------------------------------
Unknown device is
----------------------------------------------------------------*/
short int mes4[]={128,256,384,512,2048,768,640,1536,3456,3584,3712,3840,3712,2176,-1};
/*----------------------------------------------------------------
connected
----------------------------------------------------------------*/
short int mes5[]={2304,2432,2560,2688,2816,2944,3072,3968,-1};
/*----------------------------------------------------------------
Voice recognition system
----------------------------------------------------------------*/
short int mes6[]={128,256,384,512,2048,768,640,1536,4096,4224,3712,-1};
/*----------------------------------------------------------------
is not responding
----------------------------------------------------------------*/
short int mes7[]={4352,4480,2176,4608,4736,3072,3200,3328,-1};
/*----------------------------------------------------------------
Misconnection
----------------------------------------------------------------*/
short int mes8[]={2304,2432,4864,4992,5120,2176,4608,4736,3072,3968,-1};
/*----------------------------------------------------------------
Fatal error
----------------------------------------------------------------*/
short int mes9[]={5248,5376,5504,5632,5760,1408,5888,6016,3968,-1};
/*----------------------------------------------------------------
Registering invalid
----------------------------------------------------------------*/
short int mes10[]={6144,6272,4864,6400,6528,5632,6656,6784,6912,-1};
/*----------------------------------------------------------------
word in dictionary
----------------------------------------------------------------*/
short int mes11[]={7040,7168,7296,7424,7552,7680,7296,3072,7296,7808,-1};
/*----------------------------------------------------------------
Dictionary is out of memory
----------------------------------------------------------------*/
short int mes12[]={6144,6272,2176,7936,8064,8192,8320,8448,5888,8576,5888,6016,3968,-1};
/*----------------------------------------------------------------
Speak into microphone
----------------------------------------------------------------*/
short int mes13[]={8704,8832,8960,4864,128,256,6912,9088,9216,7296,2816,9344,2560,2944,-1};
/*----------------------------------------------------------------
Too noisy
----------------------------------------------------------------*/
short int mes14[]={9472,128,9600,-1};
/*----------------------------------------------------------------
No matching word
----------------------------------------------------------------*/
short int mes15[]={9728,9856,9984,-1};
/*----------------------------------------------------------------
Too loud voice
----------------------------------------------------------------*/
short int mes16[]={128,256,9600,-1};
/*----------------------------------------------------------------
Too quiet voice
----------------------------------------------------------------*/
short int mes17[]={128,256,10112,-1};
/*----------------------------------------------------------------
Standby
----------------------------------------------------------------*/
short int mes18[]={10240,10368,10496,-1};
/*----------------------------------------------------------------
Not detected yet
----------------------------------------------------------------*/
short int mes19[]={10624,10752,10880,-1};
/*----------------------------------------------------------------
Cancel
----------------------------------------------------------------*/
short int mes20[]={11008,11136,11264,11392,11520,-1};
/*----------------------------------------------------------------
Detecting
----------------------------------------------------------------*/
short int mes21[]={10752,10880,10496,-1};
/*----------------------------------------------------------------
Recognition complete
----------------------------------------------------------------*/
short int mes22[]={384,512,11648,11776,-1};
/*----------------------------------------------------------------
Strings that stores recognized word
----------------------------------------------------------------*/
short int mes[][17] = {
{ 11904,12032,4864,12160,-1} ,
{ 4864,3328,2816,3328,12288,7552,-1} ,
{ 12416,4096,12544,12672,7552,-1} ,
{ 12800,3328,12032,6016,12544,12672,7552,-1} ,
{ 7552,12544,12672,7552,-1} ,
{ 3840,7296,3840,7296,-1} ,
{ 12928,3328,4864,12544,13056,-1} ,
{ 12928,3328,13184,3328,13056,-1} ,
{ 2560,7424,7552,5632,4224,-1} ,
{ 13312,11904,3968,13440,-1} ,
{ 13184,2944,13184,2944,-1} ,
{ 8704,8192,8448,-1} ,
{ 13568,11520,13696,-1} ,
{ 13824,3328,7680,7552,-1} ,
{ 2816,3328,12288,3328,-1} ,
{ 4096,13952,12288,3328,-1} ,
{ 1408,5888,7936,11264,-1} ,
{ 12032,14080,13824,13952,-1} ,
{ 7680,3072,7680,-1} ,
{ 14208,2944,12928,3328,-1} ,
{ 4864,3328,14336,3328,-1} ,
{ 12416,5888,3072,3328,-1} ,
{ 7808,3072,14464,14592,-1} ,
{ 14336,14080,2176,2944,3840,-1} ,
{ 2560,13952,3072,2944,3840,-1} ,
{ 2688,3328,12928,3328,-1} ,
{ 14720,14720,14848,-1} ,
{ 768,896,1152,5888,-1} ,
{ 8448,14976,11264,-1} ,
{ 15104,15232,7552,-1} ,
{ 7552,12288,3328,-1} ,
{ 15360,13312,3328,-1} ,
{ 15488,12288,7552,-1} ,
{ 15616,7680,3328,-1} ,
{ 4736,3328,15104,-1} ,
{ 7936,1152,11264,-1} ,
{ 2944,12544,15104,-1} ,
{ 15744,15872,11264,896,-1} ,
{ 15360,3328,7680,7552,-1} ,
{ 14208,2944,15232,7552,16000,3328,-1} ,
{ 15744,16128,16256,8960,768,-1} ,
{ 15744,15872,16256,8960,768,-1} ,
{ 7552,16384,-1} ,
{ 7296,7808,-1} ,
{ 16512,14208,4736,-1} ,
{ 13440,14592,-1} ,
};
I talked to the MESS dev and unfortunately he has dropped his involvement many years back. Does anyone here know a n64 emu developer that could assist? All we need is an emulator that boots the game to the point we can hit the z button. At that point I think we can turn on debug and watch what the game sends to the controller ports.
If we get to that point I can get the recognized HEX code from the VRU and send it on the 3rd row of buttons or analog data like the dial axis. That would be very easy to pick up in the emulator and relay to the game. At most it's a good test to get this working.