diff ppl.c @ 151:8708b0354eb8

Various improvements and small optimizations in display drawing/updating.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 06 Oct 2012 03:31:16 +0300
parents 6a838784fb3a
children f1aa6e90ad22
line wrap: on
line diff
--- a/ppl.c	Sat Oct 06 03:30:48 2012 +0300
+++ b/ppl.c	Sat Oct 06 03:31:16 2012 +0300
@@ -247,6 +247,81 @@
 }
 
 
+void dmDisplayChn(SDL_Surface *screen, int x0, int y0, int x1, int y1, JSSChannel *chn)
+{
+    int yh = y1 - y0 - 2;
+    if (yh < 10 || chn == NULL)
+        return;
+
+    int xc, ym = y0 + (y1 - y0) / 2, vol = FP_GETH(chn->chVolume);
+    int pitch = screen->pitch / sizeof(Uint32);
+    DMFixedPoint offs = chn->chPos;
+    Uint32 coln = dmCol(0.0, 0.8, 0.0);
+    Uint32 *pix = screen->pixels;
+    Sint16 *data = chn->chData;
+
+
+    dmFillBox3D(screen, x0, y0, x1, y1,
+        (chn->chMute ? dmCol(0.3,0.1,0.1) : dmCol(0,0,0)),
+        col.box2, col.box1);
+
+    if (chn->chData == NULL || !chn->chPlaying)
+        return;
+
+    for (xc = x0 + 1; xc < x1 - 1; xc++)
+    {
+        Sint16 val = ym + (data[FP_GETH(offs)] * yh * vol) / (65536 * 128);
+        pix[xc + val * pitch] = coln;
+        if (chn->chDirection)
+            FP_ADD(offs, chn->chDeltaO);
+        else
+            FP_SUB(offs, chn->chDeltaO);
+    }
+}
+
+
+void dmDisplayChannels(SDL_Surface *screen, int x0, int y0, int x1, int y1, JSSMixer *dev)
+{
+    int nchannel, qx, qy,
+        qwidth = x1 - x0,
+        qheight = y1 - y0,
+        nwidth = jsetNChannels,
+        nheight = 1;
+    
+    if (qheight < 40)
+        return;
+    
+    while (qwidth / nwidth <= 60 && qheight / nheight >= 40)
+    {
+        nheight++;
+        nwidth /= nheight;
+    }
+
+//    fprintf(stderr, "%d x %d\n", nwidth, nheight);
+    
+    if (qheight / nheight <= 40)
+    {
+        nwidth = qwidth / 60;
+        nheight = qheight / 40;
+    }
+
+    qwidth /= nwidth;
+    qheight /= nheight;
+        
+    for (nchannel = qy = 0; qy < nheight; qy++)
+    {
+        for (qx = 0; qx < nwidth; qx++)
+        {
+            int xc = x0 + qx * qwidth,
+                yc = y0 + qy * qheight;
+
+            dmDisplayChn(screen, xc + 1, yc + 1, xc + qwidth - 1, yc + qheight - 1, &dev->channels[nchannel]);
+            nchannel++;
+        }
+    }
+}
+
+
 static const char patNoteTable[12][3] =
 {
     "C-", "C#", "D-",
@@ -338,8 +413,10 @@
 {
     int cwidth = (font->width * 10 + 3 * 4 + 5),
         lwidth = 6 + font->width * 3,
+        qy0 = y0 + font->height + 2,
+        qy1 = y1 - font->height - 2,
         qwidth  = ((x1 - x0 - lwidth) / cwidth),
-        qheight = ((y1 - y0 - 4) / (font->height + 1)),
+        qheight = ((qy1 - qy0 - 4) / (font->height + 1)),
         nrow, nchannel, yc, choffs,
         midrow = qheight / 2;
 
@@ -351,10 +428,7 @@
     else
         choffs = engine.actChannel - qwidth/2;
 
-    
-    dmDrawBox3D(screen, x0 + lwidth, y0, x1, y1,
-        col.inboxBg, col.box2, col.box1);
-
+    dmDrawBox3D(screen, x0 + lwidth, qy0, x1, qy1, col.box2, col.box1);
 
     for (nchannel = 0; nchannel < qwidth; nchannel++)
     {
@@ -363,24 +437,39 @@
             
         if (engine.actChannel == nchannel + choffs)
         {
-            dmFillRect(screen, bx0+1, y0 + 1, bx1-1, y1 - 1, col.activeChannel);
+            dmFillRect(screen, bx0+1, qy0 + 1, bx1-1, qy1 - 1, col.activeChannel);
+        }
+        else
+        {
+            dmFillRect(screen, bx0+1, qy0 + 1, bx1-1, qy1 - 1, col.inboxBg);
         }
+    }
 
-        dmDrawVLine(screen, y0 + 1, y1 - 1, bx1, col.viewDiv);
+    yc = qy0 + 2 + (font->height + 1) * midrow;
+    dmFillRect(screen, x0 + lwidth + 1, yc - 1, x1 - 1, yc + font->height, col.activeRow);
+
+    for (nchannel = 0; nchannel < qwidth; nchannel++)
+    {
+        int bx0 = x0 + lwidth + 1 + nchannel * cwidth, 
+            bx1 = bx0 + cwidth;
+
+        dmDrawVLine(screen, qy0 + 1, qy1 - 1, bx1, col.viewDiv);
 
         if (jvmGetMute(engine.dev, nchannel + choffs))
         {
-            dmDrawBMTextConstQ(screen, font, DMD_TRANSPARENT, bx0 + 10, y1, "MUTED");
+            dmDrawBMTextConstQ(screen, font, DMD_TRANSPARENT,
+                bx0 + (cwidth - font->width * 5) / 2, qy1 + 3, "MUTED");
         }
+        
+        dmDrawBMTextQ(screen, font, DMD_TRANSPARENT,
+            bx0 + (cwidth - font->width * 3) / 2, y0 + 1, "%3d",
+            nchannel + choffs);
     }
-
-    yc = y0 + 2 + (font->height + 1) * midrow;
-    dmFillRect(screen, x0 + lwidth + 1, yc - 1, x1 - 1, yc + font->height, col.activeRow);
     
     for (nrow = 0; nrow < qheight; nrow++)
     {
         int crow = nrow - midrow + row;
-        yc = y0 + 2 + (font->height + 1) * nrow;
+        yc = qy0 + 2 + (font->height + 1) * nrow;
         
         if (crow >= 0 && crow < pat->nrows)
         {
@@ -593,6 +682,8 @@
     // okay, main loop here ... "play" module and print out info
     SDL_PauseAudio(0);
 
+    int currTick, prevTick = 0, prevRow = -1;
+    
     while (!engine.exitFlag && engine.plr->isPlaying)
     {
         while (SDL_PollEvent(&engine.event))
@@ -654,25 +745,48 @@
             goto error_exit;
         }
 
+        currTick = SDL_GetTicks();
 #if 1
-        dmDrawBox3D(engine.screen, 0, 0, engine.screen->w - 1, engine.screen->h - 1,
-            col.boxBg, col.box1, col.box2);
-        
-        dmDrawBMTextQ(engine.screen, font, DMD_TRANSPARENT, 5, 5, "%s v%s by ccr/TNSP - (c) Copyright 2012 TNSP", dmProgDesc, dmProgVersion);
+
+
+        if (engine.plr->row != prevRow || currTick - prevTick > 50)
+        {
+            dmClearSurface(engine.screen, col.boxBg);
+            
+            dmDrawBMTextQ(engine.screen, font, DMD_TRANSPARENT, 5, 5, "%s v%s by ccr/TNSP - (c) Copyright 2012 TNSP", dmProgDesc, dmProgVersion);
+
+            dmDrawBMTextQ(engine.screen, font, DMD_TRANSPARENT, 5, 5 + 12 + 11,
+                "Song: '%s'",
+                engine.mod->moduleName);
+
+            dmDisplayPattern(engine.screen, 5, 40,
+                engine.screen->w - 6, engine.screen->h * 0.8,
+                engine.plr->pattern, engine.plr->row);
+            
+            prevTick = currTick;
+            prevRow = engine.plr->row;
+        }
+        else
+        {
+            dmFillRect(engine.screen, 5, 5 + 12, engine.screen->w, 5 + 12 + 10, col.boxBg);
+        }
+
+        dmDrawBMTextQ(engine.screen, font, DMD_TRANSPARENT, 5, 5 + 12,
+            "Tempo: %3d | Speed: %3d | Row: %3d | Order: %3d/%3d | Pattern: %3d/%3d",
+            engine.plr->tempo, engine.plr->speed, engine.plr->row,
+            engine.plr->order, engine.mod->norders,
+            engine.plr->npattern, engine.mod->npatterns);
+
 
 
         JSS_LOCK(engine.dev);
         JSS_LOCK(engine.plr);
-
-        dmDrawBMTextQ(engine.screen, font, DMD_TRANSPARENT, 5, 5 + 12,
-            "Tempo: %3d | Speed: %3d | Row: %3d | Order: %d",
-            engine.plr->tempo, engine.plr->speed, engine.plr->row, engine.plr->order);
-
-        dmDisplayPattern(engine.screen, 5, 30, engine.screen->w - 6, engine.screen->h - 10,
-            engine.plr->pattern, engine.plr->row);
+        dmDisplayChannels(engine.screen, 5, engine.screen->h * 0.8 + 5,
+            engine.screen->w - 5, engine.screen->h - 5, engine.dev);
 
         JSS_UNLOCK(engine.plr);
         JSS_UNLOCK(engine.dev);
+
 #endif
 
         // Flip screen
@@ -680,7 +794,7 @@
             SDL_UnlockSurface(engine.screen);
 
         SDL_Flip(engine.screen);
-        SDL_Delay(engine.pauseFlag ? 80 : 16);
+        SDL_Delay(engine.pauseFlag ? 100 : 15);
     }
 
 error_exit: