DEADSOFTWARE

kos32: efficiently implement main loop
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Tue, 2 Feb 2021 20:23:19 +0000 (23:23 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Tue, 2 Feb 2021 20:23:19 +0000 (23:23 +0300)
src/kos32/kos32.h
src/kos32/main.c

index 9686f1266867949210985c5f187e720706509785..a11e7911fd13aae6abcb4512d638a93738aec162 100644 (file)
@@ -186,6 +186,18 @@ static inline int CheckEvent (void) {
   return ret;
 }
 
+/* --- fn 23 --- */
+static inline int WaitEventTimeout (int timeout) {
+  int ret;
+  __asm__ __volatile__ (
+    "int $0x40"
+    : "=a" (ret)
+    : "a" (23),
+      "b" (timeout)
+  );
+  return ret;
+}
+
 /* --- fn 2 --- */
 static inline int GetKey (void) {
   int ret;
@@ -246,6 +258,26 @@ static inline int GetSkinHeight (void) {
   return ret;
 }
 
+/* --- fn 68.1 --- */
+static inline void SwitchTask (void) {
+  __asm__ __volatile__ (
+    "int $0x40"
+    :
+    : "a" (68),
+      "b" (1)
+  );
+}
+
+/* --- fn 5 --- */
+static inline void Delay (int time) {
+  __asm__ __volatile__ (
+    "int $0x40"
+    :
+    : "a" (5),
+      "b" (time)
+  );
+}
+
 #define KOS32_SC_UNKNOWN 0x00
 #define KOS32_SC_ESCAPE  0x01
 #define KOS32_SC_1       0x02
index 3ccbb5bce6d8930d297fe3a4ab420a8a66420694..557505df4a386b903e0a9df025574985df6b94a9 100644 (file)
@@ -38,7 +38,6 @@
 #include "music.h" // S_initmusic S_updatemusic S_donemusic
 #include "render.h" // R_init R_draw R_done
 
-static int ticks = 0;
 static int quit = 0;
 static videomode_size_t wlist[3] = {
  { 320, 200, 0 },
@@ -486,10 +485,13 @@ static void handle_scancode (int code) {
 
 static void poll_events (void) {
   int ev, key, button, code, ch, k;
-  while(!!(ev = CheckEvent())) {
+  while((ev = CheckEvent()) != KOS32_EVENT_NONE) {
     switch (ev) {
       case KOS32_EVENT_REDRAW:
-        return; /* force redraw */
+        if (buf != NULL) {
+          Y_repaint(); /* redraw window */
+        }
+        break;
       case KOS32_EVENT_KEYBOARD:
         key = GetKey();
         if ((key & 0xff) == 0) {
@@ -521,19 +523,27 @@ static void poll_events (void) {
   }
 }
 
-static void step (void) {
-  poll_events();
-  MUS_update();
-  long t = GetTimeCountPro(); /* ns */
-  if (t - ticks > DELAY * 1000000) {
-    ticks = t;
-    G_act();
+static void game_loop (void) {
+  static long ticks; /* ns */
+  ticks = GetTimeCountPro();
+  while (!quit) {
+    poll_events();
+    MUS_update();
+    long t = GetTimeCountPro(); /* ns */
+    int n = (t - ticks) / ((DELAY + 1) * 1000000);
+    ticks = ticks + n * ((DELAY + 1) * 1000000);
+    if (n > 0) {
+      while (n) {
+        G_act();
+        n -= 1;
+      }
+      R_draw();
+    }
+    Delay(1);
   }
-  R_draw();
 }
 
 int main (int argc, char **argv) {
-  char *pw;
   CFG_args(argc, argv);
   logo("system: initialize engine\n");
   SetEventsMask(KOS32_EVENT_FLAG_REDRAW | KOS32_EVENT_FLAG_KEYBOARD | KOS32_EVENT_FLAG_BUTTON);
@@ -561,12 +571,7 @@ int main (int argc, char **argv) {
   srand(GetIdleCount());
   F_startup();
   CFG_load();
-  pw = "doom2d.wad";
-  if (fexists(pw)) {
-    F_addwad(pw);
-  } else {
-    F_addwad("doom2d.wad");
-  }
+  F_addwad("doom2d.wad");
   F_initwads();
   M_startup();
   F_allocres();
@@ -574,11 +579,8 @@ int main (int argc, char **argv) {
   MUS_init();
   R_init();
   G_init();
-  ticks = GetTimeCountPro();
   logo("system: game loop\n");
-  while (!quit) {
-    step();
-  }
+  game_loop();
   logo("system: finalize engine\n");
   CFG_save();
   R_done();