+char *psp_get_status_line(void)
+{
+ static char buff[64];
+ int ret, bat_percent, bat_time;
+ pspTime time;
+
+ ret = sceRtcGetCurrentClockLocalTime(&time);
+ bat_percent = scePowerGetBatteryLifePercent();
+ bat_time = scePowerGetBatteryLifeTime();
+ if (ret < 0 || bat_percent < 0 || bat_time < 0) return NULL;
+
+ snprintf(buff, sizeof(buff), "%02i:%02i bat: %3i%%", time.hour, time.minutes, bat_percent);
+ if (!scePowerIsPowerOnline())
+ snprintf(buff+strlen(buff), sizeof(buff)-strlen(buff), " (%i:%02i)", bat_time/60, bat_time%60);
+ return buff;
+}
+
+/* alt logging */
+#define LOG_FILE "log.txt"
+
+#ifndef LPRINTF_STDIO
+typedef struct _log_entry
+{
+ char buff[256];
+ struct _log_entry *next;
+} log_entry;
+
+static log_entry *le_root = NULL;
+#endif
+
+void lprintf_f(const char *fmt, ...)
+{
+ va_list vl;
+
+#ifdef LPRINTF_STDIO
+ va_start(vl, fmt);
+ vprintf(fmt, vl);
+ va_end(vl);
+#else
+ static SceUID logfd = -1;
+ char buff[256];
+ log_entry *le, *le1;
+
+ if (logfd == -2) return; // disabled
+
+ va_start(vl, fmt);
+ vsnprintf(buff, sizeof(buff), fmt, vl);
+ va_end(vl);
+
+ // note: this is still unsafe code
+ if (main_thread_id != sceKernelGetThreadId())
+ {
+ le = malloc(sizeof(*le));
+ if (le == NULL) return;
+ le->next = NULL;
+ strcpy(le->buff, buff);
+ if (le_root == NULL) le_root = le;
+ else {
+ for (le1 = le_root; le1->next != NULL; le1 = le1->next);
+ le1->next = le;
+ }
+ return;
+ }
+
+ logfd = sceIoOpen(LOG_FILE, PSP_O_WRONLY|PSP_O_APPEND, 0777);
+ if (logfd < 0) {
+ logfd = -2;
+ return;
+ }
+
+ if (le_root != NULL)
+ {
+ le1 = le_root;
+ le_root = NULL;
+ sceKernelDelayThread(1000);
+ while (le1 != NULL) {
+ le = le1;
+ le1 = le->next;
+ sceIoWrite(logfd, le->buff, strlen(le->buff));
+ free(le);
+ }
+ }
+
+ sceIoWrite(logfd, buff, strlen(buff));
+
+ // make sure it gets flushed
+ sceIoClose(logfd);
+ logfd = -1;
+#endif
+}
+
+