Beispiel #1
0
void hidWaitForEvent(HID_Event id, bool nextEvent)
{
	if(id>=HIDEVENT_MAX)return;

	if (nextEvent)
		svcClearEvent(hidEvents[id]);
	svcWaitSynchronization(hidEvents[id], U64_MAX);
	if (!nextEvent)
		svcClearEvent(hidEvents[id]);
}
Beispiel #2
0
void aptAppletClosed(void)
{
	aptAppletUtility_Exit_RetToApp(1);

	GSPGPU_AcquireRight(0x0);
	GSPGPU_RestoreVramSysArea();

	svcClearEvent(aptStatusEvent);
	aptSetStatus(APP_RUNNING);
	svcClearEvent(aptStatusEvent);
}
Beispiel #3
0
bool udsWaitConnectionStatusEvent(bool nextEvent, bool wait)
{
	bool ret = true;
	u64 delayvalue = U64_MAX;

	if(!wait)delayvalue = 0;

	if(nextEvent)svcClearEvent(__uds_connectionstatus_event);

	if(svcWaitSynchronization(__uds_connectionstatus_event, delayvalue)!=0 && !wait)ret = false;

	if(!nextEvent)svcClearEvent(__uds_connectionstatus_event);

	return ret;
}
Beispiel #4
0
bool udsWaitDataAvailable(const udsBindContext *bindcontext, bool nextEvent, bool wait)
{
	bool ret = true;
	u64 delayvalue = U64_MAX;

	if(!wait)delayvalue = 0;

	if(nextEvent)svcClearEvent(bindcontext->event);

	if(svcWaitSynchronization(bindcontext->event, delayvalue)!=0 && !wait)ret = false;

	if(!nextEvent)svcClearEvent(bindcontext->event);

	return ret;
}
Beispiel #5
0
static inline void ndspWaitForIrq(void)
{
	LightLock_Lock(&ndspMutex);
	svcWaitSynchronization(irqEvent, U64_MAX);
	svcClearEvent(irqEvent);
	LightLock_Unlock(&ndspMutex);
}
Beispiel #6
0
void gspEventThreadMain(void *arg)
{
	while (gspRunEvents)
	{
		svcWaitSynchronization(gspEvent, U64_MAX);
		svcClearEvent(gspEvent);

		while (true)
		{
			int curEvt = popInterrupt();

			if (curEvt == -1)
				break;

			if (curEvt < GSPGPU_EVENT_MAX)
			{
				if (gspEventCb[curEvt])
				{
					ThreadFunc func = gspEventCb[curEvt];
					if (gspEventCbOneShot[curEvt])
						gspEventCb[curEvt] = NULL;
					func(gspEventCbData[curEvt]);
				}
				LightEvent_Signal(&gspEvents[curEvt]);
				do
					__ldrex(&gspLastEvent);
				while (__strex(&gspLastEvent, curEvt));
				svcArbitrateAddress(__sync_get_arbiter(), (u32)&gspLastEvent, ARBITRATION_SIGNAL, 1, 0);
				gspEventCounts[curEvt]++;
			}
		}
	}
}
Beispiel #7
0
void aptEventHandler(void *arg)
{
	bool runThread = true;

	while(runThread)
	{
		s32 syncedID = 0;
		svcWaitSynchronizationN(&syncedID, aptEvents, 3, 0, U64_MAX);
		svcClearEvent(aptEvents[syncedID]);
		switch(syncedID)
		{
			// Event 0 means we got a signal from NS (home button, power button etc).
			case 0x0:
				__handle_notification();
				break;
			// Event 1 means we got an incoming parameter.
			case 0x1:
				runThread = __handle_incoming_parameter();
				break;
			// Event 2 means we should exit the thread.
			case 0x2:
				runThread = false;
				break;
		}
	}
}
Beispiel #8
0
static void ndspSync(void)
{
	if (bSleeping)
	{
		svcWaitSynchronization(sleepEvent, U64_MAX);
		svcClearEvent(sleepEvent);
	}

	ndspWaitForIrq();
	if (bDspReady)
	{
		int counter = ndspGetCounter(~ndspFrameId & 1);
		if (counter)
		{
			int next = (counter + 1) & 0xFFFF;
			ndspFrameId = next ? next : 2;
			ndspBufferId = ndspFrameId & 1;
			ndspiReadChnState();
			//memcpy(dspVar9Backup, dspVars[9][ndspBufferId], sizeof(dspVar9Backup));
			ndspUpdateCapture((s16*)ndspVars[6][ndspBufferId], 160);
			droppedFrames += *((u16*)ndspVars[5][ndspBufferId] + 1);
		}
		bNeedsSync = false;
	}
}
Beispiel #9
0
void aptAppStarted(void)
{
	u8 buf1[4], buf2[4];

	aptSetStatus(APP_RUNNING);
	svcClearEvent(aptStatusEvent);

	if(!aptIsCrippled())
	{
		memset(buf1, 0, 4);

		buf1[0] = 0x10;
		aptOpenSession();
		APT_AppletUtility(NULL, 0x7, 0x4, buf1, 0x1, buf2);
		aptCloseSession();

		buf1[0] = 0x00;
		aptOpenSession();
		APT_AppletUtility(NULL, 0x4, 0x1, buf1, 0x1, buf2);
		aptCloseSession();

		aptOpenSession();
		APT_AppletUtility(NULL, 0x4, 0x1, buf1, 0x1, buf2);
		aptCloseSession();
	}
}
Beispiel #10
0
void LuaThread(void *arg) {
	// Run Lua interpreter
	// Load the boot.lua file onto the stack as a chunk
	luaL_loadfile(L, "lua/bios.lua");

	// Continuously resume the chunk until it finishes or errors
	int args = 0;
	while(LuaBox_Running) {
		int state = lua_resume(L, NULL, args);
		args = 0;
		if(state == LUA_OK) break; // Execution complete
		if(state != LUA_YIELD) {
			// Error of some kind
			printf("# Uncaught lua error (code %i)\nTraceback:",  state);
			luaL_dostring(L, "print(debug.traceback())");
			break;
		}

		// Handle yield below
		svcWaitSynchronization(LuaBox_EventMutex, U64_MAX); // Attempt to lock event list

		if(LuaBox_EventList == NULL) {
			// Release the event lock and wait for a signal
			svcReleaseMutex(LuaBox_EventMutex);
			svcWaitSynchronization(LuaBox_EventSignal, U64_MAX); // Wait for another thread to signal us an event
			svcClearEvent(LuaBox_EventSignal); // Clear the event
			svcWaitSynchronization(LuaBox_EventMutex, U64_MAX); // Attempt to lock event list
		}

		struct LuaBox_Event * ev = LuaBox_EventList; // Grab end of list

		if(ev != NULL) {
			switch(ev->type) {
				case LUABOX_EVENT_CHAR:
					lua_pushstring(L, "char"); // Push string 'char' onto stack
					char *charPressed = malloc(2);
					charPressed[0] = (char)ev->value;
					charPressed[1] = 0x0;
					lua_pushstring(L, charPressed);
					free(charPressed);
					args = 2;
					break;
				default:
					break;
			}

			struct LuaBox_Event * next = ev->next;
			free(ev);
			LuaBox_EventList = next;
		}

		// Release the event lock
		svcReleaseMutex(LuaBox_EventMutex);
	}

	// Execution complete past this point
	printf("# bios.lua execution complete\n");
	while (1) {	svcSleepThread(10000000ULL);}
}
Beispiel #11
0
bool hidTryWaitForEvent(HID_Event id, s64 nanoseconds){
    if(R_DESCRIPTION(svcWaitSynchronization(hidEvents[id], nanoseconds))==RD_TIMEOUT){
        return false;
    } else{
        svcClearEvent(hidEvents[id]);
        return true;
    }
        
}
Beispiel #12
0
void threadMain(void *arg) {

	while(1) {
		svcWaitSynchronization(threadRequest, U64_MAX);
		svcClearEvent(threadRequest);		

		if(threadExit) svcExitThread();

		threadcount++;
	}
}
Beispiel #13
0
void conn_main() {
    APP_STATUS status;
    u32 it = 0;
    int ret = 0;
    int first = 1;
    int exiting = 0;

    while((status = aptGetStatus()) != APP_EXITING)
    {
        hidScanInput();
        consoleClear(&bot);

        print(&bot, "frame: %08x\n", it);
        print(&bot, "ret: %08x\n", ret);
        print(&bot, "last_cmd: %02x\n", last_cmd & 0xFF);

        if(!first) {
            u32 bytes_read = 0;

            while(1) {
                ret = recv(sock, &cmd, sizeof(cmd), 0);
                if(ret < 0) {
                    if(ret == -EWOULDBLOCK)
                        continue;
                    break;
                }

                bytes_read += ret;
                if(bytes_read == sizeof(cmd)) {
                    svcSignalEvent(new_cmd_event);
                    svcWaitSynchronization(cmd_done_event, U64_MAX);
                    svcClearEvent(cmd_done_event);

                    send(sock, &resp, sizeof(resp), 0);

                    if(last_cmd_result == 0xDEAD)
                        exiting = 1;
                    break;
                }
            }
        }

        first = 0;
        it++;

        if(enable_draw)
            renderFrame(); 

        u32 keys = hidKeysUp();
        if(keys & KEY_A || exiting)
            break;     
    }
}
Beispiel #14
0
void cmd_thread_func() {
    while(1) {
        svcWaitSynchronization(new_cmd_event, U64_MAX);
        svcClearEvent(new_cmd_event);

        if(thread_exit) svcExitThread();

        last_cmd = cmd.type;
        last_cmd_result = execute_cmd(sock, &cmd);

        svcSignalEvent(cmd_done_event);
    }
}
Beispiel #15
0
void threadMain(void *arg)
{
	ThreadArgs *const args = arg;
	while (1)
	{
		svcWaitSynchronization(*args->threadRequest, U64_MAX);
		svcClearEvent(*args->threadRequest);

		if (*args->shouldExit)
			svcExitThread();

		(*args->count)++;
	}
}
Beispiel #16
0
static void svchax_gspwn(u32 dst, u32 src, u32 size, u8* flush_buffer)
{
   extern Handle gspEvents[GSPEVENT_MAX];

   memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
   GSPGPU_InvalidateDataCache(dst, size);
   GSPGPU_FlushDataCache(src, size);
   memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);

   svcClearEvent(gspEvents[GSPEVENT_PPF]);
	GX_TextureCopy(src, 0, dst, 0, size, 8);
   svcWaitSynchronization(gspEvents[GSPEVENT_PPF], U64_MAX);

   memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000);
}
Beispiel #17
0
// 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;
		}
	}
}
Beispiel #18
0
void Handler::run() {
	lock();
	running = true;
	while (running) { // TODO: volatile bool for running state
		if (!handleMessageUnsafe()) {
			// If there is a message on the queue, find the reason why it didn't execute
			auto message = peek();
			u64 time = osGetTime();
			if (message && message->when > time) {
				u64 when = message->when;
				unlock();
				svcWaitSynchronization(eventHandle, (when-time)*1000000LL);
			} else {
				unlock();
				svcWaitSynchronization(eventHandle, UINT64_MAX);
			}

			lock();
		}
		svcClearEvent(eventHandle);
	}
  unlock();
}
Beispiel #19
0
void aptAppletStarted(void)
{
	u8 buf1[4], buf2[4];

	memset(buf1, 0, 4);

	// Set status to SUSPENDED.
	svcClearEvent(aptStatusEvent);
	aptSetStatus(APP_SUSPENDED);

	aptOpenSession();
	APT_SendCaptureBufferInfo(0x20, __ns_capinfo);
	aptCloseSession();

	aptOpenSession();
	APT_ReplySleepQuery(currentAppId, 0x0);
	aptCloseSession();

	aptOpenSession();
	APT_StartLibraryApplet(__apt_launchapplet_appID, __apt_launchapplet_inhandle, __apt_launchapplet_parambuf, __apt_launchapplet_parambufsize);
	aptCloseSession();

	buf1[0]=0x00;
	aptOpenSession();
	APT_AppletUtility(NULL, 0x4, 0x1, buf1, 0x1, buf2);
	aptCloseSession();

	aptOpenSession();
	APT_NotifyToWait(currentAppId);
	aptCloseSession();

	buf1[0]=0x00;
	aptOpenSession();
	APT_AppletUtility(NULL, 0x4, 0x1, buf1, 0x1, buf2);
	aptCloseSession();
}
Beispiel #20
0
Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize)
{
	Result ret=0;
	u8 tmp=0;

	u8 buf1[4];
	u8 buf2[4];

	aptOpenSession();
	APT_ReplySleepQuery(currentAppId, 0);
	aptCloseSession();

	aptOpenSession();
	ret=APT_PrepareToStartLibraryApplet(appID);
	aptCloseSession();
	if(R_FAILED(ret))return ret;

	memset(buf1, 0, 4);
	aptOpenSession();
	APT_AppletUtility(NULL, 0x4, 0x1, buf1, 0x1, buf2);
	aptCloseSession();

	while(1)
	{
		aptOpenSession();
		ret=APT_IsRegistered(appID, &tmp);
		aptCloseSession();
		if(R_FAILED(ret))return ret;

		if(tmp!=0)break;
	}

	aptCallHook(APTHOOK_ONSUSPEND);

	__apt_launchapplet_appID = appID;
	__apt_launchapplet_inhandle = inhandle;
	__apt_launchapplet_parambuf = parambuf;
	__apt_launchapplet_parambufsize = parambufsize;

	// Set status to SUSPENDED.
	svcClearEvent(aptStatusEvent);
	aptSetStatus(APP_SUSPENDED);

	// Save Vram
	GSPGPU_SaveVramSysArea();

	// Capture screen.
	memset(__ns_capinfo, 0, 0x20);

	aptInitCaptureInfo(__ns_capinfo);

	// Send capture-screen info to the library applet.
	aptOpenSession();
	APT_SendParameter(currentAppId, appID, 0x20, __ns_capinfo, 0x0, 0x2);
	aptCloseSession();

	// Release GSP module.
	GSPGPU_ReleaseRight();

	return 0;
}
Beispiel #21
0
void conn_main() {
    APP_STATUS status;
    u32 it = 0;
    int ret = 0;
    int first = 1;
    int exiting = 0;

    while((status = aptGetStatus()) != APP_EXITING)
    {
        hidScanInput();
        consoleClear(&bot);

        print(&bot, "frame: %08x\n", it);
        print(&bot, "ret: %08x\n", ret);
        print(&bot, "last_cmd: %02x\n", last_cmd & 0xFF);
        int i;for(i=0;i<GSPEVENT_MAX;i++)print(&bot, "%d : %08X\n", i, gspEventCounts[i]);

        if(!first) {
            u32 bytes_read = 0;

            while(1) {
                ret = recv(sock, &cmd, 4, 0);
                if(ret < 0) {
                    if(ret == -EWOULDBLOCK)
                        continue;
                    break;
                }

                if(!cmd.numarg)cmd.numarg=7;
                u32 size=cmd.numarg*4;
                ret = recv(sock, &cmd.args, size, 0);
                if(ret < 0) {
                    if(ret == -EWOULDBLOCK)
                        continue;
                    break;
                }

                bytes_read += ret;
                if(bytes_read == size) {
                    svcSignalEvent(new_cmd_event);
                    svcWaitSynchronization(cmd_done_event, U64_MAX);
                    svcClearEvent(cmd_done_event);

                    size=4+4*resp.numarg;
                    send(sock, &resp, size, 0);

                    if(last_cmd_result == 0xDEAD)
                        exiting = 1;
                    break;
                }
            }
        }

        first = 0;
        it++;

        if(enable_draw)
            renderFrame(); 

        u32 keys = hidKeysUp();
        if(keys & KEY_A || exiting)
            break;     
    }
}
Beispiel #22
0
static bool ctr_frame(void* data, const void* frame,
      unsigned width, unsigned height, unsigned pitch, const char* msg)
{
   ctr_video_t* ctr = (ctr_video_t*)data;
   settings_t* settings = config_get_ptr();

   static uint64_t currentTick,lastTick;
   static float fps = 0.0;
   static int total_frames = 0;
   static int frames = 0;

   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;
   }

   svcWaitSynchronization(gspEvents[GSPEVENT_P3D], 20000000);
   svcClearEvent(gspEvents[GSPEVENT_P3D]);
   svcWaitSynchronization(gspEvents[GSPEVENT_PPF], 20000000);
   svcClearEvent(gspEvents[GSPEVENT_PPF]);

   gfxSwapBuffersGpu();   
   frames++;

   if (ctr->vsync)
      svcWaitSynchronization(gspEvents[GSPEVENT_VBlank0], U64_MAX);

   svcClearEvent(gspEvents[GSPEVENT_VBlank0]);

   currentTick = svcGetSystemTick();
   uint32_t 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;
   }

   printf("fps: %8.4f frames: %i\r", fps, total_frames++);
   fflush(stdout);

   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)) < 0x1c000000)) /* 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 / 2, height, CTRGU_RGB565, false,
                        ctr->texture_swizzled, ctr->texture_width, CTRGU_RGB565,  true);
      }
      else
      {
         int i;
         uint16_t* dst = (uint16_t*)ctr->texture_linear;
         const uint8_t* src = frame;
         for (i = 0; i < height; i++)
         {
            memcpy(dst, src, width * sizeof(uint16_t));
            dst += ctr->texture_width;
            src += pitch;
         }
         GSPGPU_FlushDataCache(NULL, ctr->texture_linear,
                               ctr->texture_width * ctr->texture_height * sizeof(uint16_t));

         ctrGuCopyImage(false, ctr->texture_linear, ctr->texture_width, ctr->menu.texture_height, CTRGU_RGB565, false,
                        ctr->texture_swizzled, ctr->texture_width, CTRGU_RGB565,  true);

      }

   }


   ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->texture_swizzled), ctr->texture_width, ctr->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_RGB565);

   ctr->frame_coords->u = width;
   ctr->frame_coords->v = height;
   GSPGPU_FlushDataCache(NULL, (u8*)ctr->frame_coords, sizeof(ctr_vertex_t));

   ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords));
   ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->scale_vector, 1);
   GPU_DrawArray(GPU_UNKPRIM, 1);

   if (ctr->menu_texture_enable)
   {

      GSPGPU_FlushDataCache(NULL, 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(1, (float*)&ctr->menu.scale_vector, 1);
      GPU_DrawArray(GPU_UNKPRIM, 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);

   ctr->frame_count++;

   return true;
}
Beispiel #23
0
static void __handle_notification(void) {
	APT_Signal type;
	Result ret=0;

	// Get notification type.
	aptOpenSession();
	ret = APT_InquireNotification(currentAppId, &type);
	aptCloseSession();
	if(R_FAILED(ret)) return;

	_aptDebug(1, type);

	switch(type)
	{
	case APTSIGNAL_HOMEBUTTON:
	case APTSIGNAL_POWERBUTTON:
		// The main thread should call aptReturnToMenu() when the status gets set to this.
		if(aptGetStatus() == APP_RUNNING)
		{
			aptOpenSession();
			APT_ReplySleepQuery(currentAppId, 0x0);
			aptCloseSession();
		
			if(type == APTSIGNAL_HOMEBUTTON)  aptSetStatusPower(0);
			if(type == APTSIGNAL_POWERBUTTON) aptSetStatusPower(1);
			aptSetStatus(APP_SUSPENDING);
		}
		break;

	case APTSIGNAL_PREPARESLEEP:
		// Reply to sleep-request.
		aptStatusBeforeSleep = aptGetStatus();
		aptSetStatus(APP_PREPARE_SLEEPMODE);
		svcWaitSynchronization(aptSleepSync, U64_MAX);
		svcClearEvent(aptSleepSync);
		
		aptOpenSession();
		APT_ReplySleepQuery(currentAppId, 0x1);
		aptCloseSession();
		break;

	case APTSIGNAL_ENTERSLEEP:
		if(aptGetStatus() == APP_PREPARE_SLEEPMODE)
		{
			// Report into sleep-mode.
			aptSetStatus(APP_SLEEPMODE);
			
			aptOpenSession();
			APT_ReplySleepNotificationComplete(currentAppId);
			aptCloseSession();
		}
		break;

	// Leaving sleep-mode.
	case APTSIGNAL_WAKEUP:
		if(aptGetStatus() == APP_SLEEPMODE)
		{
			if(aptStatusBeforeSleep == APP_RUNNING)GSPGPU_SetLcdForceBlack(0);

			// Restore old aptStatus.
			aptSetStatus(aptStatusBeforeSleep);
		}
		break;

	default:
		break;
	}
}
Beispiel #24
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(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(&not_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;
}
Beispiel #25
0
void aptReturnToMenu(void)
{
	NS_APPID menu_appid;
	u32 tmp0 = 1, tmp1 = 0;

	if(aptIsCrippled())
	{
		svcClearEvent(aptStatusEvent);
		aptSetStatus(APP_EXITING);
		return;
	}

	// This is only executed when ret-to-menu was triggered via the home-button, not the power-button.
	if(aptGetStatusPower() == 0)
	{
		aptOpenSession();
		APT_AppletUtility(NULL, 0x6, 0x4, (u8*)&tmp0, 0x1, (u8*)&tmp1);
		aptCloseSession();
	}

	// Set status to SUSPENDED.
	__apt_launchapplet_appID = 0;
	svcClearEvent(aptStatusEvent);
	aptSetStatus(APP_SUSPENDED);

	// Prepare for return to menu
	aptOpenSession();
	APT_PrepareToJumpToHomeMenu();
	aptCloseSession();

	// Save Vram
	GSPGPU_SaveVramSysArea();

	// Capture screen.
	memset(__ns_capinfo, 0, 0x20);

	aptInitCaptureInfo(__ns_capinfo);

	menu_appid = aptGetMenuAppID();

	// Send capture-screen info to menu.
	aptOpenSession();
	APT_SendParameter(currentAppId, menu_appid, 0x20, __ns_capinfo, 0x0, 0x10);
	aptCloseSession();

	aptOpenSession();
	APT_SendCaptureBufferInfo(0x20, __ns_capinfo);
	aptCloseSession();

	// Release GSP module.
	GSPGPU_ReleaseRight();

	// Jump to menu!
	aptOpenSession();
	APT_JumpToHomeMenu(0x0, 0x0, 0x0);
	aptCloseSession();

	// Wait for return to application.
	aptOpenSession();
	APT_NotifyToWait(currentAppId);
	aptCloseSession();

	// This is only executed when ret-to-menu was triggered via the home-button, not the power-button.
	if(aptGetStatusPower() == 0)
	{
		tmp0 = 0;
		aptOpenSession();
		APT_AppletUtility(NULL, 0x4, 0x1, (u8*)&tmp0, 0x1, (u8*)&tmp1);
		aptCloseSession();
	}

	aptWaitStatusEvent();
}
Beispiel #26
0
void streamWAV(void* arg){

	// Fetching cachePackage struct from main thread
	cachePackage* pack = (cachePackage*)arg;
	while(1) {
	
		// Waiting for updateStream event
		svcWaitSynchronization(updateStream, U64_MAX);
		svcClearEvent(updateStream);
		
		// Close the thread if closeStream event received
		if(closeStream){
			closeStream = false;
			svcExitThread();
		}
		
		// Check if the current stream is paused or not
		Music* src = pack->song;
		Socket* Client = pack->client;
		if (src->isPlaying){
		
			// Check if a free buffer is available
			if (src->wavebuf2 == NULL){
			
				// Check if file reached EOF
				if (src->audio_pointer >= src->size){
				
					// Check if playback ended
					if (!ndspChnIsPlaying(src->ch)){
						src->isPlaying = false;
						src->tick = (osGetTime()-src->tick);
					}
					
					continue;
				}
				
				// Swap audiobuffers
				u8* tmp = src->audiobuf;
				src->audiobuf = src->audiobuf2;
				src->audiobuf2 = tmp;
				
				// Create a new block for DSP service
				u32 bytesRead;
				src->wavebuf2 = (ndspWaveBuf*)calloc(1,sizeof(ndspWaveBuf));
				createDspBlock(src->wavebuf2, src->bytepersample, src->mem_size, 0, (u32*)src->audiobuf);
				populatePurgeTable(src, src->wavebuf2);
				ndspChnWaveBufAdd(src->ch, src->wavebuf2);
				socketSend(Client, "exec2:0000");
				u32 processedBytes = 0;
				netSize = 0;
				while (netSize <= 0) heapRecv(Client, 2048);
				while (processedBytes < (src->mem_size / 2)){
					if (netSize <= 0){
							heapRecv(Client, 2048);
							continue;
					}
					if (strncmp((char*)netBuffer, "EOF", 3) == 0) break;
					memcpy(&streamCache[songPointer + processedBytes], netBuffer, netSize);
					processedBytes = processedBytes + netSize;
					heapRecv(Client, 2048);
				}
				memcpy(src->audiobuf, &streamCache[songPointer], src->mem_size);
				if (songPointer == 0) songPointer = src->mem_size / 2;
				else songPointer = 0;
				src->audio_pointer = src->audio_pointer + src->mem_size;
				
				// Changing endianess if Big Endian
				if (src->big_endian){
					u64 i = 0;
					while (i < src->mem_size){
						u8 tmp = src->audiobuf[i];
						src->audiobuf[i] = src->audiobuf[i+1];
						src->audiobuf[i+1] = tmp;
						i=i+2;	
					}
				}
			
			}
			
			// Check if a block playback is finished
			u32 curSample = ndspChnGetSamplePos(src->ch);
			if (src->lastCheck > curSample){
			
				// Prepare next block
				src->wavebuf = src->wavebuf2;
				src->wavebuf2 = NULL;
			
			}
			
			// Update sample position tick
			src->lastCheck = curSample;
		
		}
	}		
}
Beispiel #27
0
void streamMusic(void* arg)
{
    clearBottomScreen();
    debug("play_buffer start\n");
    stream_filename* strm_file = static_cast<stream_filename*>(arg);
    VGMSTREAM* vgmstream = strm_file->stream;

    if (!vgmstream)
        return;

	int channel = 0;
	ndspSetOutputMode(NDSP_OUTPUT_STEREO);
	for (int i = 0; i < vgmstream->channels; i++)
    {
        ndspChnReset(channel + i);
        ndspChnSetInterp(channel + i, NDSP_INTERP_LINEAR);
        ndspChnSetRate(channel + i, vgmstream->sample_rate / vgmstream->channels);
        ndspChnSetFormat(channel + i, NDSP_FORMAT_STEREO_PCM16);
    }

    std::vector<ndspWaveBuf> waveBufs1(vgmstream->channels);
    std::vector<ndspWaveBuf> waveBufs2(vgmstream->channels);
    for (auto& waveBuf : waveBufs1)
        memset(&waveBuf, 0, sizeof(ndspWaveBuf));
    for (auto& waveBuf : waveBufs2)
        memset(&waveBuf, 0, sizeof(ndspWaveBuf));

    debug("play_buffer signal produce\n");
    svcSignalEvent(bufferReadyProduceRequest);
    // Wait for 2 buffers to play
    debug("play_buffer wait data 1\n");
    svcWaitSynchronization(bufferReadyConsumeRequest, U64_MAX);
    svcClearEvent(bufferReadyConsumeRequest);

    debug("play_buffer signal produce\n");
    svcSignalEvent(bufferReadyProduceRequest);
    debug("play_buffer wait data 2\n");
    svcWaitSynchronization(bufferReadyConsumeRequest, U64_MAX);
    svcClearEvent(bufferReadyConsumeRequest);

    // Play it
    debug("play_buffer play\n");
    playSoundChannels(channel, playBuffer1.samples, false, playBuffer1.channels, waveBufs1);
    playSoundChannels(channel, playBuffer2.samples, false, playBuffer2.channels, waveBufs2);
    stream_buffer* buffer = &playBuffer2;
    stream_buffer* playingBuf = &playBuffer1;
    std::vector<ndspWaveBuf>* waveBuf = &waveBufs2;
    std::vector<ndspWaveBuf>* playingWaveBuf = &waveBufs1;

    debug("play_buffer signal produce\n");
    svcSignalEvent(bufferReadyProduceRequest);

    while (runThreads)
    {
        if (playingWaveBuf->at(0).status == NDSP_WBUF_DONE) {
            debug("play_buffer wait data\n");
            // Wait for sound data here
            svcWaitSynchronization(bufferReadyConsumeRequest, U64_MAX);
            svcClearEvent(bufferReadyConsumeRequest);

            // Flip buffers
            if (buffer == &playBuffer1)
            {
                buffer = &playBuffer2;
                playingBuf = &playBuffer1;
                waveBuf = &waveBufs2;
                playingWaveBuf = &waveBufs1;
            }
            else
            {
                buffer = &playBuffer1;
                playingBuf = &playBuffer2;
                waveBuf = &waveBufs1;
                playingWaveBuf = &waveBufs2;
            }


            debug("play_buffer play\n");
            playSoundChannels(channel, buffer->samples, false, buffer->channels, *waveBuf);
            debug("play_buffer signal produce\n");
            svcSignalEvent(bufferReadyProduceRequest);
        }
    }

    for (int i = 0; i < vgmstream->channels; i++)
    {
        ndspChnWaveBufClear(channel + i);
    }
    debug("play_buffer done\n");

}
Beispiel #28
0
bool stream_file(const std::string& filename)
{
    if (filename.empty())
    {
        print("No file selected\n");
        return true;
    }

    VGMSTREAM* vgmstream = init_vgmstream(filename.c_str());
    if (!vgmstream)
    {
        print("Bad file %s\n", filename.c_str());
        return true;
    }

    const int channels = vgmstream->channels;
    u32 buffer_size = max_samples * vgmstream->channels * sizeof(sample);

    rawSampleBuffer = static_cast<sample*>(linearAlloc(buffer_size));
    sample* buffer = static_cast<sample*>(linearAlloc(buffer_size));
    sample* buffer2 = static_cast<sample*>(linearAlloc(buffer_size));
    playBuffer1.samples = max_samples;
    playBuffer2.samples = max_samples;
    for (int i = 0; i < channels; i++)
    {
        playBuffer1.channels.push_back(buffer + i * max_samples);
        playBuffer2.channels.push_back(buffer2 + i * max_samples);
    }

    stream_filename strm_file;
    strm_file.filename = filename;
    strm_file.stream = vgmstream;

    runThreads = true;

    s32 prio = 0;
    Thread musicThread;
    Thread produceThread;
    svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
    musicThread = threadCreate(streamMusic, &strm_file, 4 * 1024, prio-1, -2, false);
    produceThread = threadCreate(decodeThread, &strm_file, 4 * 1024, prio-1, -2, false);

    bool ret = false;
    while (aptMainLoop())
    {
        hidScanInput();
        u32 kDown = hidKeysDown();
        if (kDown & KEY_START || kDown & KEY_B)
        {
            ret = kDown & KEY_START;
            break;
        }
        gfxFlushBuffers();
        gfxSwapBuffers();

        gspWaitForVBlank();
    }

    runThreads = false;
    svcSignalEvent(bufferReadyProduceRequest);
    svcSignalEvent(bufferReadyConsumeRequest);
    threadJoin(musicThread, U64_MAX);
    threadJoin(produceThread, U64_MAX);
    threadFree(musicThread);
    threadFree(produceThread);
    svcClearEvent(bufferReadyConsumeRequest);
    svcClearEvent(bufferReadyProduceRequest);


    linearFree(rawSampleBuffer);
    linearFree(buffer);
    linearFree(buffer2);
    playBuffer1.channels.clear();
    playBuffer2.channels.clear();

    close_vgmstream(vgmstream);

    return ret;
}
Beispiel #29
0
void decodeThread(void* arg)
{
    debug("decode_buffer start\n");
    stream_filename* strm_file = static_cast<stream_filename*>(arg);
    VGMSTREAM* vgmstream = strm_file->stream;
    std::string& filename = strm_file->filename;

    if (!vgmstream)
        return;

    const int channels = vgmstream->channels;
    const u32 stream_samples_amount = get_vgmstream_play_samples(1, 0, 0, vgmstream);
    u32 current_sample_pos = 0;
    stream_buffer* buffer = &playBuffer1;

    while (runThreads)
    {
        debug("decode_buffer wait produce\n");
        // Wait for signal to make another stream
        svcWaitSynchronization(bufferReadyProduceRequest, U64_MAX);
        svcClearEvent(bufferReadyProduceRequest);

        u32 toget = max_samples;

        if (!vgmstream->loop_flag)
        {
            if (current_sample_pos >= stream_samples_amount)
                break;
            if (current_sample_pos + toget > stream_samples_amount)
                toget = stream_samples_amount - current_sample_pos;
        }

        debug("decode_buffer decode %d\n", toget);
        // TODO modify render_vgmstream to return not decode channel data sequentially in the buffer passed in.
        render_vgmstream(rawSampleBuffer, toget, vgmstream);

        debug("decode_buffer detangle\n");
        // Detangle audio data...
        buffer->samples = toget;
        for (u32 i = 0; i < max_samples; i++)
        {
            for (int j = 0; j < channels; j++)
            {
                buffer->channels[j][i] = rawSampleBuffer[i * channels + j];
            }
        }

        debug("decode_buffer signal consume\n");
        // Ready to play
        svcSignalEvent(bufferReadyConsumeRequest);

        clearTopScreen();
        print("\x1b[1;0HCurrently playing %s\nPress B to choose another song\nPress Start to exit", filename.c_str());
        print("\x1b[29;0HPLAYING %.4lf %.4lf\n", (float)current_sample_pos / vgmstream->sample_rate, (float)stream_samples_amount / vgmstream->sample_rate);
        current_sample_pos += toget;

        // Flip buffers
        if (buffer == &playBuffer1)
            buffer = &playBuffer2;
        else
            buffer = &playBuffer1;

        debug("decode_buffer decode more\n");
    }
    debug("decode_buffer done\n");
}
Beispiel #30
0
void aptWaitStatusEvent(void)
{
	svcWaitSynchronization(aptStatusEvent, U64_MAX);
	svcClearEvent(aptStatusEvent);
}