Path: blob/main/RSDKv4/NativeObjects/MultiplayerScreen.cpp
817 views
#include "RetroEngine.hpp"12#if !RETRO_USE_ORIGINAL_CODE && RETRO_USE_NETWORKING34void MultiplayerScreen_Create(void *objPtr)5{6if (skipStartMenu) {7// code has been copied here from SegaSplash_Create due to the possibility of loading the 2P stage without the HW menus >:(8ResetBitmapFonts();9int heading = 0, labelTex = 0, textTex = 0;1011if (Engine.useHighResAssets)12heading = LoadTexture("Data/Game/Menu/Heading_EN.png", TEXFMT_RGBA4444);13else14heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);15LoadBitmapFont("Data/Game/Menu/Heading_EN.fnt", FONT_HEADING, heading);1617if (Engine.useHighResAssets)18labelTex = LoadTexture("Data/Game/Menu/Label_EN.png", TEXFMT_RGBA4444);19else20labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);21LoadBitmapFont("Data/Game/Menu/Label_EN.fnt", FONT_LABEL, labelTex);2223textTex = LoadTexture("Data/Game/Menu/Text_EN.png", TEXFMT_RGBA4444);24LoadBitmapFont("Data/Game/Menu/Text_EN.fnt", FONT_TEXT, textTex);2526switch (Engine.language) {27case RETRO_JP:28heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);29LoadBitmapFont("Data/Game/Menu/Heading_JA.fnt", FONT_HEADING, heading);3031labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);32LoadBitmapFont("Data/Game/Menu/Label_JA.fnt", FONT_LABEL, labelTex);3334textTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);35LoadBitmapFont("Data/Game/Menu/Text_JA.fnt", FONT_TEXT, textTex);36break;37case RETRO_RU:38if (Engine.useHighResAssets)39heading = LoadTexture("Data/Game/Menu/Heading_RU.png", TEXFMT_RGBA4444);40else41heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);42LoadBitmapFont("Data/Game/Menu/Heading_RU.fnt", FONT_HEADING, heading);4344if (Engine.useHighResAssets)45labelTex = LoadTexture("Data/Game/Menu/Label_RU.png", TEXFMT_RGBA4444);46else47labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);48LoadBitmapFont("Data/Game/Menu/Label_RU.fnt", FONT_LABEL, labelTex);49break;50case RETRO_KO:51heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);52LoadBitmapFont("Data/Game/Menu/Heading_KO.fnt", FONT_HEADING, heading);5354labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);55LoadBitmapFont("Data/Game/Menu/Label_KO.fnt", FONT_LABEL, labelTex);5657textTex = LoadTexture("Data/Game/Menu/Text_KO.png", TEXFMT_RGBA4444);58LoadBitmapFont("Data/Game/Menu/Text_KO.fnt", FONT_TEXT, textTex);59break;60case RETRO_ZH:61heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);62LoadBitmapFont("Data/Game/Menu/Heading_ZH.fnt", FONT_HEADING, heading);6364labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);65LoadBitmapFont("Data/Game/Menu/Label_ZH.fnt", FONT_LABEL, labelTex);6667textTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);68LoadBitmapFont("Data/Game/Menu/Text_ZH.fnt", FONT_TEXT, textTex);69break;70case RETRO_ZS:71heading = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);72LoadBitmapFont("Data/Game/Menu/Heading_ZHS.fnt", FONT_HEADING, heading);73labelTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);74LoadBitmapFont("Data/Game/Menu/Label_ZHS.fnt", FONT_LABEL, labelTex);75textTex = LoadTexture("Data/Game/Menu/[email protected]", TEXFMT_RGBA4444);76LoadBitmapFont("Data/Game/Menu/Text_ZHS.fnt", FONT_TEXT, textTex);77break;78default: break;79}80}8182RSDK_THIS(MultiplayerScreen);8384self->state = MULTIPLAYERSCREEN_STATE_ENTER;8586self->label = CREATE_ENTITY(TextLabel);87self->label->useRenderMatrix = true;88self->label->fontID = FONT_HEADING;89self->label->scale = 0.2;90self->label->alpha = 256;91self->label->x = -144.0;92self->label->y = 100.0;93self->label->z = 16.0;94self->label->state = TEXTLABEL_STATE_IDLE;95SetStringToFont8(self->label->text, "MULTIPLAYER", FONT_HEADING);9697self->meshPanel = LoadMesh("Data/Game/Models/Panel.bin", -2);98SetMeshVertexColors(self->meshPanel, 0, 0, 0, 0xC0);99self->textureArrows = LoadTexture("Data/Game/Menu/ArrowButtons.png", TEXFMT_RGBA4444);100self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST] = CREATE_ENTITY(PushButton);101self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->useRenderMatrix = true;102self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->x = 0.0;103self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->y = 20.0;104self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->z = 0.0;105self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->scale = 0.25;106self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->bgColor = 0x00A048;107self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->bgColorSelected = 0x00C060;108SetStringToFont8(self->buttons[0]->text, "HOST", FONT_LABEL);109110self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN] = CREATE_ENTITY(PushButton);111self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->useRenderMatrix = true;112self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->x = 0.0;113self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->y = -20.0;114self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->z = 0.0;115self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->scale = 0.25;116self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->bgColor = 0x00A048;117self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->bgColorSelected = 0x00C060;118SetStringToFont8(self->buttons[1]->text, "JOIN", FONT_LABEL);119120self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY] = CREATE_ENTITY(PushButton);121self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->useRenderMatrix = true;122self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->x = 0.0;123self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->y = -56.0;124self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->z = 0.0;125self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->scale = 0.175;126self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->bgColor = 0x00A048;127self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->bgColorSelected = 0x00C060;128self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->alpha = 0;129SetStringToFont8(self->buttons[2]->text, "COPY", FONT_LABEL);130131self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM] = CREATE_ENTITY(PushButton);132self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->useRenderMatrix = true;133self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->x = -56.0;134self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->y = -56.0;135self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->z = 0.0;136self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->scale = 0.175;137self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->bgColor = 0x00A048;138self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->bgColorSelected = 0x00C060;139self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->alpha = 0;140SetStringToFont8(self->buttons[3]->text, "JOIN ROOM", FONT_LABEL);141142self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE] = CREATE_ENTITY(PushButton);143self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->useRenderMatrix = true;144self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->x = 64.0;145self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->y = -56.0;146self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->z = 0.0;147self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->scale = 0.175;148self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->bgColor = 0x00A048;149self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->bgColorSelected = 0x00C060;150self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->alpha = 0;151SetStringToFont8(self->buttons[4]->text, "PASTE", FONT_LABEL);152153for (int i = 0; i < 3; ++i) {154self->codeLabel[i] = CREATE_ENTITY(TextLabel);155self->codeLabel[i]->useRenderMatrix = true;156self->codeLabel[i]->fontID = FONT_LABEL;157self->codeLabel[i]->scale = 0.15;158self->codeLabel[i]->alpha = 0;159self->codeLabel[i]->x = 0;160self->codeLabel[i]->y = 0;161self->codeLabel[i]->z = 16.0;162self->codeLabel[i]->state = TEXTLABEL_STATE_IDLE;163}164165SetStringToFont8(self->codeLabel[0]->text, "ROOM CODE", self->codeLabel[0]->fontID);166self->codeLabel[0]->alignPtr(self->codeLabel[0], ALIGN_CENTER);167168SetStringToFont8(self->codeLabel[1]->text, "UNKNOWN", self->codeLabel[1]->fontID);169self->codeLabel[1]->alignPtr(self->codeLabel[1], ALIGN_CENTER);170self->codeLabel[1]->y -= 20.0f;171172self->codeLabel[2]->y = 48.0f;173self->codeLabel[2]->scale = 0.20f;174SetStringToFont8(self->codeLabel[2]->text, "WAITING FOR 2P...", self->codeLabel[2]->fontID);175self->codeLabel[2]->alignPtr(self->codeLabel[2], ALIGN_CENTER);176177char codeBuf[0x8];178sprintf(codeBuf, "%X", 0);179180for (int i = 0; i < 8; ++i) {181self->enterCodeLabel[i] = CREATE_ENTITY(TextLabel);182self->enterCodeLabel[i]->useRenderMatrix = true;183self->enterCodeLabel[i]->fontID = FONT_LABEL;184self->enterCodeLabel[i]->scale = 0.25;185self->enterCodeLabel[i]->alpha = 0;186self->enterCodeLabel[i]->x = -102.0f + (i * 27.2) + 8.0f;187self->enterCodeLabel[i]->y = 0;188self->enterCodeLabel[i]->z = 16.0;189self->enterCodeLabel[i]->state = TEXTLABEL_STATE_IDLE;190191self->enterCodeLabel[i]->r = 0xFF;192self->enterCodeLabel[i]->g = 0xFF;193self->enterCodeLabel[i]->b = 0x00;194195SetStringToFont8(self->enterCodeLabel[i]->text, codeBuf, self->enterCodeLabel[i]->fontID);196self->enterCodeLabel[i]->alignPtr(self->enterCodeLabel[i], ALIGN_CENTER);197}198for (int i = 0; i < 2; ++i) {199self->enterCodeSlider[i] = CREATE_ENTITY(TextLabel);200self->enterCodeSlider[i]->useRenderMatrix = true;201self->enterCodeSlider[i]->fontID = FONT_LABEL;202self->enterCodeSlider[i]->scale = 0.175;203self->enterCodeSlider[i]->alpha = 0;204// self->enterCodeSlider[i]->textX = -102.0f + (i * 27.2) + 8.0f;205self->enterCodeSlider[i]->y = (i ? -23.0 : -40.0);206self->enterCodeSlider[i]->z = 16.0;207self->enterCodeSlider[i]->state = TEXTLABEL_STATE_IDLE;208SetStringToFont8(self->enterCodeSlider[i]->text, "V", self->enterCodeSlider[i]->fontID);209self->enterCodeSlider[i]->alignPtr(self->enterCodeSlider[i], ALIGN_CENTER);210}211}212213void MultiplayerScreen_DrawJoinCode(void *objPtr, int v)214{215RSDK_THIS(MultiplayerScreen);216union {217uint val;218byte bytes[4];219} u;220u.val = self->roomCode;221222for (int i = 0; i < 8; i += 2) {223int n = 7 - i;224int nybbles[] = { u.bytes[n >> 1] & 0xF, ((u.bytes[n >> 1] & 0xF0) >> 4) & 0xF };225226self->enterCodeLabel[i + 0]->alpha = 0x100;227self->enterCodeLabel[i + 1]->alpha = 0x100;228229self->enterCodeLabel[i + 0]->useColors = false;230self->enterCodeLabel[i + 1]->useColors = false;231232char codeBuf[0x10];233sprintf(codeBuf, "%X", nybbles[1]);234SetStringToFont8(self->enterCodeLabel[i + 0]->text, codeBuf, self->enterCodeLabel[i + 0]->fontID);235self->enterCodeLabel[i + 0]->alignPtr(self->enterCodeLabel[i + 0], ALIGN_CENTER);236237sprintf(codeBuf, "%X", nybbles[0]);238SetStringToFont8(self->enterCodeLabel[i + 1]->text, codeBuf, self->enterCodeLabel[i + 1]->fontID);239self->enterCodeLabel[i + 1]->alignPtr(self->enterCodeLabel[i + 1], ALIGN_CENTER);240}241self->enterCodeLabel[v]->useColors = true;242}243244void MultiplayerScreen_Destroy(void *objPtr)245{246RSDK_THIS(MultiplayerScreen);247RemoveNativeObject(self->label);248for (int i = 0; i < 3; ++i) RemoveNativeObject(self->codeLabel[i]);249for (int i = 0; i < 8; ++i) RemoveNativeObject(self->enterCodeLabel[i]);250for (int i = 0; i < 2; ++i) RemoveNativeObject(self->enterCodeSlider[i]);251for (int i = 0; i < MULTIPLAYERSCREEN_BUTTON_COUNT; ++i) RemoveNativeObject(self->buttons[i]);252RemoveNativeObject(self->bg);253RemoveNativeObject(self);254}255256void MultiplayerScreen_Main(void *objPtr)257{258RSDK_THIS(MultiplayerScreen);259260if (dcError && self->state == MULTIPLAYERSCREEN_STATE_HOSTSCR)261CREATE_ENTITY(MultiplayerHandler);262263switch (self->state) {264case MULTIPLAYERSCREEN_STATE_ENTER: {265if (self->arrowAlpha < 0x100)266self->arrowAlpha += 8;267268self->scale = fminf(self->scale + ((1.05 - self->scale) / ((60.0 * Engine.deltaTime) * 8.0)), 1.0f);269270NewRenderState();271MatrixScaleXYZF(&self->renderMatrix, self->scale, self->scale, 1.0);272MatrixTranslateXYZF(&self->matrixTemp, 0.0, -8.0, 160.0);273MatrixMultiplyF(&self->renderMatrix, &self->matrixTemp);274SetRenderMatrix(&self->renderMatrix);275276memcpy(&self->label->renderMatrix, &self->renderMatrix, sizeof(MatrixF));277for (int i = 0; i < 3; ++i) memcpy(&self->codeLabel[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));278for (int i = 0; i < MULTIPLAYERSCREEN_BUTTON_COUNT; ++i) memcpy(&self->buttons[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));279for (int i = 0; i < 8; ++i) memcpy(&self->enterCodeLabel[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));280memcpy(&self->enterCodeSlider[1]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));281MatrixRotateZF(&self->enterCodeSlider[0]->renderMatrix, DegreesToRad(180));282MatrixMultiplyF(&self->enterCodeSlider[0]->renderMatrix, &self->renderMatrix);283284self->timer += Engine.deltaTime;285if (self->timer > 0.5) {286self->timer = 0.0;287self->state = MULTIPLAYERSCREEN_STATE_MAIN;288}289break;290}291case MULTIPLAYERSCREEN_STATE_MAIN: {292CheckKeyDown(&keyDown);293CheckKeyPress(&keyPress);294SetRenderMatrix(&self->renderMatrix);295296if (usePhysicalControls) {297if (touches > 0) {298usePhysicalControls = false;299}300else {301if (keyPress.up) {302PlaySfxByName("Menu Move", false);303self->selectedButton--;304if (self->selectedButton < MULTIPLAYERSCREEN_BUTTON_HOST)305self->selectedButton = MULTIPLAYERSCREEN_BUTTON_JOIN;306}307else if (keyPress.down) {308PlaySfxByName("Menu Move", false);309self->selectedButton++;310if (self->selectedButton > MULTIPLAYERSCREEN_BUTTON_JOIN)311self->selectedButton = MULTIPLAYERSCREEN_BUTTON_HOST;312}313314self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->state = PUSHBUTTON_STATE_UNSELECTED;315self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->state = PUSHBUTTON_STATE_UNSELECTED;316self->buttons[self->selectedButton]->state = PUSHBUTTON_STATE_SELECTED;317318if (keyPress.start || keyPress.A) {319PlaySfxByName("Menu Select", false);320self->buttons[self->selectedButton]->state = PUSHBUTTON_STATE_FLASHING;321self->state = MULTIPLAYERSCREEN_STATE_ACTION;322}323else if (keyPress.B || self->backPressed) {324PlaySfxByName("Menu Back", false);325self->backPressed = false;326self->state = MULTIPLAYERSCREEN_STATE_EXIT;327self->timer = 0;328NativeEntity_FadeScreen *fade = CREATE_ENTITY(FadeScreen);329fade->delay = 1.1f;330fade->state = FADESCREEN_STATE_FADEOUT;331}332}333}334else {335if (touches > 0) {336for (int i = 0; i < 2; ++i) {337self->buttons[i]->state =338CheckTouchRect(0, 20 - (i * 40), ((64.0 * self->buttons[i]->scale) + self->buttons[i]->textWidth) * 0.75, 20.4) >= 0;339}340self->backPressed = CheckTouchRect(128.0, -92.0, 32.0, 32.0) >= 0;341if (self->state == MULTIPLAYERSCREEN_STATE_MAIN) {342if (keyDown.left) {343self->selectedButton = MULTIPLAYERSCREEN_BUTTON_JOIN;344usePhysicalControls = true;345}346if (keyDown.right) {347self->selectedButton = MULTIPLAYERSCREEN_BUTTON_HOST;348usePhysicalControls = true;349}350}351}352else {353for (int i = 0; i < 2; ++i) {354if (self->buttons[i]->state == PUSHBUTTON_STATE_SELECTED) {355PlaySfxByName("Menu Select", false);356self->buttons[i]->state = PUSHBUTTON_STATE_FLASHING;357self->selectedButton = i;358self->state = MULTIPLAYERSCREEN_STATE_ACTION;359break;360}361}362363if (keyPress.B || self->backPressed) {364PlaySfxByName("Menu Back", false);365self->backPressed = false;366self->state = MULTIPLAYERSCREEN_STATE_EXIT;367self->timer = 0;368NativeEntity_FadeScreen *fade = CREATE_ENTITY(FadeScreen);369fade->delay = 1.0;370fade->state = FADESCREEN_STATE_FADEOUT;371}372else {373if (self->state == MULTIPLAYERSCREEN_STATE_MAIN) {374if (keyDown.down) {375self->selectedButton = MULTIPLAYERSCREEN_BUTTON_JOIN;376usePhysicalControls = true;377}378if (keyDown.up) {379self->selectedButton = MULTIPLAYERSCREEN_BUTTON_HOST;380usePhysicalControls = true;381}382}383}384}385}386break;387}388case MULTIPLAYERSCREEN_STATE_ACTION: { // action389CheckKeyDown(&keyDown);390SetRenderMatrix(&self->renderMatrix);391392if (self->buttons[self->selectedButton]->state == PUSHBUTTON_STATE_UNSELECTED) {393self->state = MULTIPLAYERSCREEN_STATE_MAIN;394switch (self->selectedButton) {395default: break;396case MULTIPLAYERSCREEN_BUTTON_HOST:397self->state = MULTIPLAYERSCREEN_STATE_FLIP;398self->nextState = MULTIPLAYERSCREEN_STATE_HOSTSCR;399self->nextStateDraw = MULTIPLAYERSCREEN_STATEDRAW_HOST;400break;401case MULTIPLAYERSCREEN_BUTTON_JOIN:402self->state = MULTIPLAYERSCREEN_STATE_FLIP;403self->nextState = MULTIPLAYERSCREEN_STATE_JOINSCR;404self->nextStateDraw = MULTIPLAYERSCREEN_STATEDRAW_JOIN;405break;406case MULTIPLAYERSCREEN_BUTTON_JOINROOM: {407self->state = MULTIPLAYERSCREEN_STATE_STARTGAME;408NativeEntity_FadeScreen *fade = CREATE_ENTITY(FadeScreen);409fade->state = FADESCREEN_STATE_GAMEFADEOUT;410fade->delay = 1.1f;411break;412}413}414}415break;416}417case MULTIPLAYERSCREEN_STATE_STARTGAME:418case MULTIPLAYERSCREEN_STATE_EXIT: {419if (self->dialog)420self->dialog->state = DIALOGPANEL_STATE_IDLE;421if (self->arrowAlpha > 0)422self->arrowAlpha -= 8;423424/*if (self->timer < 0.2)425self->scale = fmaxf(self->scale + ((1.5f - self->scale) / ((Engine.deltaTime * 60.0) * 8.0)), 0.0);426else427self->scale = fmaxf(self->scale + ((-1.0f - self->scale) / ((Engine.deltaTime * 60.0) * 8.0)), 0.0);428//*/429NewRenderState();430MatrixScaleXYZF(&self->renderMatrix, self->scale, self->scale, 1.0);431MatrixTranslateXYZF(&self->matrixTemp, 0.0, -8.0, 160.0);432MatrixMultiplyF(&self->renderMatrix, &self->matrixTemp);433SetRenderMatrix(&self->renderMatrix);434435memcpy(&self->label->renderMatrix, &self->renderMatrix, sizeof(MatrixF));436for (int i = 0; i < 3; ++i) memcpy(&self->codeLabel[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));437for (int i = 0; i < MULTIPLAYERSCREEN_BUTTON_COUNT; ++i) memcpy(&self->buttons[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));438for (int i = 0; i < 8; ++i) memcpy(&self->enterCodeLabel[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));439memcpy(&self->enterCodeSlider[1]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));440MatrixRotateZF(&self->enterCodeSlider[0]->renderMatrix, DegreesToRad(180));441MatrixMultiplyF(&self->enterCodeSlider[0]->renderMatrix, &self->renderMatrix);442443self->timer += Engine.deltaTime;444if (self->timer > 0.5) {445if (self->state == MULTIPLAYERSCREEN_STATE_EXIT) {446if (skipStartMenu) {447StopMusic(true);448// is there a better way of removing the pop up message? :(449if (self->dialog) {450RemoveNativeObject(self->dialog);451RemoveNativeObject(self->label);452RemoveNativeObject(self->label);453}454SetGlobalVariableByName("options.stageSelectFlag", 0);455activeStageList = 0;456stageMode = STAGEMODE_LOAD;457Engine.gameMode = ENGINE_MAINGAME;458stageListPosition = 0;459}460else461Engine.gameMode = ENGINE_RESETGAME;462}463else {464if (self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state == PUSHBUTTON_STATE_UNSELECTED) { /// hhhhhhack465SetRoomCode(self->roomCode);466ServerPacket send;467send.header = CL_JOIN;468vsPlayerID = 1; // we are.... Little Guy469470SendServerPacket(send, true);471}472}473MultiplayerScreen_Destroy(self);474MatrixScaleXYZF(&self->renderMatrix, Engine.windowScale, Engine.windowScale, 1.0);475MatrixTranslateXYZF(&self->matrixTemp, 0.0, 0.0, 160.0);476MatrixMultiplyF(&self->renderMatrix, &self->matrixTemp);477SetRenderMatrix(&self->renderMatrix);478479RenderRect(-SCREEN_CENTERX_F, SCREEN_CENTERY_F, 160.0, SCREEN_XSIZE_F, SCREEN_YSIZE_F, 0, 0, 0, 255);480return;481}482break;483}484case MULTIPLAYERSCREEN_STATE_FLIP: { // panel flip485if (self->flipDir) {486self->rotationY += (10.0 * Engine.deltaTime);487if (self->rotationY > (M_PI_2)) {488self->state = self->nextState;489self->rotationY = 0.0;490}491else if (self->rotationY > M_PI) {492self->stateDraw = self->nextStateDraw;493self->nextStateDraw = MULTIPLAYERSCREEN_STATEDRAW_NONE;494}495}496else {497self->rotationY -= (10.0 * Engine.deltaTime);498if (self->rotationY < -(M_PI_2)) {499self->state = self->nextState;500self->rotationY = 0.0;501}502else if (self->rotationY < -M_PI) {503self->stateDraw = self->nextStateDraw;504self->nextStateDraw = MULTIPLAYERSCREEN_STATEDRAW_NONE;505}506}507NewRenderState();508MatrixRotateYF(&self->renderMatrix, self->rotationY);509MatrixTranslateXYZF(&self->matrixTemp, 0.0, -8.0, 160.0);510MatrixMultiplyF(&self->renderMatrix, &self->matrixTemp);511SetRenderMatrix(&self->renderMatrix);512513for (int i = 0; i < 3; ++i) memcpy(&self->codeLabel[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));514for (int i = 0; i < MULTIPLAYERSCREEN_BUTTON_COUNT; ++i) memcpy(&self->buttons[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));515for (int i = 0; i < 8; ++i) memcpy(&self->enterCodeLabel[i]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));516memcpy(&self->enterCodeSlider[1]->renderMatrix, &self->renderMatrix, sizeof(MatrixF));517MatrixRotateZF(&self->enterCodeSlider[0]->renderMatrix, DegreesToRad(180));518MatrixMultiplyF(&self->enterCodeSlider[0]->renderMatrix, &self->renderMatrix);519520break;521}522case MULTIPLAYERSCREEN_STATE_HOSTSCR: {523CheckKeyDown(&keyDown);524CheckKeyPress(&keyPress);525SetRenderMatrix(&self->renderMatrix);526527if (!self->roomCode) {528int code = GetRoomCode();529if (code) {530char buffer[0x30];531int code = GetRoomCode();532sprintf(buffer, "%08X", code);533SetStringToFont8(self->codeLabel[1]->text, buffer, self->codeLabel[1]->fontID);534self->codeLabel[1]->alignPtr(self->codeLabel[1], ALIGN_CENTER);535self->roomCode = code;536}537}538else {539// listen.540if (Engine.gameMode != ENGINE_WAIT2PVS) {541self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state = PUSHBUTTON_STATE_UNSELECTED; // HAck542self->selectedButton = MULTIPLAYERSCREEN_BUTTON_JOINROOM;543self->state = MULTIPLAYERSCREEN_STATE_ACTION;544}545}546547if (usePhysicalControls) {548if (touches > 0) {549usePhysicalControls = false;550}551else {552if (keyPress.A || keyPress.start) {553PlaySfxByName("Menu Select", false);554char buffer[0x30];555int code = GetRoomCode();556sprintf(buffer, "%08X", code);557SDL_SetClipboardText(buffer);558}559if (keyPress.B) {560self->dialog = CREATE_ENTITY(DialogPanel);561SetStringToFont8(self->dialog->text,562"Are you sure you want to exit?\rThis will close the room,\rand you will return to the main menu.", 2);563self->state = MULTIPLAYERSCREEN_STATE_DIALOGWAIT;564PlaySfxByName("Resume", false);565}566}567}568else {569if (touches > 0) {570self->backPressed = CheckTouchRect(128.0, -92.0, 32.0, 32.0) >= 0;571self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->state = CheckTouchRect(0, -64.0f,572((64.0 * self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->scale)573+ self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->textWidth)574* 0.75,57512.0)576>= 0;577}578else {579self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->state |= keyPress.A || keyPress.start;580if (self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->state) {581self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->state = PUSHBUTTON_STATE_UNSELECTED;582if (keyPress.A || keyPress.start)583usePhysicalControls = true;584PlaySfxByName("Menu Select", false);585char buffer[0x30];586int code = GetRoomCode();587sprintf(buffer, "%08X", code);588SDL_SetClipboardText(buffer);589}590if (keyPress.B || self->backPressed) {591self->backPressed = false;592self->dialog = CREATE_ENTITY(DialogPanel);593SetStringToFont8(self->dialog->text,594"Are you sure you want to exit?\rThis will close the room,\rand you will return to the main menu.",595FONT_TEXT);596self->state = MULTIPLAYERSCREEN_STATE_DIALOGWAIT;597PlaySfxByName("Resume", false);598}599}600}601break;602}603case MULTIPLAYERSCREEN_STATE_JOINSCR: {604CheckKeyDown(&keyDown);605CheckKeyPress(&keyPress);606SetRenderMatrix(&self->renderMatrix);607608if (usePhysicalControls) {609if (touches > 0) {610usePhysicalControls = false;611}612else {613if (keyPress.left) {614PlaySfxByName("Menu Move", false);615self->selectedButton--;616if (self->selectedButton < 3)617self->selectedButton = 12;618}619else if (keyPress.right) {620PlaySfxByName("Menu Move", false);621self->selectedButton++;622if (self->selectedButton > 12)623self->selectedButton = 3;624}625626if ((self->selectedButton != MULTIPLAYERSCREEN_BUTTON_JOINROOM && self->selectedButton != MULTIPLAYERSCREEN_BUTTON_PASTE)627&& (keyPress.up || keyPress.down)) {628union {629int val;630byte bytes[4];631} u;632u.val = self->roomCode;633int n = 7 - (self->selectedButton - 5);634int nybbles[] = { u.bytes[n >> 1] & 0xF, ((u.bytes[n >> 1] & 0xF0) >> 4) & 0xF };635636if (keyPress.up) {637PlaySfxByName("Menu Move", false);638nybbles[n & 1] = (nybbles[n & 1] + 1) & 0xF;639}640else if (keyPress.down) {641PlaySfxByName("Menu Move", false);642nybbles[n & 1] = (nybbles[n & 1] - 1) & 0xF;643}644645u.bytes[n >> 1] = (nybbles[1] << 4) | (nybbles[0] & 0xF);646self->roomCode = u.val;647648MultiplayerScreen_DrawJoinCode(self, n);649}650651for (int i = 0; i < 8; ++i) self->enterCodeLabel[i]->useColors = false;652self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state = PUSHBUTTON_STATE_UNSELECTED;653self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->state = PUSHBUTTON_STATE_UNSELECTED;654self->enterCodeSlider[0]->alpha = 0;655self->enterCodeSlider[1]->alpha = 0;656657if (self->selectedButton == MULTIPLAYERSCREEN_BUTTON_JOINROOM)658self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state = PUSHBUTTON_STATE_SELECTED;659else if (self->selectedButton == MULTIPLAYERSCREEN_BUTTON_PASTE)660self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->state = PUSHBUTTON_STATE_SELECTED;661else if (self->selectedButton > 4) {662self->enterCodeSlider[0]->x = self->enterCodeLabel[7 - (self->selectedButton - 5)]->x - 2.5;663self->enterCodeSlider[1]->x = -(self->enterCodeLabel[7 - (self->selectedButton - 5)]->x - 2.5);664self->enterCodeSlider[0]->alpha = 0x100;665self->enterCodeSlider[1]->alpha = 0x100;666667self->enterCodeLabel[self->selectedButton - 5]->useColors = true;668}669670if (keyPress.start || keyPress.A) {671if (self->selectedButton == MULTIPLAYERSCREEN_BUTTON_JOINROOM) {672PlaySfxByName("Menu Select", false);673self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state = PUSHBUTTON_STATE_UNSELECTED;674self->selectedButton = MULTIPLAYERSCREEN_BUTTON_JOINROOM;675self->state = MULTIPLAYERSCREEN_STATE_ACTION;676}677else if (self->selectedButton == MULTIPLAYERSCREEN_BUTTON_PASTE) {678self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->state = PUSHBUTTON_STATE_FLASHING;679char buf[0x30];680char *txt = SDL_GetClipboardText(); // easier bc we must SDL free after681if (StrLength(txt) && StrLength(txt) < 0x30 - 2) {682StrCopy(buf, "0x");683StrAdd(buf, txt);684int before = self->roomCode;685if (ConvertStringToInteger(buf, &self->roomCode)) {686MultiplayerScreen_DrawJoinCode(self, 0);687self->enterCodeLabel[0]->useColors = false;688self->selectedButton = MULTIPLAYERSCREEN_BUTTON_JOINROOM;689if (Engine.gameType == GAME_SONIC1) //??690PlaySfxByName("Lamp Post", false);691else692PlaySfxByName("Star Post", false);693}694else {695self->roomCode = before;696PlaySfxByName("Hurt", false);697}698}699else700PlaySfxByName("Hurt", false);701SDL_free(txt);702}703}704else if (keyPress.B) {705PlaySfxByName("Menu Back", false);706self->state = MULTIPLAYERSCREEN_STATE_FLIP;707self->nextState = MULTIPLAYERSCREEN_STATE_MAIN;708self->nextStateDraw = MULTIPLAYERSCREEN_STATEDRAW_MAIN;709}710}711}712else {713if (touches > 0) {714float w = self->enterCodeLabel[1]->x - self->enterCodeLabel[0]->x;715for (int i = 0; i < 8; ++i) {716if (CheckTouchRect(self->enterCodeLabel[i]->x, 16.0f, w / 2, 16.0) >= 0)717self->touchedUpID = i;718if (CheckTouchRect(self->enterCodeLabel[i]->x, -16.0f, w / 2, 16.0) >= 0)719self->touchedDownID = i;720}721722for (int i = 0; i < 8; ++i) self->enterCodeLabel[i]->useColors = false;723724int id = self->touchedDownID;725if (self->touchedUpID >= 0)726id = self->touchedUpID;727if (id >= 0) {728self->selectedButton = id + 5;729self->enterCodeSlider[0]->x = self->enterCodeLabel[7 - id]->x - 2.5;730self->enterCodeSlider[1]->x = -(self->enterCodeLabel[7 - id]->x - 2.5);731self->enterCodeSlider[0]->alpha = 0x100;732self->enterCodeSlider[1]->alpha = 0x100;733734self->enterCodeLabel[id]->useColors = true;735}736737self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state =738CheckTouchRect(-56.0f, -64.0f,739((64.0 * self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->scale)740+ self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->textWidth)741* 0.75,74212.0)743>= 0;744self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->state =745CheckTouchRect(74664.0f, -64.0f,747((64.0 * self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->scale) + self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->textWidth)748* 0.75,74912.0)750>= 0;751752self->backPressed = CheckTouchRect(128.0, -92.0, 32.0, 32.0) >= 0;753if (keyDown.left || keyDown.right) {754usePhysicalControls = true;755}756}757else {758if (self->touchedUpID >= 0 || self->touchedDownID >= 0) {759int id = self->touchedDownID;760if (self->touchedUpID >= 0)761id = self->touchedUpID;762763union {764int val;765byte bytes[4];766} u;767u.val = self->roomCode;768int n = 7 - id;769int nybbles[] = { u.bytes[n >> 1] & 0xF, ((u.bytes[n >> 1] & 0xF0) >> 4) & 0xF };770771if (self->touchedUpID >= 0) {772PlaySfxByName("Menu Move", false);773nybbles[n & 1] = (nybbles[n & 1] + 1) & 0xF;774}775else if (self->touchedDownID >= 0) {776PlaySfxByName("Menu Move", false);777nybbles[n & 1] = (nybbles[n & 1] - 1) & 0xF;778}779780u.bytes[n >> 1] = (nybbles[1] << 4) | (nybbles[0] & 0xF);781self->roomCode = u.val;782783for (int i = 0; i < 8; i += 2) {784int n = 7 - i;785int nybbles[] = { u.bytes[n >> 1] & 0xF, ((u.bytes[n >> 1] & 0xF0) >> 4) & 0xF };786787self->enterCodeLabel[i + 0]->alpha = 0x100;788self->enterCodeLabel[i + 1]->alpha = 0x100;789790self->enterCodeLabel[i + 0]->useColors = false;791self->enterCodeLabel[i + 1]->useColors = false;792793char codeBuf[0x10];794sprintf(codeBuf, "%X", nybbles[1]);795SetStringToFont8(self->enterCodeLabel[i + 0]->text, codeBuf, self->enterCodeLabel[i + 0]->fontID);796self->enterCodeLabel[i + 0]->alignPtr(self->enterCodeLabel[i + 0], ALIGN_CENTER);797798sprintf(codeBuf, "%X", nybbles[0]);799SetStringToFont8(self->enterCodeLabel[i + 1]->text, codeBuf, self->enterCodeLabel[i + 1]->fontID);800self->enterCodeLabel[i + 1]->alignPtr(self->enterCodeLabel[i + 1], ALIGN_CENTER);801}802self->enterCodeLabel[id]->useColors = true;803804self->touchedUpID = -1;805self->touchedDownID = -1;806}807808if (self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state == PUSHBUTTON_STATE_SELECTED) {809PlaySfxByName("Menu Select", false);810self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->state = PUSHBUTTON_STATE_UNSELECTED;811self->selectedButton = MULTIPLAYERSCREEN_BUTTON_JOINROOM;812self->state = MULTIPLAYERSCREEN_STATE_ACTION;813}814else if (self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->state == PUSHBUTTON_STATE_SELECTED) {815self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->state = PUSHBUTTON_STATE_FLASHING;816char buf[0x30];817char *txt = SDL_GetClipboardText(); // easier bc we must SDL free after818if (StrLength(txt) && StrLength(txt) < 0x30 - 2) {819StrCopy(buf, "0x");820StrAdd(buf, txt);821int before = self->roomCode;822if (ConvertStringToInteger(buf, &self->roomCode)) {823MultiplayerScreen_DrawJoinCode(self, 0);824self->enterCodeLabel[0]->useColors = false;825self->selectedButton = 5;826if (Engine.gameType == GAME_SONIC1)827PlaySfxByName("Lamp Post", false);828else829PlaySfxByName("Star Post", false);830}831else {832self->roomCode = before;833PlaySfxByName("Hurt", false);834}835}836else837PlaySfxByName("Hurt", false);838SDL_free(txt);839}840841if (keyPress.B || self->backPressed) {842PlaySfxByName("Menu Back", false);843self->backPressed = false;844self->state = MULTIPLAYERSCREEN_STATE_FLIP;845self->nextState = MULTIPLAYERSCREEN_STATE_MAIN;846self->nextStateDraw = MULTIPLAYERSCREEN_STATEDRAW_MAIN;847}848else {849if (keyDown.left) {850self->selectedButton = 5;851usePhysicalControls = true;852}853if (keyDown.right) {854self->selectedButton = 12;855usePhysicalControls = true;856}857}858}859}860break;861}862case MULTIPLAYERSCREEN_STATE_DIALOGWAIT: {863SetRenderMatrix(&self->renderMatrix);864if (self->dialog->selection == DLG_NO || self->dialog->selection == DLG_OK) {865self->state = MULTIPLAYERSCREEN_STATE_HOSTSCR;866}867else if (self->dialog->selection == DLG_YES) {868PlaySfxByName("Menu Back", false);869self->backPressed = false;870self->state = MULTIPLAYERSCREEN_STATE_EXIT;871self->timer = 0;872NativeEntity_FadeScreen *fade = CREATE_ENTITY(FadeScreen);873fade->delay = 1.1f;874fade->state = FADESCREEN_STATE_FADEOUT;875DisconnectNetwork();876InitNetwork();877}878break;879}880}881882switch (self->stateDraw) {883default: break;884case MULTIPLAYERSCREEN_STATEDRAW_MAIN:885for (int i = 0; i < MULTIPLAYERSCREEN_BUTTON_COUNT; ++i) self->buttons[i]->alpha = 0;886self->buttons[MULTIPLAYERSCREEN_BUTTON_HOST]->alpha = 0x100;887self->buttons[MULTIPLAYERSCREEN_BUTTON_JOIN]->alpha = 0x100;888889for (int i = 0; i < 3; ++i) self->codeLabel[i]->alpha = 0;890for (int i = 0; i < 8; ++i) self->enterCodeLabel[i]->alpha = 0;891for (int i = 0; i < 2; ++i) self->enterCodeSlider[i]->alpha = 0;892893self->selectedButton = MULTIPLAYERSCREEN_BUTTON_HOST;894break;895case MULTIPLAYERSCREEN_STATEDRAW_HOST: {896for (int i = 0; i < MULTIPLAYERSCREEN_BUTTON_COUNT; ++i) self->buttons[i]->alpha = 0;897for (int i = 0; i < 3; ++i) self->codeLabel[i]->alpha = 0x100;898for (int i = 0; i < 8; ++i) self->enterCodeLabel[i]->alpha = 0;899for (int i = 0; i < 2; ++i) self->enterCodeSlider[i]->alpha = 0;900901self->selectedButton = MULTIPLAYERSCREEN_BUTTON_COPY;902self->buttons[MULTIPLAYERSCREEN_BUTTON_COPY]->alpha = 0x100;903904self->roomCode = 0;905SetStringToFont8(self->codeLabel[1]->text, "FETCHING...", self->codeLabel[1]->fontID);906self->codeLabel[1]->alignPtr(self->codeLabel[1], ALIGN_CENTER);907908ServerPacket send;909send.header = CL_REQUEST_CODE;910// send over a preferred roomcode style911if (!vsGameLength)912vsGameLength = 4;913if (!vsItemMode)914vsItemMode = 1;915send.data.multiData.type = 0x00000FF0;916send.data.multiData.data[0] = (vsGameLength << 4) | (vsItemMode << 8);917vsPlayerID = 0; // we are... Big Host918919SendServerPacket(send, true);920break;921}922case MULTIPLAYERSCREEN_STATEDRAW_JOIN: {923for (int i = 0; i < MULTIPLAYERSCREEN_BUTTON_COUNT; ++i) self->buttons[i]->alpha = 0;924self->selectedButton = MULTIPLAYERSCREEN_BUTTON_COUNT;925self->touchedUpID = -1;926self->touchedDownID = -1;927928for (int i = 0; i < 3; ++i) self->codeLabel[i]->alpha = 0;929930self->roomCode = 0;931for (int i = 0; i < 8; ++i) {932self->enterCodeLabel[i]->alpha = 0x100;933self->enterCodeLabel[i]->useColors = false;934935char codeBuf[0x10];936sprintf(codeBuf, "%X", 0);937SetStringToFont8(self->enterCodeLabel[i]->text, codeBuf, self->enterCodeLabel[i]->fontID);938self->enterCodeLabel[i]->alignPtr(self->enterCodeLabel[i], ALIGN_CENTER);939}940self->enterCodeLabel[0]->useColors = true;941self->buttons[MULTIPLAYERSCREEN_BUTTON_JOINROOM]->alpha = 0x100;942self->buttons[MULTIPLAYERSCREEN_BUTTON_PASTE]->alpha = 0x100;943944break;945}946}947self->stateDraw = MULTIPLAYERSCREEN_STATEDRAW_NONE;948949SetRenderBlendMode(RENDER_BLEND_ALPHA);950RenderMesh(self->meshPanel, MESH_COLORS, false);951SetRenderBlendMode(RENDER_BLEND_ALPHA);952NewRenderState();953SetRenderMatrix(NULL);954955if (self->backPressed)956RenderImage(128.0, -92.0, 160.0, 0.3, 0.3, 64.0, 64.0, 128.0, 128.0, 128.0, 128.0, self->arrowAlpha, self->textureArrows);957else958RenderImage(128.0, -92.0, 160.0, 0.3, 0.3, 64.0, 64.0, 128.0, 128.0, 128.0, 0.0, self->arrowAlpha, self->textureArrows);959}960#endif961962963