papermario/src/evt/msg_api.c

352 lines
11 KiB
C

#include "common.h"
extern s32 ShowMessageScreenOffsetX;
extern s32 ShowMessageScreenOffsetY;
extern s32 D_802DAE58[2]; // unused?
extern char D_802DAE60[0x400]; // unused?
extern MessagePrintState* gCurrentPrintContext;
extern bool D_802DB264;
extern MessagePrintState* D_802DB268;
ApiStatus _show_message(Evt* script, s32 isInitialCall, s32 mode);
enum {
SHOW_MESSAGE_SPEAK_TO_PLAYER = 0,
SHOW_MESSAGE_END_SPEECH = 1,
SHOW_MESSAGE_CONTINUE_SPEECH = 2,
SHOW_MESSAGE_SPEAK_TO_NPC = 3,
};
API_CALLABLE(SpeakToPlayer) {
return _show_message(script, isInitialCall, SHOW_MESSAGE_SPEAK_TO_PLAYER);
}
API_CALLABLE(EndSpeech) {
return _show_message(script, isInitialCall, SHOW_MESSAGE_END_SPEECH);
}
API_CALLABLE(ContinueSpeech) {
return _show_message(script, isInitialCall, SHOW_MESSAGE_CONTINUE_SPEECH);
}
API_CALLABLE(SpeakToNpc) {
return _show_message(script, isInitialCall, SHOW_MESSAGE_SPEAK_TO_NPC);
}
s32 _show_message(Evt* script, s32 isInitialCall, s32 mode) {
PlayerStatus* playerStatus = &gPlayerStatus;
Bytecode* args = script->ptrReadPos;
s32 screenX, screenY, screenZ;
Npc* speakerNpc;
Npc* targetNpc;
f32 reverseAngle;
f32 angle;
f32* listenerYaw;
s32 speakerNpcID;
s32 targetNpcID;
s32 msgID;
s32 animID;
s32 ret;
targetNpc = NULL;
if (isInitialCall) {
D_802DB264 = false;
speakerNpcID = evt_get_variable(script, *args++);
script->varTable[13] = evt_get_variable(script, *args++);
script->varTable[14] = evt_get_variable(script, *args++);
script->functionTemp[1] = evt_get_variable(script, *args++);
ShowMessageScreenOffsetY = 0;
ShowMessageScreenOffsetX = 0;
if (script->functionTemp[1] & SPEECH_FLAG_HAS_OFFSET) {
ShowMessageScreenOffsetX = evt_get_variable(script, *args++);
ShowMessageScreenOffsetY = evt_get_variable(script, *args++);
}
switch (mode) {
case SHOW_MESSAGE_SPEAK_TO_PLAYER:
msgID = evt_get_variable(script, *args++);
gCurrentPrintContext = msg_get_printer_for_msg(msgID, &D_802DB264);
break;
case SHOW_MESSAGE_END_SPEECH:
close_message(gCurrentPrintContext);
break;
case SHOW_MESSAGE_CONTINUE_SPEECH:
msgID = evt_get_variable(script, *args++);
msg_printer_load_msg(msgID, gCurrentPrintContext);
break;
case SHOW_MESSAGE_SPEAK_TO_NPC:
targetNpcID = evt_get_variable(script, *args++);
msgID = evt_get_variable(script, *args++);
targetNpc = resolve_npc(script, targetNpcID);
gCurrentPrintContext = msg_get_printer_for_msg(msgID, &D_802DB264);
break;
}
if (speakerNpcID == NPC_PLAYER) {
get_screen_coords(gCurrentCameraID, playerStatus->pos.x,
playerStatus->pos.y + playerStatus->colliderHeight, playerStatus->pos.z,
&screenX, &screenY, &screenZ);
script->functionTemp[3] = playerStatus->anim;
speakerNpc = (Npc*) NPC_PLAYER;
script->varTable[15] = playerStatus->targetYaw;
} else {
speakerNpc = resolve_npc(script, speakerNpcID);
get_screen_coords(gCurrentCameraID, speakerNpc->pos.x, speakerNpc->pos.y + speakerNpc->collisionHeight, speakerNpc->pos.z,
&screenX, &screenY, &screenZ);
script->functionTemp[3] = speakerNpc->curAnim;
script->varTable[15] = speakerNpc->yaw;
}
msg_printer_set_origin_pos(gCurrentPrintContext,
screenX + ShowMessageScreenOffsetX,
screenY + ShowMessageScreenOffsetY);
script->varTablePtr[12] = speakerNpc;
if (speakerNpc != (Npc*) NPC_PLAYER) {
if (mode == SHOW_MESSAGE_SPEAK_TO_NPC) {
listenerYaw = &targetNpc->yaw;
angle = atan2(speakerNpc->pos.x, speakerNpc->pos.z, targetNpc->pos.x, targetNpc->pos.z);
} else {
listenerYaw = &playerStatus->targetYaw;
angle = atan2(speakerNpc->pos.x, speakerNpc->pos.z, playerStatus->pos.x, playerStatus->pos.z);
}
reverseAngle = clamp_angle(angle + 180.0f);
switch (script->functionTemp[1] & SPEECH_ORIENTATION_MASK) {
case SPEECH_FACE_EACH_OTHER:
speakerNpc->yaw = angle;
*listenerYaw = reverseAngle;
break;
case SPEECH_FACE_LIKE_LISTENER:
speakerNpc->yaw = reverseAngle;
*listenerYaw = reverseAngle;
break;
case SPEECH_FACE_LIKE_SPEAKER:
speakerNpc->yaw = angle;
*listenerYaw = angle;
break;
case SPEECH_FACE_AWAY_FROM:
speakerNpc->yaw = reverseAngle;
*listenerYaw = angle;
break;
case SPEECH_FACE_SPEAKER_ONLY:
speakerNpc->yaw = angle;
break;
case 5:
break;
}
}
}
speakerNpc = script->varTablePtr[12];
if (speakerNpc != (Npc*) NPC_PLAYER) {
get_screen_coords(gCurrentCameraID, speakerNpc->pos.x, speakerNpc->pos.y + speakerNpc->collisionHeight, speakerNpc->pos.z, &screenX, &screenY, &screenZ);
animID = script->varTable[13];
if (animID != -1) {
if (!(gCurrentPrintContext->stateFlags & MSG_STATE_FLAG_SPEAKING)) {
animID = script->varTable[14];
}
set_npc_animation(speakerNpc, animID);
}
} else {
get_screen_coords(gCurrentCameraID, playerStatus->pos.x, playerStatus->pos.y + playerStatus->colliderHeight, playerStatus->pos.z, &screenX, &screenY, &screenZ);
if (script->varTable[13] != -1) {
if (gCurrentPrintContext->stateFlags & MSG_STATE_FLAG_SPEAKING) {
playerStatus->anim = script->varTable[13];
} else {
playerStatus->anim = script->varTable[14];
}
}
}
if (!(script->functionTemp[1] & SPEECH_FLAG_200)) {
msg_printer_set_origin_pos(gCurrentPrintContext, screenX + ShowMessageScreenOffsetX, screenY + ShowMessageScreenOffsetY);
}
if (gCurrentPrintContext->stateFlags & MSG_STATE_FLAG_40) {
return true;
}
if (D_802DB264 != true) {
return false;
}
if (script->varTable[13] != -1) {
if (speakerNpc != (Npc*) NPC_PLAYER) {
set_npc_animation(speakerNpc, script->functionTemp[3]);
} else {
playerStatus->anim = script->functionTemp[3];
}
}
if (script->functionTemp[1] & SPEECH_FLAG_10) {
speakerNpc->yaw = script->varTable[0xF];
}
return true;
}
API_CALLABLE(ShowMessageAtScreenPos) {
Bytecode* args = script->ptrReadPos;
if (isInitialCall) {
s32 msgID = evt_get_variable(script, *args++);
s32 x = evt_get_variable(script, *args++);
s32 y = evt_get_variable(script, *args++);
bool* temp802DB264 = &D_802DB264;
*temp802DB264 = false;
gCurrentPrintContext = msg_get_printer_for_msg(msgID, temp802DB264);
msg_printer_set_origin_pos(gCurrentPrintContext, x, y);
}
if (gCurrentPrintContext->stateFlags & MSG_STATE_FLAG_40) {
return ApiStatus_DONE1;
}
if (D_802DB264 != true) {
return ApiStatus_BLOCK;
}
script->varTable[0] = gCurrentPrintContext->curOption;
return ApiStatus_DONE1;
}
API_CALLABLE(ShowMessageAtWorldPos) {
Bytecode* args = script->ptrReadPos;
MessagePrintState** currentPrintContext;
s32* currentCameraID = &gCurrentCameraID;
if (isInitialCall) {
s32 msgID = evt_get_variable(script, *args++);
s32 x = evt_get_variable(script, *args++);
s32 y = evt_get_variable(script, *args++);
s32 z = evt_get_variable(script, *args++);
s32 x2;
s32 y2;
s32 z2;
bool* temp802DB264 = &D_802DB264;
*temp802DB264 = false;
currentPrintContext = &gCurrentPrintContext;
*currentPrintContext = msg_get_printer_for_msg(msgID, temp802DB264);
get_screen_coords(*currentCameraID, x, y, z, &x2, &y2, &z2);
msg_printer_set_origin_pos(*currentPrintContext, x2, y2);
}
if (gCurrentPrintContext->stateFlags & MSG_STATE_FLAG_40) {
return ApiStatus_DONE1;
}
if (D_802DB264 != true) {
return ApiStatus_BLOCK;
}
script->varTable[0] = gCurrentPrintContext->curOption;
return ApiStatus_DONE1;
}
API_CALLABLE(CloseMessage) {
if (isInitialCall) {
close_message(gCurrentPrintContext);
}
if (gCurrentPrintContext->stateFlags & MSG_STATE_FLAG_40) {
return ApiStatus_DONE1;
} else if (D_802DB264 != true) {
return ApiStatus_BLOCK;
} else {
script->varTable[0] = gCurrentPrintContext->curOption;
return ApiStatus_DONE1;
}
}
API_CALLABLE(SwitchMessage) {
Bytecode* args = script->ptrReadPos;
if (isInitialCall) {
msg_printer_load_msg(evt_get_variable(script, *args), gCurrentPrintContext);
}
if (gCurrentPrintContext->stateFlags & MSG_STATE_FLAG_40) {
return ApiStatus_DONE1;
} else if (D_802DB264 != true) {
return ApiStatus_BLOCK;
} else {
script->varTable[0] = gCurrentPrintContext->curOption;
return ApiStatus_DONE1;
}
}
API_CALLABLE(ShowChoice) {
Bytecode* args = script->ptrReadPos;
MessagePrintState** temp802DB268;
if (isInitialCall) {
s32 msgID = evt_get_variable(script, *args++);
script->functionTempBool[1] = false;
D_802DB268 = msg_get_printer_for_msg(msgID, &script->functionTempBool[1]);
}
temp802DB268 = &D_802DB268;
script->varTable[0] = gCurrentPrintContext->curOption = (*temp802DB268)->curOption;
if ((*temp802DB268)->stateFlags & MSG_STATE_FLAG_40) {
return ApiStatus_DONE1;
}
return script->functionTempBool[1] == true;
}
API_CALLABLE(CloseChoice) {
close_message(D_802DB268);
return ApiStatus_DONE1;
}
API_CALLABLE(CancelMessage) {
cancel_message(gCurrentPrintContext);
return ApiStatus_DONE2;
}
s32 cancel_current_message(void) {
cancel_message(gCurrentPrintContext);
return 0;
}
API_CALLABLE(SetMessageImages) {
Bytecode* args = script->ptrReadPos;
set_message_images((MessageImageData*) *args++);
return ApiStatus_DONE2;
}
API_CALLABLE(func_802D0C94) {
Bytecode* args = script->ptrReadPos;
if (evt_get_variable(script, *args++) == 0) {
gOverrideFlags |= GLOBAL_OVERRIDES_MESSAGES_OVER_FRONTUI;
} else {
gOverrideFlags &= ~GLOBAL_OVERRIDES_MESSAGES_OVER_FRONTUI;
}
return ApiStatus_DONE2;
}
API_CALLABLE(SetMessageText) {
Bytecode* args = script->ptrReadPos;
s32 msg = evt_get_variable(script, *args++);
s32 index = evt_get_variable(script, *args++);
set_message_text_var(msg, index);
return ApiStatus_DONE2;
}
API_CALLABLE(SetMessageValue) {
Bytecode* ptrReadPos = script->ptrReadPos;
s32 value = evt_get_variable(script, *ptrReadPos++);
s32 index = evt_get_variable(script, *ptrReadPos);
set_message_int_var(value, index);
return ApiStatus_DONE2;
}