usercode handling in BXP
1 messages in this thread
I have been experimenting (black box methods) to determine the manner in which
3DS v4 will respond to opcode/user code return values following BXP_INITIALIZE
and prior to returning BXP_INIT_DONE in the opcode member.
I have extended the USER code handling of the sample BXP.C, and include my
adaptations later in this message.
The modifications I made assigned UPM_xxx defines for my private user_codes.
When I send back
>> case UPM_DONT_UNLOAD:
>> CallTrace("UPM_DONT_UNLOAD", -1);
>> localbuf.opcode=BXP_IMAGE_INFO;
>> localbuf.usercode=UPM_IMAGE_INFO;
>> break;
then the next time BXP is called, I do not receive the expected UPM_IMAGE_INFO,
but rather receive the BXP_SAVE_IMAGE, even though I did not explicitly send
BXP_INIT_DONE.
Now I note that the example BXP.C was not entirely "consistent" in the
management or use of "status=" assignments, so I was wondering if 3DS
automatically assumes BXP_INIT-DONE when it sees the opcode request for
BXP_IMAGE_INFO, or does it assume an error in procedure and simply pick up at
the lext logical place in the sequence.
—————————— THE BXP.C code follows
—————————
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "bxp.h"
/*
Codes 0x0001-0x01FF Reserved for internal interface codes
*/
/*
Codes 0x0200-0x0FFF Reserved for user codes
*/
// UPM_xxxx user/op codes are USER PRIVATE MESSAGE defined codes
// The UPM_xx are all implementation specific. They have no fundamental
// association to 3DS itself or any BXP generically.
#define UPM_SAVE_GINFO 0x0010
#define UPM_DONT_UNLOAD 0x0011
#define UPM_IMAGE_INFO 0x0012
// define or undefine TRACE_IS_ON to enable/disable trace text output
#define TRACE_IS_ON
#ifdef TRACE_IS_ON
#define CallTrace(t,i) traceit(t,i)
#else
#define CallTrace(t,i)
#endif
int studio_version(void);
char gp_buffer[256];
typedef struct
{
ulong magic; /* Magic number */
int opcode; /* What .EXP wants to do in 3D Studio */
int usercode;/* What .EXP wants to do when it gets back */
int status; /* How it all came out */
} BufHdr;
static int bufsize=sizeof(EXPbuf);
/* Pointers to bitmaps living in 3D Studio's memory */
/* These are "_far" pointers — 48 bits worth */
static EXPbuf _far *fexpbuf; /* Comm buffer struct ptr */
/*————————————————-*/
/* Local Data */
static EXPbuf localbuf;
static int version=200;
static int init_done = 0;
/* Non-Client External Procedures (Utility) in Client Module */
extern void traceit (char *pText, int ival); // debug trace strings
/* long xpmagic, xpmainseg, xpbuffer; */
void main(void) {
/* Check magic number */
if(xpmagic!=BXP_MAGIC)
{
bad_magic:
localbuf.status=0;
return;
}
/* Copy comm buffer data to our structure */
FP_SET(fexpbuf, xpbuffer, xpmainseg);
far_to_near(&localbuf, fexpbuf, bufsize);
/* Double-check its magic number */
if(localbuf.magic!=BXP_MAGIC)
goto bad_magic;
if(localbuf.ver.magic==VER_MAGIC)
version=localbuf.ver.version;
switch(localbuf.usercode)
{
case BXP_INITIALIZE: /* A chance for user setup right after load */
CallTrace("BXP_INITIALIZE", -1);
localbuf.opcode=EXP_GFX_INFO; /* Grab graphics info */
localbuf.usercode=UPM_SAVE_GINFO; /* (for gfx_debug_print) */
break;
case UPM_SAVE_GINFO:
CallTrace("UPM_SAVE_GINFO", -1);
memcpy(GI, &localbuf.data.ginfo, sizeof(GFXInfo)); /* Hold onto
this */
GC=localbuf.data.ginfo.buf;
localbuf.opcode=EXP_DONT_UNLOAD;
localbuf.usercode=UPM_DONT_UNLOAD;
break;
case UPM_DONT_UNLOAD:
CallTrace("UPM_DONT_UNLOAD", -1);
localbuf.opcode=BXP_IMAGE_INFO;
localbuf.usercode=UPM_IMAGE_INFO;
break;
case UPM_IMAGE_INFO:
CallTrace("UPM_IMAGE_INFO", -1);
localbuf.opcode=BXP_INIT_DONE;
localbuf.status=1;
init_done = 1;
break;
case BXP_LOAD_START: /* Phase 1 of image load */
CallTrace("BXP_LOAD_START -> ClientLoadStart", -1);
ClientLoadStart(&localbuf);
break;
case BXP_LOAD_FINISH: /* Phase 2 of image load */
CallTrace("BXP_LOAD_FINISH -> ClientLoadFinish", -1);
ClientLoadFinish(&localbuf);
break;
case BXP_GET_FRAME:
CallTrace("BXP_GET_FRAME -> ClientGetFrame", -1);
ClientGetFrame(&localbuf);
break;
case BXP_IMAGE_INFO:
CallTrace("BXP_IMAGE_INFO -> ClientImageInfo", -1);
ClientImageInfo(&localbuf);
break;
case BXP_SAVE_IMAGE: /* Image save */
CallTrace("BXP_SAVE_IMAGE -> ClientSaveImage", -1);
ClientSaveImage(&localbuf);
break;
case EXP_TERMINATE:
CallTrace("EXP_TERMINATE", -1);
localbuf.opcode=EXP_TERMINATE; /* Terminate! */
localbuf.status=1; /* OK status */
break;
default:
CallTrace("ERROR IN BXP", -1);
printf("ERROR IN BXP.C: %X\n", localbuf.usercode);
localbuf.opcode=EXP_TERMINATE; /* Terminate! */
localbuf.status=0; /* ERROR status */
break;
}
if (localbuf.opcode == EXP_TERMINATE)
{
traceit(&"ClientTerminate", -1);
ClientTerminate();
}
near_to_far(fexpbuf, &localbuf, bufsize);
return;
}
int studio_version()
{
CallTrace("studio_version", -1);
return(version);
}