// -------------------------------------------------- ViewState Viewer::startMainLoop(Viewer* viewer) // -------------------------------------------------- { viewer->initialize(); u32 kDown, kHeld, kUp; touchPosition touch; while(viewer->isRunning() && aptMainLoop()) { hidScanInput(); kDown = hidKeysDown(); kHeld = hidKeysHeld(); kUp = hidKeysUp(); hidTouchRead(&touch); sf2d_start_frame(GFX_TOP, GFX_LEFT); viewer->drawTopScreen(); sf2d_end_frame(); sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); viewer->drawBotScreen(); sf2d_end_frame(); sf2d_swapbuffers(); viewer->updateControls(kDown, kHeld, kUp, &touch); } return viewer->state(); }
void Input::checkForEvents() { hidScanInput(); m_kDown = hidKeysDown(); hidTouchRead(&m_touch); }
static int lua_show(lua_State *L){ int argc = lua_gettop(L); #ifndef SKIP_ERROR_HANDLING if (argc != 0) return luaL_error(L, "wrong number of arguments"); #endif touchPosition touch; hidScanInput(); hidTouchRead(&touch); keystate = keyboard.HBKB_CallKeyboard(touch); return 0; }
static int lua_touchpad(lua_State *L) { int argc = lua_gettop(L); #ifndef SKIP_ERROR_HANDLING if (lua_gettop(L) != 0) return luaL_error(L, "wrong number of arguments."); #endif touchPosition cpos; hidTouchRead(&cpos); lua_pushnumber(L, cpos.px); lua_pushnumber(L, cpos.py); return 2; }
int hidCollectData(struct hidInfo *info) { info->keys.up = hidKeysUp(); info->keys.down = hidKeysDown(); info->keys.held = hidKeysHeld(); hidTouchRead(&info->touchscreen); hidCircleRead(&info->circlepad); hidGyroRead(&info->gyro); hidCstickRead(&info->cstick); return 0; }
std::string getInput(HB_Keyboard* sHBKB, bool &bCancelled) { sHBKB->HBKB_Clean(); touchPosition touch; u8 KBState = 4; std::string input; while (KBState != 1 || input.length() == 0) { if (!aptMainLoop()) { bCancelled = true; break; } hidScanInput(); hidTouchRead(&touch); KBState = sHBKB->HBKB_CallKeyboard(touch); input = sHBKB->HBKB_CheckKeyboardInput(); // If the user cancelled the input if (KBState == 3) { bCancelled = true; break; } // Otherwise if the user has entered a key else if (KBState != 4) { printf("%c[2K\r", 27); // If input string is > 50 characters, show just the right hand side if (input.length() > 49) { printf("%s", input.substr(input.length() - 49).c_str()); } else { printf("%s", input.c_str()); } } // Flush and swap framebuffers gfxFlushBuffers(); gfxSwapBuffers(); //Wait for VBlank gspWaitForVBlank(); } printf("\n"); return input; }
void getInput() { //Touch input touchPosition myTouchPosition; hidTouchRead(&myTouchPosition); posX = myTouchPosition.px; posY = myTouchPosition.py; //HID Input old_input = input; hidScanInput(); input = hidKeysDown(); }
void UpdateInput(Input_s* input){ resetInput(input); hidScanInput(); u32 kDown = hidKeysDown(); if (kDown & KEY_TOUCH) { TC = 1; } if (TC > 0) { hidTouchRead(&tp); input->touchX = tp.px; input->touchY = tp.py; TC--; } checkVButtonTouch(input); if(kDown){ x++; //char buffer[100]; //sprintf(buffer, "Input, %d\n", x); //print(buffer); if(kDown & KEY_A){ input->A = true; } if(kDown & KEY_B){ input->B = true; } if(kDown & KEY_X){ input->X = true; } if(kDown & KEY_Y){ input->Y = true; } if(kDown & KEY_UP){ input->Up = true; } if(kDown & KEY_DOWN){ input->Down = true; } if(kDown & KEY_LEFT){ input->Left = true; } if(kDown & KEY_RIGHT){ input->Right = true; } if(kDown & KEY_START){ input->Start = true; } if(kDown & KEY_SELECT){ input->Select = true; } if(kDown & KEY_L){ input->L = true; } if(kDown & KEY_R){ input->R = true; } } }
static void ctr_joypad_poll(void) { uint32_t state_tmp; circlePosition state_tmp_left_analog, state_tmp_right_analog; touchPosition state_tmp_touch; hidScanInput(); state_tmp = hidKeysHeld(); hidCircleRead(&state_tmp_left_analog); irrstCstickRead(&state_tmp_right_analog); hidTouchRead(&state_tmp_touch); pad_state = 0; pad_state |= (state_tmp & KEY_DLEFT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0; pad_state |= (state_tmp & KEY_DDOWN) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0; pad_state |= (state_tmp & KEY_DRIGHT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0; pad_state |= (state_tmp & KEY_DUP) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0; pad_state |= (state_tmp & KEY_START) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0; pad_state |= (state_tmp & KEY_SELECT) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0; pad_state |= (state_tmp & KEY_X) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0; pad_state |= (state_tmp & KEY_Y) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0; pad_state |= (state_tmp & KEY_B) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0; pad_state |= (state_tmp & KEY_A) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0; pad_state |= (state_tmp & KEY_R) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0; pad_state |= (state_tmp & KEY_L) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0; pad_state |= (state_tmp & KEY_ZR) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0; pad_state |= (state_tmp & KEY_ZL) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0; analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = ctr_joypad_fix_range(state_tmp_left_analog.dx); analog_state[0][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = -ctr_joypad_fix_range(state_tmp_left_analog.dy); analog_state[0][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_X] = ctr_joypad_fix_range(state_tmp_right_analog.dx); analog_state[0][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_Y] = -ctr_joypad_fix_range(state_tmp_right_analog.dy); BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); if((state_tmp & KEY_TOUCH) && (state_tmp_touch.py > 120)) BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE); /* panic button */ if((state_tmp & KEY_START) && (state_tmp & KEY_SELECT) && (state_tmp & KEY_L) && (state_tmp & KEY_R)) command_event(CMD_EVENT_QUIT, NULL); }
// Mic thread void threadMic(){ while(1) { svcWaitSynchronization(threadRequest, U64_MAX); svcClearEvent(threadRequest); if(threadExit) svcExitThread(); touchPosition touch; hidTouchRead(&touch); u32 kDown = hidKeysDown(); if((touchInCircle(touch, 85, 120, 35) || kDown & KEY_A) && recording == 0) { audiobuf_pos = 0; MIC_SetRecording(1); recording = 1; } if((recording == 1) && (audiobuf_pos < audiobuf_size)) { audiobuf_pos+= MIC_ReadAudioData(&audiobuf[audiobuf_pos], audiobuf_size-audiobuf_pos, 0); if(audiobuf_pos > audiobuf_size)audiobuf_pos = audiobuf_size; if(audiobuf_pos >= 32704 && print == 0){ print = 1; } } if((touchInCircle(touch, 165, 120, 35) || kDown & KEY_B) && recording == 1) { print = 0; MIC_SetRecording(0); recording = 2; //Prevent first mute second to be allocated in wav struct if(audiobuf_pos >= 32704){ nomute_audiobuf = (u8*)linearAlloc(audiobuf_pos - 32704); memcpy(nomute_audiobuf,&audiobuf[32704],audiobuf_pos - 32704); buf_size = (audiobuf_pos - 32704) / 2; write_wav("audio.wav", buf_size, (short int *)nomute_audiobuf, S_RATE); } GSPGPU_FlushDataCache(NULL, nomute_audiobuf, audiobuf_pos); recording = 0; } } }
int cursorController() { //hidKeysHeld returns information about which buttons have are held down in this frame u32 kHeld = hidKeysHeld(); //Read the touch screen coordinates if (kHeld & KEY_TOUCH) { hidTouchRead(&touch); touch_x = touch.px; touch_y = touch.py; } sf2d_draw_texture(cursor, touch_x, touch_y); return 0; }
void CtrUi::ProcessEvents() { hidScanInput(); u32 input = hidKeysHeld(); keys[Input::Keys::Z] = (input & KEY_A); keys[Input::Keys::X] = (input & KEY_B); keys[Input::Keys::N8] = (input & KEY_X); keys[Input::Keys::SHIFT] = (input & KEY_Y); keys[Input::Keys::F12] = (input & KEY_SELECT); keys[Input::Keys::ESCAPE] = (input & KEY_START); keys[Input::Keys::RIGHT] = (input & KEY_DRIGHT); keys[Input::Keys::LEFT] = (input & KEY_DLEFT); keys[Input::Keys::UP] = (input & KEY_DUP); keys[Input::Keys::DOWN] = (input & KEY_DDOWN); keys[Input::Keys::F2] = (input & KEY_L); //Fullscreen mode support bool old_state = trigger_state; trigger_state = (input & KEY_R); if ((trigger_state != old_state) && trigger_state) fullscreen = !fullscreen; //CirclePad support circlePosition circlepad; hidCircleRead(&circlepad); if (circlepad.dy > 25) keys[Input::Keys::UP] = true; else if (circlepad.dy < -25) keys[Input::Keys::DOWN] = true; else if (circlepad.dx > 25) keys[Input::Keys::RIGHT] = true; else if (circlepad.dx < -25) keys[Input::Keys::LEFT] = true; #ifdef NO_DEBUG //Touchscreen support if (input & KEY_TOUCH){ touchPosition pos; hidTouchRead(&pos); u8 row = pos.px>>6; u8 col = pos.py / 60; u32 keys_tbl[16] = {Input::Keys::N7, Input::Keys::N8, Input::Keys::N9, Input::Keys::DIVIDE, Input::Keys::N4, Input::Keys::N5, Input::Keys::N6, Input::Keys::MULTIPLY, Input::Keys::N1, Input::Keys::N2, Input::Keys::N3, Input::Keys::SUBTRACT, Input::Keys::N0, Input::Keys::N0, Input::Keys::PERIOD, Input::Keys::ADD }; keys[keys_tbl[row + (col*4)]] = true; }else{
void getInput() { //Touch input touchPosition myTouchPosition; hidTouchRead(&myTouchPosition); posX = myTouchPosition.px; posY = myTouchPosition.py; //HID Input old_input = input; hidScanInput(); input = hidKeysDown(); if (!(!(input & KEY_TOUCH) && (old_input & KEY_TOUCH))){ posX = 0; posY = 0; } }
static void I_GetInput() { event_t event; event.data2 = event.data3 = 0; uint32_t down = hidKeysDown(); uint32_t held = hidKeysHeld(); uint32_t up = hidKeysUp(); // iterate over other possible key values int i; for (i = 0; i < (usejoystick ? 28 : 32); i++) { uint32_t key = 1<<i; if (down & key) { event.data1 = I_TranslateKey(key); event.type = ev_keydown; D_PostEvent(&event); } else if (up & key) { event.data1 = I_TranslateKey(key); event.type = ev_keyup; D_PostEvent(&event); } } // handle touch pad movement if (usemouse) { static int px = 0; static int py = 0; touchPosition touch; hidTouchRead(&touch); if (down & KEY_TOUCH) { px = touch.px; py = touch.py; } else if (held & KEY_TOUCH && (touch.px != px || touch.py != py)) { event.type = ev_mouse; event.data1 = -1; event.data2 = (touch.px - px) << 5; event.data3 = -(touch.py - py) << 5; D_PostEvent(&event); px = touch.px; py = touch.py; } } }
void IN_Move (usercmd_t *cmd) { if(hidKeysHeld() & KEY_TOUCH){ hidTouchRead(&touch); touch.px = (touch.px + oldtouch.px) / 2; touch.py = (touch.py + oldtouch.py) / 2; cl.viewangles[YAW] -= (touch.px - oldtouch.px) * sensitivity.value/2; if(in_mlook.state & 1) cl.viewangles[PITCH] += (touch.py - oldtouch.py) * sensitivity.value/2; oldtouch = touch; } hidCircleRead(&circlepad); //CirclePad deadzone to fix ghost movements if(abs(circlepad.dy) > 15){ cmd->forwardmove += m_forward.value * circlepad.dy * 2; } if(abs(circlepad.dx) > 15){ if((in_strafe.state & 1) || (lookstrafe.value)) cmd->sidemove += m_side.value * circlepad.dx * 2; else cl.viewangles[YAW] -= m_side.value * circlepad.dx * 0.03; } //cStick is only available on N3DS... Until libctru implements support for circlePad Pro if(isN3DS){ hidCstickRead(&cstick); if(m_pitch.value < 0) cstick.dy = -cstick.dy; cstick.dx = abs(cstick.dx) < 10 ? 0 : cstick.dx * csensitivity.value * 0.01; cstick.dy = abs(cstick.dy) < 10 ? 0 : cstick.dy * csensitivity.value * 0.01; cl.viewangles[YAW] -= cstick.dx; cl.viewangles[PITCH] -= cstick.dy; } V_StopPitchDrift (); }
//--------------------------------------------------------------------------- int main(int argc, char** argv) { touchPosition lastTouch; int frame=0,lp_frame=0; CWebRequest::InitializeClient(); gfxInitDefault(); GPU_Init(NULL); gfxSet3D(false); srand(svcGetSystemTick()); CFBClient::Initialize(); while(aptMainLoop()){ hidScanInput(); u32 press = hidKeysDown(); u32 held = hidKeysHeld(); u32 release = hidKeysUp(); if((press & ~KEY_TOUCH)){ CFBClient::onKeysPressEvent(press,1); hidCircleRead(&lcp); } if((release & ~KEY_TOUCH)){ CFBClient::onKeysUpEvent(press,1); hidCircleRead(&lcp); } if (held & KEY_TOUCH){ hidTouchRead(<); if(!lp_frame){ lastTouch=lt; lp_frame++; } else{ int i=0; if(abs(lt.px-lastTouch.px) <= 5){ if(abs(lt.py-lastTouch.py) <= 5) i = 1; } if(i) lp_frame++; else{ lp_frame = 0; CFBClient::onTouchEvent(<,2); } } if(!frame) CFBClient::onTouchEvent(<,1); frame++; } else{ if(frame) CFBClient::onTouchEvent(<,lp_frame > 120 ? 8 : 4); frame = 0; lp_frame = 0; } CFBClient::main(0); gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); } CFBClient::Destroy(); CWebRequest::DestroyClient(); fsExit(); hidExit(); gfxExit(); aptExit(); srvExit(); return 0; }
int main(int argc, char **argv) { gfxInitDefault(); socInit((u32 *)memalign(0x1000, 0x100000), 0x100000); // Check wifi status u32 wifiStatus = 0; ACU_GetWifiStatus(&wifiStatus); if (!wifiStatus) { printf("\x1b[1;1HNo WiFi! Is your wireless slider on?"); } // Use printf on top screen consoleInit(GFX_TOP, NULL); // Stuff for network magic int recvlen; unsigned char buf[BUFSIZE]; unsigned char IDBuf[BUFSIZE]; // Try create socket int err = 0; if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { err = 1; } // Setup socket addresses out.sin_family = in.sin_family = AF_INET; out.sin_port = in.sin_port = htons(PORT); // Set port in.sin_addr.s_addr = INADDR_ANY; // Try to bind socket to port if (err == 0 && bind(sock, (struct sockaddr *)&in, sizeof(in)) < 0) err = 2; // If any errors if (err != 0) printf("\x1b[4;1HError opening connection: %i", err); // Set socket receive to non-blocking to be able to exit while listening for broadcast fcntl(sock, F_SETFL, O_NONBLOCK); bool connected = false; // Main loop while (aptMainLoop()) { if (err == 0) { // If not connected, listen for broadcast if (!connected) { printf("\x1b[1;1HListening for broadcast on port %d", PORT); // Listen for packets. Returns packet size recvlen = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *)&out, &addrlen); // Check if correct packet. recvlen < 0 -> Error if (recvlen > 0) { printf("\x1b[2;1Hr"); // Debug print. Writes r for any packet received buf[recvlen] = 0; // Don't remember what this is for. Oops // Check if message is connection port (Broadcast sends out port number as broadcast) int i = atoi(buf); if (i == PORT) { // If broadcast message, assign send address to received address in.sin_addr.s_addr = out.sin_addr.s_addr; // Prepare program; Setting flag, turning of backlight, etc connected = true; consoleClear(); printf("\x1b[1;1HConnected"); if (backlightOff == false) disableBacklight(); backlightOff = true; } } } } printf("\x1b[28;1HPlayer ID: %i", playerID); printf("\x1b[29;1HPress START and SELECT to exit"); // Scan input hidScanInput(); // Save keystate u32 kDown = hidKeysHeld(); if ((kDown & KEY_START) && (kDown & KEY_SELECT)) break; // break in order to return to hbmenu // If no errors and connected. Contruct input message if (err == 0 && connected) { // Get circle pad state circlePosition pos; hidCircleRead(&pos); // Construct message message.ID = playerID; message.pdx = pos.dx; message.pdy = pos.dy; message.btn = kDown; // Query for touchscreen information touchPosition touch; hidTouchRead(&touch); message.touch_px = touch.px; message.touch_py = touch.py; // Send packet to address broadcast came from sendto(sock, &message, sizeof(message), 0, (struct sockaddr *)&in, sizeof(in)); int recv = 0; int count = 0; do { count++; // Send packet to address broadcast came from sendto(sock, &message, sizeof(message), 0, (struct sockaddr *)&in, sizeof(in)); // Listen for packet to get player ID and check if server is alive //int recv = read(sock, IDBuf, sizeof(IDBuf)); recv = recvfrom(sock, IDBuf, BUFSIZE, 0, (struct sockaddr *)&out, &addrlen); } while (atoi(IDBuf) == PORT && count < 5); if (count < 5 && recv > 0) playerID = IDBuf[0] | IDBuf[1] << 1; else { connected = false; playerID = 0; consoleClear(); printf("\x1b[2;1HDisconnected"); if (backlightOff == true) { enableBacklight(); backlightOff = false; } } } u64 sleepDuration = 16000000ULL; svcSleepThread(sleepDuration); // Draw stuff gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); } // On exit if (backlightOff == true) enableBacklight(); socExit(); gfxExit(); return 0; }
u8 keyboardUpdate() { blinkTimer++; if(blinkTimer > 10) { blinkTimer = 0; blink++; blink&=1; } touchPosition touchPos; hidTouchRead(&touchPos); if(isKeyPressed(KEY_TOUCH)) { if(isTouchingRect(&touchPos, &key1)) { writeChar('1'); } else if(isTouchingRect(&touchPos, &key2)) { writeChar('2'); } else if(isTouchingRect(&touchPos, &key3)) { writeChar('3'); } else if(isTouchingRect(&touchPos, &key4)) { writeChar('4'); } else if(isTouchingRect(&touchPos, &key5)) { writeChar('5'); } else if(isTouchingRect(&touchPos, &key6)) { writeChar('6'); } else if(isTouchingRect(&touchPos, &key7)) { writeChar('7'); } else if(isTouchingRect(&touchPos, &key8)) { writeChar('8'); } else if(isTouchingRect(&touchPos, &key9)) { writeChar('9'); } else if(isTouchingRect(&touchPos, &key0)) { writeChar('0'); } else if(isTouchingRect(&touchPos, &keyDash)) { writeChar('-'); } else if(isTouchingRect(&touchPos, &keyQ)){ if (lowercase) writeChar('q'); else writeChar('Q'); } else if(isTouchingRect(&touchPos, &keyW)){ if (lowercase) writeChar('w'); else writeChar('W'); } else if(isTouchingRect(&touchPos, &keyE)){ if (lowercase) writeChar('e'); else writeChar('E'); } else if(isTouchingRect(&touchPos, &keyR)){ if (lowercase) writeChar('r'); else writeChar('R'); } else if(isTouchingRect(&touchPos, &keyT)){ if (lowercase) writeChar('t'); else writeChar('T'); } else if(isTouchingRect(&touchPos, &keyY)){ if (lowercase) writeChar('y'); else writeChar('Y'); } else if(isTouchingRect(&touchPos, &keyU)){ if (lowercase) writeChar('u'); else writeChar('U'); } else if(isTouchingRect(&touchPos, &keyI)){ if (lowercase) writeChar('i'); else writeChar('I'); } else if(isTouchingRect(&touchPos, &keyO)){ if (lowercase) writeChar('o'); else writeChar('O'); } else if(isTouchingRect(&touchPos, &keyP)){ if (lowercase) writeChar('p'); else writeChar('P'); } else if(isTouchingRect(&touchPos, &keyA)){ if (lowercase) writeChar('a'); else writeChar('A'); } else if(isTouchingRect(&touchPos, &keyS)){ if (lowercase) writeChar('s'); else writeChar('S'); } else if(isTouchingRect(&touchPos, &keyD)){ if (lowercase) writeChar('d'); else writeChar('D'); } else if(isTouchingRect(&touchPos, &keyF)){ if (lowercase) writeChar('f'); else writeChar('F'); } else if(isTouchingRect(&touchPos, &keyG)){ if (lowercase) writeChar('g'); else writeChar('G'); } else if(isTouchingRect(&touchPos, &keyH)){ if (lowercase) writeChar('h'); else writeChar('H'); } else if(isTouchingRect(&touchPos, &keyJ)){ if (lowercase) writeChar('j'); else writeChar('J'); } else if(isTouchingRect(&touchPos, &keyK)){ if (lowercase) writeChar('k'); else writeChar('K'); } else if(isTouchingRect(&touchPos, &keyL)){ if (lowercase) writeChar('l'); else writeChar('L'); } else if(isTouchingRect(&touchPos, &keySingleQuote)){ writeChar('\''); } else if(isTouchingRect(&touchPos, &keyEqual)){ writeChar('='); } else if(isTouchingRect(&touchPos, &keySlash)){ writeChar('/'); } else if(isTouchingRect(&touchPos, &keyZ)){ if (lowercase) writeChar('z'); else writeChar('Z'); } else if(isTouchingRect(&touchPos, &keyX)){ if (lowercase) writeChar('x'); else writeChar('X'); } else if(isTouchingRect(&touchPos, &keyC)){ if (lowercase) writeChar('c'); else writeChar('C'); } else if(isTouchingRect(&touchPos, &keyV)){ if (lowercase) writeChar('v'); else writeChar('V'); } else if(isTouchingRect(&touchPos, &keyB)){ if (lowercase) writeChar('b'); else writeChar('B'); } else if(isTouchingRect(&touchPos, &keyN)){ if (lowercase) writeChar('n'); else writeChar('N'); } else if(isTouchingRect(&touchPos, &keyM)){ if (lowercase) writeChar('m'); else writeChar('M'); } else if(isTouchingRect(&touchPos, &keyComma)){ writeChar(','); } else if(isTouchingRect(&touchPos, &keyDot)){ writeChar('.'); } else if(isTouchingRect(&touchPos, &keyQMark)){ writeChar('?'); } else if(isTouchingRect(&touchPos, &keyEMark)){ writeChar('!'); } else if(isTouchingRect(&touchPos, &keyAt)){ writeChar('@'); } else if(isTouchingRect(&touchPos, &keySpace)){ writeChar(' '); } } if(isKeyPressed(CONTROLS_CANCEL) || (isKeyPressed(KEY_TOUCH) && isTouchingRect(&touchPos, &keyBackspace))) { if(charIndex > 0) { textCursorPos.x -= getCharWidth(FONTFAMILY_VERDANA14, text[charIndex-1]); charIndex--; text[charIndex] = ' '; } } if(isKeyPressed(CONTROLS_KBENTER) || (isKeyPressed(KEY_TOUCH) && isTouchingRect(&touchPos, &keyOK))) { if(charIndex > 0) return 1; } return 0; }
static void eventThreadFunc(void *arg) { OSystem_3DS *osys = (OSystem_3DS *)g_system; auto eventQueue = (Common::Queue<Common::Event> *)arg; uint32 touchStartTime = osys->getMillis(); touchPosition lastTouch = {0, 0}; bool isRightClick = false; float cursorX = 0; float cursorY = 0; float cursorDeltaX = 0; float cursorDeltaY = 0; int circleDeadzone = 20; int borderSnapZone = 6; Common::Event event; while (!osys->exiting) { do { osys->delayMillis(10); } while (osys->sleeping && !osys->exiting); hidScanInput(); touchPosition touch; circlePosition circle; u32 held = hidKeysHeld(); u32 keysPressed = hidKeysDown(); u32 keysReleased = hidKeysUp(); // C-Pad used to control the cursor hidCircleRead(&circle); if (circle.dx < circleDeadzone && circle.dx > -circleDeadzone) circle.dx = 0; if (circle.dy < circleDeadzone && circle.dy > -circleDeadzone) circle.dy = 0; cursorDeltaX = (0.0002f + config.sensitivity / 100000.f) * circle.dx * abs(circle.dx); cursorDeltaY = (0.0002f + config.sensitivity / 100000.f) * circle.dy * abs(circle.dy); // Touch screen events if (held & KEY_TOUCH) { hidTouchRead(&touch); if (config.snapToBorder) { if (touch.px < borderSnapZone) touch.px = 0; if (touch.px > 319 - borderSnapZone) touch.px = 319; if (touch.py < borderSnapZone) touch.py = 0; if (touch.py > 239 - borderSnapZone) touch.py = 239; } cursorX = touch.px; cursorY = touch.py; osys->transformPoint(touch); osys->warpMouse(touch.px, touch.py); event.mouse.x = touch.px; event.mouse.y = touch.py; if (keysPressed & KEY_TOUCH) { touchStartTime = osys->getMillis(); isRightClick = (held & KEY_X || held & KEY_DUP); if (inputMode == MODE_DRAG) { event.type = isRightClick ? Common::EVENT_RBUTTONDOWN : Common::EVENT_LBUTTONDOWN; pushEventQueue(eventQueue, event); } } else if (touch.px != lastTouch.px || touch.py != lastTouch.py) { event.type = Common::EVENT_MOUSEMOVE; pushEventQueue(eventQueue, event); } lastTouch = touch; } else if (keysReleased & KEY_TOUCH) { event.mouse.x = lastTouch.px; event.mouse.y = lastTouch.py; if (inputMode == MODE_DRAG) { event.type = isRightClick ? Common::EVENT_RBUTTONUP : Common::EVENT_LBUTTONUP; pushEventQueue(eventQueue, event); } else if (osys->getMillis() - touchStartTime < 200) { // Process click in MODE_HOVER event.type = Common::EVENT_MOUSEMOVE; pushEventQueue(eventQueue, event); event.type = isRightClick ? Common::EVENT_RBUTTONDOWN : Common::EVENT_LBUTTONDOWN; pushEventQueue(eventQueue, event); event.type = isRightClick ? Common::EVENT_RBUTTONUP : Common::EVENT_LBUTTONUP; pushEventQueue(eventQueue, event); } } else if (cursorDeltaX != 0 || cursorDeltaY != 0) { cursorX += cursorDeltaX; cursorY -= cursorDeltaY; if (cursorX < 0) cursorX = 0; if (cursorY < 0) cursorY = 0; if (cursorX > 320) cursorX = 320; if (cursorY > 240) cursorY = 240; lastTouch.px = cursorX; lastTouch.py = cursorY; osys->transformPoint(lastTouch); osys->warpMouse(lastTouch.px, lastTouch.py); event.mouse.x = lastTouch.px; event.mouse.y = lastTouch.py; event.type = Common::EVENT_MOUSEMOVE; pushEventQueue(eventQueue, event); } // Button events if (keysPressed & KEY_R) { if (inputMode == MODE_DRAG) { inputMode = MODE_HOVER; osys->displayMessageOnOSD("Hover Mode"); } else { inputMode = MODE_DRAG; osys->displayMessageOnOSD("Drag Mode"); } } if (keysPressed & KEY_A || keysPressed & KEY_DLEFT || keysReleased & KEY_A || keysReleased & KEY_DLEFT) { // SIMULATE LEFT CLICK event.mouse.x = lastTouch.px; event.mouse.y = lastTouch.py; if (keysPressed & KEY_A || keysPressed & KEY_DLEFT) event.type = Common::EVENT_LBUTTONDOWN; else event.type = Common::EVENT_LBUTTONUP; pushEventQueue(eventQueue, event); } if (keysPressed & KEY_X || keysPressed & KEY_DUP || keysReleased & KEY_X || keysReleased & KEY_DUP) { // SIMULATE RIGHT CLICK event.mouse.x = lastTouch.px; event.mouse.y = lastTouch.py; if (keysPressed & KEY_X || keysPressed & KEY_DUP) event.type = Common::EVENT_RBUTTONDOWN; else event.type = Common::EVENT_RBUTTONUP; pushEventQueue(eventQueue, event); } if (keysPressed & KEY_L) { event.type = Common::EVENT_VIRTUAL_KEYBOARD; pushEventQueue(eventQueue, event); } if (keysPressed & KEY_START) { event.type = Common::EVENT_MAINMENU; pushEventQueue(eventQueue, event); } if (keysPressed & KEY_SELECT) { if (!optionMenuOpened) optionMenuOpening = true; } if (keysPressed & KEY_B || keysReleased & KEY_B || keysPressed & KEY_DDOWN || keysReleased & KEY_DDOWN) { if (keysPressed & KEY_B || keysPressed & KEY_DDOWN) event.type = Common::EVENT_KEYDOWN; else event.type = Common::EVENT_KEYUP; event.kbd.keycode = Common::KEYCODE_ESCAPE; event.kbd.ascii = Common::ASCII_ESCAPE; event.kbd.flags = 0; pushEventQueue(eventQueue, event); } // TODO: EVENT_PREDICTIVE_DIALOG // EVENT_SCREEN_CHANGED } }
void state_man() { print_menu(); u32 kDown = hidKeysDown(); //hidKeysHeld returns information about which buttons have are held down in this frame u32 kHeld = hidKeysHeld(); //hidKeysUp returns information about which buttons have been just released u32 kUp = hidKeysUp(); touchPosition touch; //Read the touch screen coordinates hidTouchRead(&touch); if (play_box.is_within(touch.px, touch.py) && (kDown & KEY_TOUCH)) { paused = !paused; draw_ui = true; } if (loop_box.is_within(touch.px, touch.py) && (kDown & KEY_TOUCH)) { loop_flag = !loop_flag; draw_ui = true; } if (state == STATE_IDLE) { if (kDown & KEY_X) { state = STATE_FC; cursor_pos = 0; draw_ui = true; } if (kUp & KEY_UP) { loop_flag = !loop_flag; draw_ui = true; } if (kUp & KEY_A) { paused = !paused; draw_ui = true; } } else if (state == STATE_FC) { if (kDown & KEY_X) { state = STATE_IDLE; draw_ui = true; } if (kUp & KEY_UP) { cursor_pos--; if (cursor_pos < 0) cursor_pos = 0; draw_ui = true; } if (kDown & KEY_DOWN) { cursor_pos++; if (cursor_pos < 0) cursor_pos = 0; draw_ui = true; } if (kUp & KEY_A) { pick(); draw_ui = true; } } }
static bool ctr_frame(void* data, const void* frame, unsigned width, unsigned height, uint64_t frame_count, unsigned pitch, const char* msg) { uint32_t diff; static uint64_t currentTick,lastTick; ctr_video_t *ctr = (ctr_video_t*)data; settings_t *settings = config_get_ptr(); static float fps = 0.0; static int total_frames = 0; static int frames = 0; static struct retro_perf_counter ctrframe_f = {0}; uint32_t state_tmp; touchPosition state_tmp_touch; extern bool select_pressed; if (!width || !height) { gspWaitForEvent(GSPEVENT_VBlank0, true); return true; } if(!aptMainLoop()) { event_command(EVENT_CMD_QUIT); return true; } if (select_pressed) { event_command(EVENT_CMD_QUIT); return true; } state_tmp = hidKeysDown(); hidTouchRead(&state_tmp_touch); if((state_tmp & KEY_TOUCH) && (state_tmp_touch.py < 120)) { Handle lcd_handle; u8 not_2DS; extern PrintConsole* currentConsole; gfxBottomFramebuffers[0] = ctr->lcd_buttom_on ? (u8*)ctr->empty_framebuffer: (u8*)currentConsole->frameBuffer; CFGU_GetModelNintendo2DS(¬_2DS); if(not_2DS && srvGetServiceHandle(&lcd_handle, "gsp::Lcd") >= 0) { u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = ctr->lcd_buttom_on? 0x00120040: 0x00110040; cmdbuf[1] = 2; svcSendSyncRequest(lcd_handle); svcCloseHandle(lcd_handle); } ctr->lcd_buttom_on = !ctr->lcd_buttom_on; } svcWaitSynchronization(gspEvents[GSPEVENT_P3D], 20000000); svcClearEvent(gspEvents[GSPEVENT_P3D]); svcWaitSynchronization(gspEvents[GSPEVENT_PPF], 20000000); svcClearEvent(gspEvents[GSPEVENT_PPF]); frames++; if (ctr->vsync) svcWaitSynchronization(gspEvents[GSPEVENT_VBlank0], U64_MAX); svcClearEvent(gspEvents[GSPEVENT_VBlank0]); currentTick = svcGetSystemTick(); diff = currentTick - lastTick; if(diff > CTR_CPU_TICKS_PER_SECOND) { fps = (float)frames * ((float) CTR_CPU_TICKS_PER_SECOND / (float) diff); lastTick = currentTick; frames = 0; } // extern u32 __linear_heap_size; // extern u32 gpuCmdBufOffset; // extern u32 __heap_size; // printf("0x%08X 0x%08X 0x%08X\r", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree() +0x3FF) & ~0x3FF); // printf("fps: %8.4f frames: %i (%X)\r", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); printf("fps: %8.4f frames: %i\r", fps, total_frames++); fflush(stdout); rarch_perf_init(&ctrframe_f, "ctrframe_f"); retro_perf_start(&ctrframe_f); if (ctr->should_resize) ctr_update_viewport(ctr); ctrGuSetMemoryFill(true, (u32*)CTR_GPU_FRAMEBUFFER, 0x00000000, (u32*)(CTR_GPU_FRAMEBUFFER + CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * sizeof(uint32_t)), 0x201, (u32*)CTR_GPU_DEPTHBUFFER, 0x00000000, (u32*)(CTR_GPU_DEPTHBUFFER + CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * sizeof(uint32_t)), 0x201); GPUCMD_SetBufferOffset(0); if (width > ctr->texture_width) width = ctr->texture_width; if (height > ctr->texture_height) height = ctr->texture_height; if(frame) { if(((((u32)(frame)) >= 0x14000000 && ((u32)(frame)) < 0x40000000)) /* frame in linear memory */ && !((u32)frame & 0x7F) /* 128-byte aligned */ && !((pitch) & 0xF)) /* 16-byte aligned */ { /* can copy the buffer directly with the GPU */ ctrGuCopyImage(false, frame, pitch / (ctr->rgb32? 4: 2), height, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, false, ctr->texture_swizzled, ctr->texture_width, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, true); } else { int i; uint8_t *dst = (uint8_t*)ctr->texture_linear; const uint8_t *src = frame; for (i = 0; i < height; i++) { memcpy(dst, src, width * (ctr->rgb32? 4: 2)); dst += ctr->texture_width * (ctr->rgb32? 4: 2); src += pitch; } GSPGPU_FlushDataCache(ctr->texture_linear, ctr->texture_width * ctr->texture_height * (ctr->rgb32? 4: 2)); ctrGuCopyImage(false, ctr->texture_linear, ctr->texture_width, ctr->texture_height, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, false, ctr->texture_swizzled, ctr->texture_width, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, true); } } ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->texture_swizzled), ctr->texture_width, ctr->texture_height, (ctr->smooth? GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) : GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST)) | GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE), ctr->rgb32 ? GPU_RGBA8: GPU_RGB565); ctr->frame_coords->u = width; ctr->frame_coords->v = height; GSPGPU_FlushDataCache(ctr->frame_coords, sizeof(ctr_vertex_t)); ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords)); ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->scale_vector, 1); /* ARGB --> RGBA */ if (ctr->rgb32) { GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0), GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, 0), GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_G, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MODULATE, GPU_MODULATE, 0x0000FF); GPU_SetTexEnv(1, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_PREVIOUS), GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_B, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MULTIPLY_ADD, GPU_MODULATE, 0x00FF00); GPU_SetTexEnv(2, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_PREVIOUS), GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_ALPHA, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MULTIPLY_ADD, GPU_MODULATE, 0xFF0000); } GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); /* restore */ if (ctr->rgb32) { GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0), GPU_TEVSOURCES(GPU_TEXTURE0, GPU_PRIMARY_COLOR, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MODULATE, GPU_MODULATE, 0xFFFFFFFF); GPU_SetTexEnv(1, GPU_PREVIOUS,GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(2, GPU_PREVIOUS,GPU_PREVIOUS, 0, 0, 0, 0, 0); } if (ctr->menu_texture_enable) { GSPGPU_FlushDataCache(ctr->menu.texture_linear, ctr->menu.texture_width * ctr->menu.texture_height * sizeof(uint16_t)); ctrGuCopyImage(false, ctr->menu.texture_linear, ctr->menu.texture_width, ctr->menu.texture_height, CTRGU_RGBA4444,false, ctr->menu.texture_swizzled, ctr->menu.texture_width, CTRGU_RGBA4444, true); ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->menu.texture_swizzled), ctr->menu.texture_width, ctr->menu.texture_height, GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) | GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE), GPU_RGBA4); ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->menu.frame_coords)); ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->menu.scale_vector, 1); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); } GPU_FinishDrawing(); GPUCMD_Finalize(); ctrGuFlushAndRun(true); ctrGuDisplayTransfer(true, CTR_GPU_FRAMEBUFFER, 240,400, CTRGU_RGBA8, gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), 240,400,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); gfxSwapBuffersGpu(); retro_perf_stop(&ctrframe_f); return true; }
void Update(float delta) { ActivityManager::current->dispatchUpdate(delta); u32 kDown = hidKeysDown(); u32 kHeld = hidKeysHeld(); u32 kUp = hidKeysUp(); if (kDown != 0) ActivityManager::current->dispatchKeyPressed(kDown); if (kUp != 0) ActivityManager::current->dispatchKeyReleased(kUp); touchPosition touch; hidTouchRead(&touch); if ((!focused) && (kDown & KEY_TOUCH)) { focused = nullptr; // Find an element to focus // Get last group auto group = RootLayerGroup; while (group && group->next) { group = group->next; } while (group) { focused = group->find([&](auto element) { return element->bounds.contains(touch.px, touch.py) && element->onTouchStart && element->onTouchStart(touch.px, touch.py); }); if (focused) break; group = group->prev; } if (focused) { printf("Focused on element %p\n", focused); startTouch = touch; lastTouch = touch; tapValid = true; } } else if (focused) { if (kUp & KEY_TOUCH) { // On key up touch is invalid (0, 0) if (tapValid && focused->onTap) { // Tap is invalid if it ever strays away from the 5px requirement focused->onTap(lastTouch.px, lastTouch.py); } if (focused->onTouchEnd) { focused->onTouchEnd(lastTouch.px, lastTouch.py); } focused = nullptr; } else { if (tapValid) { s32 touchDiffX = ((s32)startTouch.px)-((s32)lastTouch.px); s32 touchDiffY = ((s32)startTouch.py)-((s32)lastTouch.py); if (std::abs(touchDiffX+touchDiffY) > 7) { // ~5 pixels away in each possible direction tapValid = false; } } // Only send onTouchMove if we are not eligible for onTap if (!tapValid) { if (focused->onTouchMove) { focused->onTouchMove(touch.px, touch.py); } } lastTouch = touch; } } }
void bank(u8* mainbuf, int game) { FILE *fptr = fopen("/3ds/data/PKSM/bank/bank.bin", "rt"); fseek(fptr, 0, SEEK_END); u32 size = ftell(fptr); if (size % (30 * PKMNLENGTH)) { fclose(fptr); infoDisp("Bank.bin has a bad size!"); return; } u8 *bankbuf = (u8*)malloc(size * sizeof(u8)); if (bankbuf == NULL) { fclose(fptr); free(bankbuf); return; } rewind(fptr); fread(bankbuf, size, 1, fptr); fclose(fptr); bool isSeen = false; bool bufferizedfrombank = false; bool isBufferized = false; int saveBox = 0, bankBox = 0; int currentEntry = 30; int coordinate[2] = {0, 0}; u8* pkmn = (u8*)malloc(PKMNLENGTH * sizeof(u8)); memset(pkmn, 0, PKMNLENGTH); while (aptMainLoop()) { hidScanInput(); touchPosition touch; hidTouchRead(&touch); if (hidKeysDown() & KEY_B) { if (isBufferized) { if (bufferizedfrombank) memcpy(&bankbuf[coordinate[0] * 30 * PKMNLENGTH + coordinate[1] * PKMNLENGTH], pkmn, PKMNLENGTH); else setPkmn(mainbuf, coordinate[0], coordinate[1], pkmn, game); memset(pkmn, 0, PKMNLENGTH); isBufferized = false; } else break; } if (hidKeysDown() & KEY_DRIGHT) if (currentEntry < 59) currentEntry++; if (hidKeysDown() & KEY_DLEFT) if (currentEntry > 0) currentEntry--; if (hidKeysDown() & KEY_DUP) if (currentEntry >= 6) currentEntry -= 6; if (hidKeysDown() & KEY_DDOWN) if (currentEntry <= 53) currentEntry += 6; if (hidKeysDown() & KEY_R) { if (currentEntry < 30) { if (bankBox < size / (30 * PKMNLENGTH) - 1) bankBox++; else if (bankBox == size / (30 * PKMNLENGTH) - 1) bankBox = 0; } else { if (saveBox < ((game < 4) ? 30 : 31)) saveBox++; else if (saveBox == ((game < 4) ? 30 : 31)) saveBox = 0; } } if (hidKeysDown() & KEY_L) { if (currentEntry < 30) { if (bankBox > 0) bankBox--; else if (bankBox == 0) bankBox = size / (30 * PKMNLENGTH) - 1; } else { if (saveBox > 0) saveBox--; else if (saveBox == 0) saveBox = (game < 4) ? 30 : 31; } } if (hidKeysDown() & KEY_TOUCH) { if (touch.px > 7 && touch.px < 23 && touch.py > 17 && touch.py < 37) { if (saveBox > 0) saveBox--; else if (saveBox == 0) saveBox = (game < 4) ? 30 : 31; } if (touch.px > 185 && touch.px < 201 && touch.py > 17 && touch.py < 37) { if (saveBox < ((game < 4) ? 30 : 31)) saveBox++; else if (saveBox == ((game < 4) ? 30 : 31)) saveBox = 0; } if ((touch.px > 208 && touch.px < 317 && touch.py > 70 && touch.py < 101) && !(isBufferized)) { if (confirmDisp("Erase the selected box?")) { u8 tmp[PKMNLENGTH]; memset(tmp, 0, PKMNLENGTH); for (u32 i = 0; i < 30; i++) { if (currentEntry < 30) memcpy(&bankbuf[bankBox * 30 * PKMNLENGTH + i * PKMNLENGTH], tmp, PKMNLENGTH); else setPkmn(mainbuf, saveBox, i, tmp, game); } } } if (touch.px > 242 && touch.px < 285 && touch.py > 5 && touch.py < 25) { u8 buffer[PKMNLENGTH]; u8 temp[PKMNLENGTH]; memset(buffer, 0, PKMNLENGTH); memset(temp, 0, PKMNLENGTH); for (u32 i = 0; i < 30; i++) { getPkmn(mainbuf, saveBox, i, buffer, game); // getpkmn -> buffer memcpy(temp, &bankbuf[bankBox * 30 * PKMNLENGTH + i * PKMNLENGTH], PKMNLENGTH); // memcpy bank -> temp setPkmn(mainbuf, saveBox, i, temp, game); // setpkmn -> temp memcpy(&bankbuf[bankBox * 30 * PKMNLENGTH + i * PKMNLENGTH], buffer, PKMNLENGTH); // memcpy bank -> buffer } } if (touch.px > 280 && touch.px < 318 && touch.py > 210 && touch.py < 240) break; } if (hidKeysHeld() & KEY_TOUCH) { if (touch.px > 4 && touch.px < 38 && touch.py > 45 && touch.py < 75) currentEntry = 30; if (touch.px > 38 && touch.px < 72 && touch.py > 45 && touch.py < 75) currentEntry = 31; if (touch.px > 72 && touch.px < 106 && touch.py > 45 && touch.py < 75) currentEntry = 32; if (touch.px > 106 && touch.px < 140 && touch.py > 45 && touch.py < 75) currentEntry = 33; if (touch.px > 140 && touch.px < 174 && touch.py > 45 && touch.py < 75) currentEntry = 34; if (touch.px > 174 && touch.px < 208 && touch.py > 45 && touch.py < 75) currentEntry = 35; if (touch.px > 4 && touch.px < 38 && touch.py > 75 && touch.py < 105) currentEntry = 36; if (touch.px > 38 && touch.px < 72 && touch.py > 75 && touch.py < 105) currentEntry = 37; if (touch.px > 72 && touch.px < 106 && touch.py > 75 && touch.py < 105) currentEntry = 38; if (touch.px > 106 && touch.px < 140 && touch.py > 75 && touch.py < 105) currentEntry = 39; if (touch.px > 140 && touch.px < 174 && touch.py > 75 && touch.py < 105) currentEntry = 40; if (touch.px > 174 && touch.px < 208 && touch.py > 75 && touch.py < 105) currentEntry = 41; if (touch.px > 4 && touch.px < 38 && touch.py > 105 && touch.py < 135) currentEntry = 42; if (touch.px > 38 && touch.px < 72 && touch.py > 105 && touch.py < 135) currentEntry = 43; if (touch.px > 72 && touch.px < 106 && touch.py > 105 && touch.py < 135) currentEntry = 44; if (touch.px > 106 && touch.px < 140 && touch.py > 105 && touch.py < 135) currentEntry = 45; if (touch.px > 140 && touch.px < 174 && touch.py > 105 && touch.py < 135) currentEntry = 46; if (touch.px > 174 && touch.px < 208 && touch.py > 105 && touch.py < 135) currentEntry = 47; if (touch.px > 4 && touch.px < 38 && touch.py > 135 && touch.py < 165) currentEntry = 48; if (touch.px > 38 && touch.px < 72 && touch.py > 135 && touch.py < 165) currentEntry = 49; if (touch.px > 72 && touch.px < 106 && touch.py > 135 && touch.py < 165) currentEntry = 50; if (touch.px > 106 && touch.px < 140 && touch.py > 135 && touch.py < 165) currentEntry = 51; if (touch.px > 140 && touch.px < 174 && touch.py > 135 && touch.py < 165) currentEntry = 52; if (touch.px > 174 && touch.px < 208 && touch.py > 135 && touch.py < 165) currentEntry = 53; if (touch.px > 4 && touch.px < 38 && touch.py > 165 && touch.py < 195) currentEntry = 54; if (touch.px > 38 && touch.px < 72 && touch.py > 165 && touch.py < 195) currentEntry = 55; if (touch.px > 72 && touch.px < 106 && touch.py > 165 && touch.py < 195) currentEntry = 56; if (touch.px > 106 && touch.px < 140 && touch.py > 165 && touch.py < 195) currentEntry = 57; if (touch.px > 140 && touch.px < 174 && touch.py > 165 && touch.py < 195) currentEntry = 58; if (touch.px > 174 && touch.px < 208 && touch.py > 165 && touch.py < 195) currentEntry = 59; } if (((hidKeysDown() & KEY_Y) || (hidKeysDown() & KEY_TOUCH && touch.px > 208 && touch.px < 317 && touch.py > 43 && touch.py < 74)) && !isBufferized) { isSeen = true; u8 tmp[PKMNLENGTH]; memset(tmp, 0, PKMNLENGTH); if (currentEntry < 30) memcpy(tmp, &bankbuf[bankBox * 30 * PKMNLENGTH + currentEntry * PKMNLENGTH], PKMNLENGTH); else getPkmn(mainbuf, saveBox, currentEntry - 30, tmp, game); while (aptMainLoop() && getPokedexNumber(tmp)) { hidScanInput(); touchPosition touch; hidTouchRead(&touch); if ((hidKeysDown() & KEY_B) || (hidKeysDown() & KEY_TOUCH && touch.px > 280 && touch.px < 318 && touch.py > 210 && touch.py < 240)) break; printPKBank(bankbuf, mainbuf, tmp, game, currentEntry, saveBox, bankBox, isBufferized, isSeen); } isSeen = false; } if (hidKeysDown() & KEY_A) { if (isBufferized) { if (!(game < 4 && getPokedexNumber(pkmn) > 721 && currentEntry > 29)) { // prevent that gen7 stuff goes into gen6 save u8 tmp[PKMNLENGTH]; if ((bufferizedfrombank == (currentEntry < 30)) && (coordinate[0] == ((currentEntry < 30) ? bankBox : saveBox)) && (coordinate[1] == currentEntry)) memcpy(&bankbuf[bankBox * 30 * PKMNLENGTH + currentEntry * PKMNLENGTH], pkmn, PKMNLENGTH); else if ((!bufferizedfrombank == (currentEntry > 29)) && (coordinate[0] == ((currentEntry < 30) ? bankBox : saveBox)) && (coordinate[1] == currentEntry - 30)) setPkmn(mainbuf, saveBox, currentEntry - 30, pkmn, game); else if (currentEntry < 30) { memcpy(tmp, &bankbuf[bankBox * 30 * PKMNLENGTH + currentEntry * PKMNLENGTH], PKMNLENGTH); memcpy(&bankbuf[bankBox * 30 * PKMNLENGTH + currentEntry * PKMNLENGTH], pkmn, PKMNLENGTH); if (bufferizedfrombank) memcpy(&bankbuf[coordinate[0] * 30 * PKMNLENGTH + coordinate[1] * PKMNLENGTH], tmp, PKMNLENGTH); else setPkmn(mainbuf, coordinate[0], coordinate[1], tmp, game); } else { getPkmn(mainbuf, saveBox, currentEntry - 30, tmp, game); setPkmn(mainbuf, saveBox, currentEntry - 30, pkmn, game); if (bufferizedfrombank) memcpy(&bankbuf[coordinate[0] * 30 * PKMNLENGTH + coordinate[1] * PKMNLENGTH], tmp, PKMNLENGTH); else setPkmn(mainbuf, coordinate[0], coordinate[1], tmp, game); } memset(pkmn, 0, PKMNLENGTH); isBufferized = false; } } else { u8 tmp[PKMNLENGTH]; memset(tmp, 0, PKMNLENGTH); coordinate[0] = (currentEntry < 30) ? bankBox : saveBox; coordinate[1] = (currentEntry > 29) ? (currentEntry - 30) : currentEntry; if (currentEntry < 30) { memcpy(pkmn, &bankbuf[bankBox * 30 * PKMNLENGTH + currentEntry * PKMNLENGTH], PKMNLENGTH); memcpy(&bankbuf[bankBox * 30 * PKMNLENGTH + currentEntry * PKMNLENGTH], tmp, PKMNLENGTH); } else { getPkmn(mainbuf, saveBox, currentEntry - 30, pkmn, game); setPkmn(mainbuf, saveBox, currentEntry - 30, tmp, game); } isBufferized = true; bufferizedfrombank = (currentEntry < 30) ? true : false; } } printPKBank(bankbuf, mainbuf, pkmn, game, currentEntry, saveBox, bankBox, isBufferized, isSeen); } if (confirmDisp("Save bank.bin changes?")) { FILE *new = fopen("/3ds/data/PKSM/bank/bank.bin", "wb"); fwrite(bankbuf, 1, size, new); fclose(new); }
touchPosition InputManager::scanTouch() { touchPosition touch; hidTouchRead(&touch); return touch; }
int main() { touchPosition touch; sf2d_init(); sftd_init(); sftd_font *text = sftd_load_font_mem(Roboto_ttf, Roboto_ttf_size); sftd_font *title = sftd_load_font_mem(RobotoThin_ttf, RobotoThin_ttf_size); sf2d_texture *logo = sfil_load_PNG_buffer(logo_png, SF2D_PLACE_RAM); sf2d_texture *record = sfil_load_PNG_buffer(record_png, SF2D_PLACE_RAM); sf2d_texture *stop = sfil_load_PNG_buffer(stop_png, SF2D_PLACE_RAM); sf2d_set_clear_color(RGBA8(0xFA, 0xFA, 0xFA, 0xFF)); sharedmem = (u32*)memalign(0x1000, sharedmem_size); audiobuf = linearAlloc(audiobuf_size); MIC_Initialize(sharedmem, sharedmem_size, control, 0, 3, 1, 1);//See mic.h. // Threading stuff svcCreateEvent(&threadRequest,0); u32 *threadStack = memalign(32, STACKSIZE); svcCreateThread(&threadHandle, threadMic, 0, &threadStack[STACKSIZE/4], 0x3f, 0); while(aptMainLoop()) { hidScanInput(); hidTouchRead(&touch); u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; // break in order to return to hbmenu sf2d_start_frame(GFX_TOP, GFX_LEFT); sf2d_draw_texture(logo, 60, 70); sftd_draw_text(title, 177, 80, RGBA8(0, 0, 0, 222), 40, "Audio"); sftd_draw_text(title, 175, 120, RGBA8(0, 0, 0, 222), 40, "Recorder"); sf2d_end_frame(); sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); sf2d_draw_texture(record, 85, 85); sf2d_draw_texture(stop, 165, 85); sf2d_end_frame(); svcSignalEvent(threadRequest); if(print == 1) { sf2d_start_frame(GFX_TOP, GFX_LEFT); sf2d_draw_texture(logo, 60, 70); sftd_draw_text(title, 177, 80, RGBA8(0, 0, 0, 222), 40, "Audio"); sftd_draw_text(title, 175, 120, RGBA8(0, 0, 0, 222), 40, "Recorder"); sftd_draw_text(text, 130, 209, RGBA8(0, 0, 0, 222), 16, "Recording audio..."); sf2d_end_frame(); } if(recording == 2) { sf2d_start_frame(GFX_TOP, GFX_LEFT); sf2d_draw_texture(logo, 60, 70); sftd_draw_text(title, 177, 80, RGBA8(0, 0, 0, 222), 40, "Audio"); sftd_draw_text(title, 175, 120, RGBA8(0, 0, 0, 222), 40, "Recorder"); sftd_draw_text(text, 130, 209, RGBA8(0, 0, 0, 222), 16, "Saving audio..."); sf2d_end_frame(); } sf2d_swapbuffers(); } MIC_Shutdown(); sftd_free_font(text); sftd_free_font(title); sf2d_free_texture(logo); sf2d_free_texture(record); sf2d_free_texture(stop); // tell thread to exit threadExit = true; // signal the thread svcSignalEvent(threadRequest); // give it time to exit svcSleepThread(10000000ULL); // close handles and free allocated stack svcCloseHandle(threadRequest); svcCloseHandle(threadHandle); free(threadStack); free(sharedmem); linearFree(audiobuf); linearFree(nomute_audiobuf); sf2d_fini(); sftd_fini(); return 0; }
int main() { // Set the random seed based on the time srand(time(NULL)); sf2d_init(); sf2d_set_clear_color(RGBA8(0x40, 0x40, 0x40, 0xFF)); sf2d_texture *tex1 = sf2d_create_texture_mem_RGBA8(dice_img.pixel_data, dice_img.width, dice_img.height, TEXFMT_RGBA8, SF2D_PLACE_RAM); sf2d_texture *tex2 = sf2d_create_texture_mem_RGBA8(citra_img.pixel_data, citra_img.width, citra_img.height, TEXFMT_RGBA8, SF2D_PLACE_RAM); float rad = 0.0f; u16 touch_x = 320/2; u16 touch_y = 240/2; touchPosition touch; circlePosition circle; u32 held; while (aptMainLoop()) { hidScanInput(); hidCircleRead(&circle); held = hidKeysHeld(); if (held & KEY_START) { break; } else if (held & KEY_TOUCH) { hidTouchRead(&touch); touch_x = touch.px; touch_y = touch.py; } else if (held & (KEY_L | KEY_R)) { sf2d_set_clear_color(RGBA8(rand()%255, rand()%255, rand()%255, 255)); } sf2d_start_frame(GFX_TOP, GFX_LEFT); sf2d_draw_rectangle_rotate(260, 20, 40, 40, RGBA8(0xFF, 0xFF, 0x00, 0xFF), -2.0f*rad); sf2d_draw_rectangle(20, 60, 40, 40, RGBA8(0xFF, 0x00, 0x00, 0xFF)); sf2d_draw_rectangle(5, 5, 30, 30, RGBA8(0x00, 0xFF, 0xFF, 0xFF)); sf2d_draw_texture_rotate(tex1, 400/2 + circle.dx, 240/2 - circle.dy, rad); sf2d_end_frame(); sf2d_start_frame(GFX_BOTTOM, GFX_LEFT); sf2d_draw_rectangle_rotate(190, 160, 70, 60, RGBA8(0xFF, 0xFF, 0xFF, 0xFF), 3.0f*rad); sf2d_draw_rectangle(30, 100, 40, 60, RGBA8(0xFF, 0x00, 0xFF, 0xFF)); sf2d_draw_texture_rotate(tex2, touch_x, touch_y, -rad); sf2d_draw_rectangle(160-15 + cosf(rad)*50.0f, 120-15 + sinf(rad)*50.0f, 30, 30, RGBA8(0x00, 0xFF, 0xFF, 0xFF)); sf2d_draw_fill_circle(40, 40, 35, RGBA8(0x00, 0xFF, 0x00, 0xFF)); sf2d_end_frame(); rad += 0.2f; sf2d_swapbuffers(); } sf2d_free_texture(tex1); sf2d_free_texture(tex2); sf2d_fini(); return 0; }
Touch inputGetTouch() { touchPosition pos; hidTouchRead(&pos); return {pos.px, pos.py}; }
void tickMenu(int menu){ switch(menu){ case MENU_SETTINGS: if(!bindOpt){ if(!selBut){ if (k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=21;} if (k_down.clicked){ ++currentSelection; if(currentSelection > 21)currentSelection=0;} if (k_left.clicked){ left = true;} if (k_right.clicked){ left = false;} } else { if (k_left.clicked){ if(left)switchGameBut(true,keys[currentSelection]); else switchMenuBut(true,keys[currentSelection]); } else if (k_right.clicked) { if(left)switchGameBut(false,keys[currentSelection]); else switchMenuBut(false,keys[currentSelection]); } } if (k_accept.clicked) selBut = !selBut; if (k_decline.clicked){ bindOpt = true; curSaveSel = 0; } } else { if (k_up.clicked){ --curSaveSel; if(curSaveSel < 0)curSaveSel=2;} if (k_down.clicked){ ++curSaveSel; if(curSaveSel > 2)curSaveSel=0;} if (k_decline.clicked){ bindOpt = false; errorBut = -1; } if (k_accept.clicked){ switch(curSaveSel){ case 0: // Exit and save if(checkPropButtons() == -1){ k_up.input = keyProp[0]; k_down.input = keyProp[1]; k_left.input = keyProp[2]; k_right.input = keyProp[3]; k_attack.input = keyProp[4]; k_menu.input = keyProp[5]; k_pause.input = keyProp[6]; k_accept.input = keyProp[7]; k_decline.input = keyProp[8]; k_delete.input = keyProp[9]; FILE *fs=fopen("btnSave.bin","wb"); fwrite(keyProp,sizeof(int),9,fs); fclose(fs); currentSelection = 2; currentMenu = MENU_TITLE; errorBut = -1; } else errorBut = checkPropButtons(); break; case 1: // Exit and DON'T save currentSelection = 2; currentMenu = MENU_TITLE; errorBut = -1; break; case 2: // reset defaults keyProp[0] = KEY_DUP | KEY_CPAD_UP | KEY_CSTICK_UP; keyProp[1] = KEY_DDOWN | KEY_CPAD_DOWN | KEY_CSTICK_DOWN; keyProp[2] = KEY_DLEFT | KEY_CPAD_LEFT | KEY_CSTICK_LEFT; keyProp[3] = KEY_DRIGHT | KEY_CPAD_RIGHT | KEY_CSTICK_RIGHT; keyProp[4] = KEY_A | KEY_B | KEY_L | KEY_ZR; keyProp[5] = KEY_X | KEY_Y | KEY_R | KEY_ZL; keyProp[6] = KEY_START; keyProp[7] = KEY_A; keyProp[8] = KEY_B; keyProp[9] = KEY_X; bindOpt = false; errorBut = -1; break; } } } break; case MENU_PAUSED: if(!areYouSure && !areYouSureSave){ if(pauseSaveDisplayTimer > 0) --pauseSaveDisplayTimer; if (k_pause.clicked) currentMenu = MENU_NONE; if (k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=2;} if (k_down.clicked){ ++currentSelection; if(currentSelection > 2)currentSelection=0;} if (k_accept.clicked){ switch(currentSelection){ case 0: currentMenu = MENU_NONE; break; case 1: areYouSureSave = true; break; case 2: areYouSure = true; break; } } } else if(areYouSureSave) { if (k_accept.clicked){ pauseSaveDisplayTimer = 60; saveCurrentWorld(currentFileName, &eManager, &player, (u8*)map, (u8*)data); areYouSureSave = false; areYouSure = false; } else if (k_decline.clicked){ areYouSureSave = false; areYouSure = false; } } else { if (k_accept.clicked){ areYouSure = false; areYouSureSave = false; sf2d_set_clear_color(0xFF); currentSelection = 0; currentMenu = MENU_TITLE; } else if (k_decline.clicked){ areYouSure = false; areYouSureSave = false; } } break; case MENU_INVENTORY: if (k_menu.clicked || k_decline.clicked){ currentMenu = MENU_NONE; player.p.activeItem = &noItem; player.p.isCarrying = false; } if (k_accept.clicked){ // Select item from inventory if(player.p.inv->lastSlot!=0){ median = player.p.inv->items[curInvSel]; // create copy of item. removeItemFromInventory(curInvSel, player.p.inv); // remove original pushItemToInventoryFront(median, player.p.inv); // add copy to front player.p.activeItem = &player.p.inv->items[0]; // active item = copy. if(player.p.activeItem->id > 27) player.p.isCarrying = true; else player.p.isCarrying = false; } currentMenu = MENU_NONE; } if (k_up.clicked){ --curInvSel; if(curInvSel < 0)curInvSel=player.p.inv->lastSlot-1;} if (k_down.clicked){ ++curInvSel; if(curInvSel > player.p.inv->lastSlot-1)curInvSel=0;} break; case MENU_CRAFTING: if (k_menu.clicked || k_decline.clicked) currentMenu = MENU_NONE; if (k_accept.clicked){ int newslot = player.p.activeItem->slotNum + 1; if(craftItem(currentRecipes, ¤tRecipes->recipes[curInvSel], player.p.inv)){ playSound(snd_craft); if(player.p.activeItem != &noItem)player.p.activeItem = &player.p.inv->items[newslot]; } } if (k_up.clicked){ --curInvSel; if(curInvSel < 0)curInvSel=currentRecipes->size-1;} if (k_down.clicked){ ++curInvSel; if(curInvSel > currentRecipes->size-1)curInvSel=0;} break; case MENU_WIN: if (k_accept.clicked){ sf2d_set_clear_color(0xFF); currentMenu = MENU_TITLE; saveCurrentWorld(currentFileName, &eManager, &player, (u8*)map, (u8*)data); } break; case MENU_LOSE: if (k_accept.clicked){ sf2d_set_clear_color(0xFF); currentMenu = MENU_TITLE; } break; case MENU_ABOUT: if (k_decline.clicked) currentMenu = MENU_TITLE; break; case MENU_CONTAINER: if (k_menu.clicked || k_decline.clicked)currentMenu = MENU_NONE; if (k_left.clicked) { curChestEntity->entityFurniture.r = 0; int tmp = curInvSel; curInvSel = curChestEntity->entityFurniture.oSel; curChestEntity->entityFurniture.oSel = tmp; } if (k_right.clicked) { curChestEntity->entityFurniture.r = 1; int tmp = curInvSel; curInvSel = curChestEntity->entityFurniture.oSel; curChestEntity->entityFurniture.oSel = tmp; } Inventory* i1 = curChestEntity->entityFurniture.r == 1 ? player.p.inv : curChestEntity->entityFurniture.inv; Inventory* i2 = curChestEntity->entityFurniture.r == 0 ? player.p.inv : curChestEntity->entityFurniture.inv; int len = i1->lastSlot; if (curInvSel < 0) curInvSel = 0; if (curInvSel >= len) curInvSel = len - 1; if (k_up.clicked) --curInvSel; if (k_down.clicked) ++curInvSel; if (len == 0) curInvSel = 0; if (curInvSel < 0) curInvSel += len; if (curInvSel >= len) curInvSel -= len; if(k_accept.clicked && len > 0){ Item* pullItem = &i1->items[curInvSel]; Item pushItem = newItem(pullItem->id,pullItem->countLevel); pushItem.chestPtr = pullItem->chestPtr; pushItemToInventoryFront(pushItem, i2); if(i2 == player.p.inv){ int newslot = player.p.activeItem->slotNum + 1; player.p.activeItem = &player.p.inv->items[newslot]; } else if(pullItem == player.p.activeItem){ player.p.activeItem = &noItem; } removeItemFromCurrentInv(pullItem); if (curInvSel >= i1->lastSlot) curInvSel = i1->lastSlot - 1; } break; case MENU_LOADGAME: if(!enteringName && !areYouSure){ // World select if (k_decline.clicked){ currentMenu = MENU_TITLE; currentSelection = 0; } if (k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection = worldFileCount;} if (k_down.clicked){ ++currentSelection; if(currentSelection > worldFileCount)currentSelection=0;} if(k_delete.clicked){ if(currentSelection < worldFileCount) areYouSure = true; } if(k_accept.clicked){ if(currentSelection == worldFileCount){ enteringName = true; } else { memset(¤tFileName, 0, 255); // reset currentFileName sprintf(currentFileName,"%s.wld",fileNames[currentSelection]); playSound(snd_test); initGame = 1; currentMenu = MENU_NONE; } } } else if (areYouSure){ if (k_decline.clicked || k_delete.clicked) areYouSure = false; if (k_accept.clicked){ sprintf(currentFileName,"%s.wld",fileNames[currentSelection]); remove(currentFileName); readFiles(); enteringName = false; areYouSure = false; memset(¤tFileName, 0, 255); // reset currentFileName } }else { // Enter new world name. if(k_decline.clicked) enteringName = false; if(k_accept.clicked && errorFileName == 0){ errorFileName = checkFileNameForErrors(); if(errorFileName == 0){ // If no errors are found with the filename, then start a new game! memset(¤tFileName, 0, 255); // reset currentFileName sprintf(currentFileName,"%s.wld",fileNames[worldFileCount]); currentMenu = MENU_NONE; playSound(snd_test); initGame = 2; ++worldFileCount; } } touchPosition touch; hidTouchRead(&touch); if((touch.px != 0 || touch.py != 0) && touchDelay == 0){ if(!isTouching)doTouchButton(touch); } else if(touch.px == 0 || touch.py == 0) isTouching = false; if(touchDelay > 0) --touchDelay; } break; case MENU_TITLE: if (k_up.clicked){ --currentSelection; if(currentSelection < 0)currentSelection=4;} if (k_down.clicked){ ++currentSelection; if(currentSelection > 4)currentSelection=0;} if(k_accept.clicked){ switch(currentSelection){ case 0: currentMenu = MENU_LOADGAME; readFiles(); currentSelection = 0; enteringName = false; areYouSure = false; break; case 2: keyProp[0] = k_up.input; keyProp[1] = k_down.input; keyProp[2] = k_left.input; keyProp[3] = k_right.input; keyProp[4] = k_attack.input; keyProp[5] = k_menu.input; keyProp[6] = k_pause.input; keyProp[7] = k_accept.input; keyProp[8] = k_decline.input; keyProp[9] = k_delete.input; left = true; selBut = false; bindOpt = false; currentSelection = 0; currentMenu = MENU_SETTINGS; break; case 3: currentMenu = MENU_ABOUT; break; case 4: quitGame = true; break; } } break; } }
int inputScan(lua_State *L) { // love.keyboard.scan() hidScanInput(); kDown = hidKeysDown(); kHeld = hidKeysHeld(); kUp = hidKeysUp(); hidTouchRead(&touch); if (kDown & BIT(20)) { // BIT(20) == "touch" -- love.mousepressed() touchIsDown = true; lua_getfield(L, LUA_GLOBALSINDEX, "love"); lua_getfield(L, -1, "mousepressed"); lua_remove(L, -2); if (!lua_isnil(L, -1)) { lua_pushinteger(L, touch.px); lua_pushinteger(L, touch.py); lua_pushstring(L, "l"); lua_call(L, 3, 0); lastPosx = touch.px; lastPosy = touch.py; } } if (kUp & BIT(20)) { // love.mousereleased() touchIsDown = false; lua_getfield(L, LUA_GLOBALSINDEX, "love"); lua_getfield(L, -1, "mousereleased"); lua_remove(L, -2); if (!lua_isnil(L, -1)) { lua_pushinteger(L, touch.px); lua_pushinteger(L, touch.py); lua_pushstring(L, "l"); lua_call(L, 3, 0); } } int i; for (i = 0; i < 32; i++) { // love.keypressed() if (kDown & BIT(i)) { if (strcmp(dsNames[i], "touch") != 0) { // Touch shouldn't be returned in love.keypressed. lua_getfield(L, LUA_GLOBALSINDEX, "love"); lua_getfield(L, -1, "keypressed"); lua_remove(L, -2); if (!lua_isnil(L, -1)) { lua_pushstring(L, dsNames[i]); lua_pushboolean(L, 0); lua_call(L, 2, 0); } } } } for (i = 0; i < 32; i++) { // love.keyreleased() if (kUp & BIT(i)) { if (strcmp(dsNames[i], "touch") != 0) { // Touch shouldn't be returned in love.keypressed. lua_getfield(L, LUA_GLOBALSINDEX, "love"); lua_getfield(L, -1, "keyreleased"); lua_remove(L, -2); if (!lua_isnil(L, -1)) { lua_pushstring(L, dsNames[i]); lua_call(L, 1, 0); } } } } return 0; }
static bool ctr_frame(void* data, const void* frame, unsigned width, unsigned height, uint64_t frame_count, unsigned pitch, const char* msg) { uint32_t diff; static uint64_t currentTick,lastTick; ctr_video_t *ctr = (ctr_video_t*)data; settings_t *settings = config_get_ptr(); static float fps = 0.0; static int total_frames = 0; static int frames = 0; static struct retro_perf_counter ctrframe_f = {0}; uint32_t state_tmp; touchPosition state_tmp_touch; extern bool select_pressed; if (!width || !height) { gspWaitForEvent(GSPGPU_EVENT_VBlank0, true); return true; } if(!aptMainLoop()) { command_event(CMD_EVENT_QUIT, NULL); return true; } if (select_pressed) { command_event(CMD_EVENT_QUIT, NULL); return true; } state_tmp = hidKeysDown(); hidTouchRead(&state_tmp_touch); if((state_tmp & KEY_TOUCH) && (state_tmp_touch.py < 120)) { Handle lcd_handle; u8 not_2DS; extern PrintConsole* currentConsole; gfxBottomFramebuffers[0] = ctr->lcd_buttom_on ? (u8*)ctr->empty_framebuffer: (u8*)currentConsole->frameBuffer; CFGU_GetModelNintendo2DS(¬_2DS); if(not_2DS && srvGetServiceHandle(&lcd_handle, "gsp::Lcd") >= 0) { u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = ctr->lcd_buttom_on? 0x00120040: 0x00110040; cmdbuf[1] = 2; svcSendSyncRequest(lcd_handle); svcCloseHandle(lcd_handle); } ctr->lcd_buttom_on = !ctr->lcd_buttom_on; } svcWaitSynchronization(gspEvents[GSPGPU_EVENT_P3D], 20000000); svcClearEvent(gspEvents[GSPGPU_EVENT_P3D]); svcWaitSynchronization(gspEvents[GSPGPU_EVENT_PPF], 20000000); svcClearEvent(gspEvents[GSPGPU_EVENT_PPF]); frames++; if (ctr->vsync) svcWaitSynchronization(gspEvents[GSPGPU_EVENT_VBlank0], U64_MAX); svcClearEvent(gspEvents[GSPGPU_EVENT_VBlank0]); currentTick = svcGetSystemTick(); diff = currentTick - lastTick; if(diff > CTR_CPU_TICKS_PER_SECOND) { fps = (float)frames * ((float) CTR_CPU_TICKS_PER_SECOND / (float) diff); lastTick = currentTick; frames = 0; } //#define CTR_INSPECT_MEMORY_USAGE #ifdef CTR_INSPECT_MEMORY_USAGE uint32_t ctr_get_stack_usage(void); void ctr_linear_get_stats(void); extern u32 __linear_heap_size; extern u32 __heap_size; MemInfo mem_info; PageInfo page_info; u32 query_addr = 0x08000000; printf(PRINTFPOS(0,0)); while (query_addr < 0x40000000) { svcQueryMemory(&mem_info, &page_info, query_addr); printf("0x%08X --> 0x%08X (0x%08X) \n", mem_info.base_addr, mem_info.base_addr + mem_info.size, mem_info.size); query_addr = mem_info.base_addr + mem_info.size; if(query_addr == 0x1F000000) query_addr = 0x30000000; } // static u32* dummy_pointer; // if(total_frames == 500) // dummy_pointer = malloc(0x2000000); // if(total_frames == 1000) // free(dummy_pointer); printf("========================================"); printf("0x%08X 0x%08X 0x%08X\n", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree())); printf("fps: %8.4f frames: %i (%X)\n", fps, total_frames++, (__linear_heap_size - linearSpaceFree())); printf("========================================"); u32 app_memory = *((u32*)0x1FF80040); u64 mem_used; svcGetSystemInfo(&mem_used, 0, 1); printf("total mem : 0x%08X \n", app_memory); printf("used: 0x%08X free: 0x%08X \n", (u32)mem_used, app_memory - (u32)mem_used); static u32 stack_usage = 0; extern u32 __stack_bottom; if(!(total_frames & 0x3F)) stack_usage = ctr_get_stack_usage(); printf("stack total:0x%08X used: 0x%08X\n", 0x10000000 - __stack_bottom, stack_usage); printf("========================================"); ctr_linear_get_stats(); printf("========================================"); #else printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++); #endif fflush(stdout); performance_counter_init(&ctrframe_f, "ctrframe_f"); performance_counter_start(&ctrframe_f); if (ctr->should_resize) ctr_update_viewport(ctr); ctrGuSetMemoryFill(true, (u32*)CTR_TOP_FRAMEBUFFER, 0x00000000, (u32*)(CTR_TOP_FRAMEBUFFER + 2 * CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * sizeof(uint32_t)), 0x201, (u32*)CTR_GPU_DEPTHBUFFER, 0x00000000, (u32*)(CTR_GPU_DEPTHBUFFER + CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * sizeof(uint32_t)), 0x201); GPUCMD_SetBufferOffset(0); if (width > ctr->texture_width) width = ctr->texture_width; if (height > ctr->texture_height) height = ctr->texture_height; if(frame) { if(((((u32)(frame)) >= 0x14000000 && ((u32)(frame)) < 0x40000000)) /* frame in linear memory */ && !((u32)frame & 0x7F) /* 128-byte aligned */ && !(pitch & 0xF) /* 16-byte aligned */ && (pitch > 0x40)) { /* can copy the buffer directly with the GPU */ // GSPGPU_FlushDataCache(frame, pitch * height); ctrGuSetCommandList_First(true,(void*)frame, pitch * height,0,0,0,0); ctrGuCopyImage(true, frame, pitch / (ctr->rgb32? 4: 2), height, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, false, ctr->texture_swizzled, ctr->texture_width, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, true); } else { int i; uint8_t *dst = (uint8_t*)ctr->texture_linear; const uint8_t *src = frame; for (i = 0; i < height; i++) { memcpy(dst, src, width * (ctr->rgb32? 4: 2)); dst += ctr->texture_width * (ctr->rgb32? 4: 2); src += pitch; } GSPGPU_FlushDataCache(ctr->texture_linear, ctr->texture_width * ctr->texture_height * (ctr->rgb32? 4: 2)); ctrGuCopyImage(false, ctr->texture_linear, ctr->texture_width, ctr->texture_height, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, false, ctr->texture_swizzled, ctr->texture_width, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, true); } ctr->frame_coords->u0 = 0; ctr->frame_coords->v0 = 0; ctr->frame_coords->u1 = width; ctr->frame_coords->v1 = height; GSPGPU_FlushDataCache(ctr->frame_coords, sizeof(ctr_vertex_t)); ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->scale_vector, 1); } ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->texture_swizzled), ctr->texture_width, ctr->texture_height, (ctr->smooth? GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) : GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST)) | GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE), ctr->rgb32 ? GPU_RGBA8: GPU_RGB565); ctr_check_3D_slider(ctr); /* ARGB --> RGBA */ if (ctr->rgb32) { GPU_SetTexEnv(0, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0), GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, 0), GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_G, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MODULATE, GPU_MODULATE, 0x0000FF); GPU_SetTexEnv(1, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_PREVIOUS), GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_B, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MULTIPLY_ADD, GPU_MODULATE, 0x00FF00); GPU_SetTexEnv(2, GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_PREVIOUS), GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0), GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_ALPHA, 0, 0), GPU_TEVOPERANDS(0, 0, 0), GPU_MULTIPLY_ADD, GPU_MODULATE, 0xFF0000); } GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); if (ctr->video_mode == CTR_VIDEO_MODE_3D) { if (ctr->menu_texture_enable) { ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(&ctr->frame_coords[1])); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(&ctr->frame_coords[2])); } else { ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords)); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); } GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER_RIGHT), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); } else ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords)); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); /* restore */ if (ctr->rgb32) { GPU_SetTexEnv(0, GPU_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0); GPU_SetTexEnv(1, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); GPU_SetTexEnv(2, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0); } if (ctr->menu_texture_enable) { GSPGPU_FlushDataCache(ctr->menu.texture_linear, ctr->menu.texture_width * ctr->menu.texture_height * sizeof(uint16_t)); ctrGuCopyImage(false, ctr->menu.texture_linear, ctr->menu.texture_width, ctr->menu.texture_height, CTRGU_RGBA4444,false, ctr->menu.texture_swizzled, ctr->menu.texture_width, CTRGU_RGBA4444, true); ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->menu.texture_swizzled), ctr->menu.texture_width, ctr->menu.texture_height, GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) | GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE), GPU_RGBA4); ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->menu.scale_vector, 1); GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->menu.frame_coords)); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); if (ctr->video_mode == CTR_VIDEO_MODE_3D) { GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER_RIGHT), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); } } GPU_FinishDrawing(); GPUCMD_Finalize(); ctrGuFlushAndRun(true); ctrGuDisplayTransfer(true, CTR_TOP_FRAMEBUFFER, 240, ctr->video_mode == CTR_VIDEO_MODE_800x240 ? 800 : 400, CTRGU_RGBA8, gfxTopLeftFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); if ((ctr->video_mode == CTR_VIDEO_MODE_400x240) || (ctr->video_mode == CTR_VIDEO_MODE_3D)) ctrGuDisplayTransfer(true, CTR_TOP_FRAMEBUFFER_RIGHT, 240, 400, CTRGU_RGBA8, gfxTopRightFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); // Swap buffers : ctr->current_buffer_top ^= 1; extern GSPGPU_FramebufferInfo topFramebufferInfo; extern u8* gfxSharedMemory; extern u8 gfxThreadID; topFramebufferInfo.active_framebuf=ctr->current_buffer_top; topFramebufferInfo.framebuf0_vaddr=(u32*)gfxTopLeftFramebuffers[ctr->current_buffer_top]; if(ctr->video_mode == CTR_VIDEO_MODE_800x240) { topFramebufferInfo.framebuf1_vaddr=(u32*)(gfxTopLeftFramebuffers[ctr->current_buffer_top] + 240 * 3); topFramebufferInfo.framebuf_widthbytesize = 240 * 3 * 2; } else { topFramebufferInfo.framebuf1_vaddr=(u32*)gfxTopRightFramebuffers[ctr->current_buffer_top]; topFramebufferInfo.framebuf_widthbytesize = 240 * 3; } topFramebufferInfo.format=(1<<8)|(1<<5)|GSP_BGR8_OES; topFramebufferInfo.framebuf_dispselect=ctr->current_buffer_top; topFramebufferInfo.unk=0x00000000; u8* framebufferInfoHeader=gfxSharedMemory+0x200+gfxThreadID*0x80; GSPGPU_FramebufferInfo* framebufferInfo=(GSPGPU_FramebufferInfo*)&framebufferInfoHeader[0x4]; framebufferInfoHeader[0x0] ^= 1; framebufferInfo[framebufferInfoHeader[0x0]] = topFramebufferInfo; framebufferInfoHeader[0x1]=1; performance_counter_stop(&ctrframe_f); return true; }