a few more patches and a little rework
[ginge.git] / prep / main.c
index 7cc4337..e732ef6 100644 (file)
@@ -1,4 +1,9 @@
-// vim:shiftwidth=2:expandtab
+/*
+ * GINGE - GINGE Is Not Gp2x Emulator
+ * (C) notaz, 2010-2011
+ *
+ * This work is licensed under the MAME license, see COPYING file for details.
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #define LOADER_DYNAMIC  "ginge_dyn.sh"
 #define LAUNCHER        "gp2xmenu"
 
+#ifdef PND
+#define WRAP_APP        "op_runfbapp "
+#else
+#define WRAP_APP        ""
+#endif
+
 #include "font.c"
 
 static void *fb_mem;
 static int fb_stride;
 static int fb_x, fb_y;
+static int init_done;
 
 static char *sskip(char *p)
 {
@@ -36,6 +48,26 @@ static char *cskip(char *p)
   return p;
 }
 
+static void fb_text_exit(void)
+{
+  if (!init_done)
+    return;
+
+  host_video_finish();
+  init_done = 0;
+}
+
+static void fb_text_init(void)
+{
+  int ret = host_video_init(&fb_stride, 1);
+  if (ret == 0)
+    fb_mem = host_video_flip();
+  fb_x = 4;
+  fb_y = 4;
+  init_done = 1;
+  atexit(fb_text_exit);
+}
+
 static void fb_syms_out(void *fbi, int x, int y, int dotsz, int stride, const char *text, int count)
 {
   int v = -1, n = 0, *p;
@@ -72,6 +104,9 @@ static void fb_text_out(char *text)
   char *p, *pe;
   int l;
 
+  if (!init_done)
+    fb_text_init();
+
   if (fb_mem == NULL)
     return;
 
@@ -98,15 +133,6 @@ static void fb_text_out(char *text)
   }
 }
 
-static void fb_text_init(void)
-{
-  int ret = host_video_init(&fb_stride, 1);
-  if (ret == 0)
-    fb_mem = host_video_flip();
-  fb_x = 4;
-  fb_y = 4;
-}
-
 static void fbprintf(int is_err, const char *format, ...)
 {
   va_list ap;
@@ -120,8 +146,8 @@ static void fbprintf(int is_err, const char *format, ...)
   fb_text_out(buff);
 }
 
-#define msg(fmt, ...) fbprintf(0, fmt, #__VA_ARGS__)
-#define err(fmt, ...) fbprintf(1, fmt, #__VA_ARGS__)
+#define msg(fmt, ...) fbprintf(0, fmt, ##__VA_ARGS__)
+#define err(fmt, ...) fbprintf(1, fmt, ##__VA_ARGS__)
 
 static int id_elf(const char *fname)
 {
@@ -169,12 +195,12 @@ out:
   return ret;
 }
 
-static void dump_args(FILE *fout, int argc, char * const argv[])
+static void dump_args(FILE *fout, char * const argv[])
 {
   const char *p;
   int i;
 
-  for (i = 0; i < argc; i++) {
+  for (i = 0; argv[i] != NULL; i++) {
     if (i != 0)
       fputc(' ', fout);
     fputc('"', fout);
@@ -237,17 +263,42 @@ int main(int argc, char *argv[])
 {
   static const char out_script[] = "/tmp/ginge_conv.sh";
   char root_path[512], cwd[512];
+  char **argv_app = NULL;
   int have_cramfs = 0;
   int rerun_gp2xmenu = 1;
+  int quit_if_no_app = 0;
   FILE *fin, *fout;
-  int ret;
+  int i, ret;
+
+  for (i = 1; i < argc && argv[i][0] == '-' && argv[i][1] == '-'; i++) {
+    if (strcmp(argv[i], "--cleanup") == 0) {
+      // as loader may crash eny time, restore screen for the menu
+      host_video_init(NULL, 1);
+      host_video_finish();
+      quit_if_no_app = 1;
+      continue;
+    }
+    if (strcmp(argv[i], "--nomenu") == 0) {
+      rerun_gp2xmenu = 0;
+      continue;
+    }
+    if (strcmp(argv[i], "--") == 0) {
+      i++;
+      break;
+    }
 
-  fb_text_init();
+    fprintf(stderr, PFX "ignoring unknown option \"%s\"\n", argv[i]);
+  }
 
-  if (argc < 2) {
-    err("usage: %s <script|program> [args]\n", argv[0]);
+  if (argc <= i) {
+    if (quit_if_no_app)
+      return 0;
+    err("usage: %s [opts] <script|program> [args]\n", argv[0]);
+    err("  --cleanup  - restore framebuffer state\n");
+    err("  --nomenu   - don't run menu on exit\n");
     return 1;
   }
+  argv_app = &argv[i];
 
   if (getcwd(cwd, sizeof(cwd)) == NULL) {
     err(PFX "failed to get cwd\n");
@@ -268,10 +319,10 @@ int main(int argc, char *argv[])
 
   fprintf(fout, "#!/bin/sh\n");
 
-  ret = id_elf(argv[1]);
+  ret = id_elf(argv_app[0]);
   if (ret == 1 || ret == 2) {
-    if (cmd_in_blacklist(argv[1])) {
-      fprintf(stderr, "blacklisted: %s\n", argv[1]);
+    if (cmd_in_blacklist(argv_app[0])) {
+      fprintf(stderr, "blacklisted: %s\n", argv_app[0]);
       goto no_in_script;
     }
   }
@@ -281,14 +332,14 @@ int main(int argc, char *argv[])
     break;
 
   case 1:
-    fprintf(fout, "op_runfbapp %s%s ", root_path, LOADER_STATIC);
-    dump_args(fout, argc - 1, &argv[1]);
+    fprintf(fout, WRAP_APP "%s%s ", root_path, LOADER_STATIC);
+    dump_args(fout, argv_app);
     fprintf(fout, "\n");
     goto no_in_script;
 
   case 2:
-    fprintf(fout, "op_runfbapp %s%s \"%s\" ", root_path, LOADER_DYNAMIC, root_path);
-    dump_args(fout, argc - 1, &argv[1]);
+    fprintf(fout, WRAP_APP "%s%s \"%s\" ", root_path, LOADER_DYNAMIC, root_path);
+    dump_args(fout, argv_app);
     fprintf(fout, "\n");
     goto no_in_script;
 
@@ -297,7 +348,7 @@ int main(int argc, char *argv[])
   }
 
   // assume script
-  fin = fopen(argv[1], "r");
+  fin = fopen(argv_app[0], "r");
   if (fin == NULL)
     return 1;
 
@@ -385,12 +436,12 @@ int main(int argc, char *argv[])
       switch (ret) {
       case 1:
         printf(PFX "prefixing as static: %s", p);
-        fprintf(fout, "op_runfbapp %s%s ", root_path, LOADER_STATIC);
+        fprintf(fout, WRAP_APP "%s%s ", root_path, LOADER_STATIC);
         break;
 
       case 2:
         printf(PFX "prefixing as dynamic: %s", p);
-        fprintf(fout, "op_runfbapp %s%s \"%s\" ", root_path, LOADER_DYNAMIC, root_path);
+        fprintf(fout, WRAP_APP "%s%s \"%s\" ", root_path, LOADER_DYNAMIC, root_path);
         break;
 
       default:
@@ -405,6 +456,13 @@ pass:
   fclose(fin);
 
 no_in_script:
+#ifdef WIZ
+  fprintf(fout, "sync\n");
+  // since we don't know if loader manages to do proper cleanup,
+  // need to wait for it's threads to die
+  fprintf(fout, "sleep 1\n");
+  fprintf(fout, "%sginge_prep --cleanup\n", root_path);
+#endif
   if (rerun_gp2xmenu) {
     fprintf(fout, "cd %s\n", root_path);
     fprintf(fout, "exec %s%s\n", root_path, LAUNCHER);
@@ -412,16 +470,21 @@ no_in_script:
 
   fclose(fout);
 
-  msg("starting script..\n");
-  if (have_cramfs)
-    msg("\nsome files need to be unpacked, this may tike a few minutes.\n"
-        "Please wait at least while SD LED is active.\n");
+  //msg("starting script..\n");
+  if (have_cramfs) {
+    msg("\nsome files need to be unpacked, this may tike a few minutes.\n");
+#ifdef PND
+    msg("Please wait at least while SD LED is active.\n");
+#endif
+  }
   system("echo ---; cat /tmp/ginge_conv.sh; echo ---");
   chmod(out_script, S_IRWXU|S_IRWXG|S_IRWXO);
   chdir(cwd);
+  fb_text_exit();
   execlp(out_script, out_script, NULL);
   perror("run out_script");
 
   return 1;
 }
 
+// vim:shiftwidth=2:expandtab