home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / DigitalCD / !DigitalCD / Copy / PowerBars / c / Main < prev    next >
Text File  |  1999-12-03  |  10KB  |  468 lines

  1. #include <signal.h>
  2. #include <stdarg.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <time.h>
  7. #include "kernel.h"
  8. #include "bool.h"
  9. #include "Event.h"
  10. #include "Exception.h"
  11. #include "Window.h"
  12. #include "Task.h"
  13.  
  14. #include "DCDswi.h"
  15.  
  16. #define TASKNAME "PowerBars"
  17. const char* TaskName = TASKNAME;
  18. int block[64];
  19.  
  20. int LeftPower = 0;
  21. int RightPower = 0;
  22. HWind wleft = -1;
  23. HWind wright = -1;
  24. HWind DCDWindow = -1;
  25. CSize spSize = {32, 128};
  26. CSize spDSize = {32, 128};
  27. CSpriteArea* pSprites = NULL;
  28.  
  29. void App_Log(const char* pformat, ...)
  30. {
  31.     va_list arg;
  32.     char    filename[] = TASKNAME ":Log";
  33.     FILE* file = fopen(filename, "a");
  34.  
  35.     if (file == NULL) file = fopen(filename, "w");
  36.  
  37.     if (file == NULL) return;
  38.  
  39.     va_start(arg, pformat);
  40.     vfprintf(file, pformat, arg);
  41.     va_end(arg);
  42.  
  43.     fclose(file);
  44. }
  45.  
  46. void App_LogBinary(void* pdata, int len)
  47. {
  48.     char    filename[] = TASKNAME ":Log";
  49.     FILE* file = fopen(filename, "a");
  50.  
  51.     if (file == NULL) file = fopen(filename, "w");
  52.  
  53.     if (file == NULL) return;
  54.  
  55.     fprintf(file, "Dump of %p\n", pdata);
  56.     fwrite(pdata, len, 1, file);
  57.     fprintf(file, "End of Dump\n");
  58.  
  59.     fclose(file);
  60. }
  61.  
  62. typedef void (*Window_Drawer)(const CWindRedraw* pdraw, void* handle);
  63.  
  64. void Window_Update(HWind w, const CRect* pbox, Window_Drawer pdraw, void* handle)
  65. {
  66.     _kernel_swi_regs    regs;
  67.     CWindRedraw        r;
  68.  
  69.     r.w = w;
  70.     r.cvt.box = *pbox;
  71.  
  72.     /* Wimp_UpdateWindow */
  73.     regs.r[1] = (int) &r;
  74.     _kernel_swi(0x0600c9, ®s, ®s);
  75.  
  76.     while (regs.r[0])
  77.     {
  78.         if (pdraw) pdraw(&r, handle);
  79.  
  80.         /* Wimp_GetRectangle */
  81.         regs.r[1] = (int) &r;
  82.         _kernel_swi(0x0600ca, ®s, ®s);
  83.     }
  84. }
  85.  
  86. void Window_Redraw(HWind w, Window_Drawer pdraw, void* handle)
  87. {
  88.     _kernel_swi_regs    regs;
  89.     CWindRedraw        r;
  90.  
  91.     r.w = w;
  92.  
  93.     /* Wimp_RedrawWindow */
  94.     regs.r[1] = (int) &r;
  95.     _kernel_swi(0x0600c8, ®s, ®s);
  96.  
  97.     while (regs.r[0])
  98.     {
  99.         if (pdraw) pdraw(&r, handle);
  100.  
  101.         /* Wimp_GetRectangle */
  102.         regs.r[1] = (int) &r;
  103.         _kernel_swi(0x0600ca, ®s, ®s);
  104.     }
  105. }
  106.  
  107. CRect Window_GetOutline(HWind id)
  108. {
  109.     _kernel_swi_regs    regs;
  110.     struct
  111.     {
  112.         HWind    w;
  113.         CRect    pos;
  114.     }    outline;
  115.  
  116.     /* Wimp_GetWindowOutline */
  117.     outline.w = id;
  118.     regs.r[1] = (int) &outline;
  119.     _kernel_swi(0x0600e0, ®s, ®s);
  120.     return outline.pos;
  121. }
  122.  
  123. void Desktop_SetStdColour(int c)
  124. {
  125.     _kernel_swi_regs    regs;
  126.  
  127.     regs.r[0] = c;
  128.     _kernel_swi(0x600e6, ®s, ®s);
  129. }
  130.  
  131. void Display_Plot(int code, int x, int y)
  132. {
  133.     _kernel_swi_regs    regs;
  134.  
  135.     /* OS_Plot  */
  136.     regs.r[0] = code;
  137.     regs.r[1] = x;
  138.     regs.r[2] = y;
  139.     _kernel_swi(0x020045, ®s, ®s);
  140. }
  141.  
  142. void BarDrawer(const CWindRedraw* pdraw, void* handle)
  143. {
  144.     int power = (int) handle;
  145.     int y = pdraw->cvt.box.y0 + (((pdraw->cvt.box.y1 - pdraw->cvt.box.y0)*power) >> 7);
  146.     CPoint pt;
  147.     CRect rect = {0, 0, 0, 0};
  148.  
  149.     pt.x = pdraw->cvt.box.x0;
  150.     pt.y = pdraw->cvt.box.y0;
  151.  
  152.     Desktop_SetStdColour(7);
  153.     Display_Plot(  4, pdraw->cvt.box.x0, y);
  154.     Display_Plot(101, pdraw->cvt.box.x1, pdraw->cvt.box.y1);
  155.  
  156.     y -= pt.y;
  157.     rect.x1 = spSize.cx;
  158.     while (y > 0)
  159.     {
  160.         rect.y1 = (spSize.cy*y)/spDSize.cy;
  161.         Desktop_PlotSprite(pSprites, "bar", &pt, &rect);
  162.         y -= spDSize.cy;
  163.         pt.y += spDSize.cy;
  164.     }
  165. }
  166.  
  167. bool App_ProcessKey(int key)
  168. {
  169.     return false;
  170. }
  171.  
  172. void BarOpenLeft(void)
  173. {
  174.     _kernel_swi_regs    regs;
  175.     CWindOpen        open;
  176.     CRect            box = Window_GetOutline(DCDWindow);
  177.  
  178.     open.w = wleft;
  179.     open.cvt.box.y0 = box.y0;
  180.     open.cvt.box.y1 = box.y1;
  181.     open.cvt.box.x0 = box.x0 - spDSize.cx;
  182.     open.cvt.box.x1 = box.x0;
  183.     open.cvt.s.cx = 0;
  184.     open.cvt.s.cy = 0;
  185.     open.behind = DCDWindow;
  186.  
  187.     regs.r[1] = (int) &open;
  188.  
  189.     _kernel_swi(0x600C5, ®s, ®s);
  190. }
  191.  
  192. void BarOpenRight(void)
  193. {
  194.     _kernel_swi_regs    regs;
  195.     CWindOpen        open;
  196.     CRect            box = Window_GetOutline(DCDWindow);
  197.  
  198.     open.w = wright;
  199.     open.cvt.box.y0 = box.y0;
  200.     open.cvt.box.y1 = box.y1;
  201.     open.cvt.box.x0 = box.x1;
  202.     open.cvt.box.x1 = box.x1 + spDSize.cx;
  203.     open.cvt.s.cx = 0;
  204.     open.cvt.s.cy = 0;
  205.     open.behind = DCDWindow;
  206.  
  207.     regs.r[1] = (int) &open;
  208.     _kernel_swi(0x600C5, ®s, ®s);
  209. }
  210.  
  211. #define SND_WIDTH 128
  212. char2 Buffer[SND_WIDTH];
  213.  
  214. void App_ProcessFrame(void)
  215. {
  216.     CRect    box = {0, 0, 32, 1024};
  217.     int    i, size;
  218.     char    left, right;
  219.     /* DCDWindow tracking, send WindowOpen Requests */
  220.  
  221.     /* Read wave */
  222.     LeftPower = 0;
  223.     RightPower = 0;
  224.     size = DCDUtils_GetBuffer(Buffer, Buffer + SND_WIDTH);
  225.     for (i = 0; i < size; i++)
  226.     {
  227.         left = Buffer[i][0];
  228.         right = Buffer[i][1];
  229.         /* Get abs */
  230.         if (left & 0x80) left = -left;
  231.         if (right & 0x80) right = - right;
  232.  
  233.         if (LeftPower < left)
  234.             LeftPower = left;
  235.         if (RightPower < right)
  236.             RightPower = right;
  237.     }
  238.     BarOpenLeft();
  239.     BarOpenRight();
  240.     Window_Update(wleft, &box, BarDrawer, (void*) LeftPower);
  241.     Window_Update(wright, &box, BarDrawer, (void*) RightPower);
  242. }
  243.  
  244. CWind w = {0,0,0,32,1024,0,0,-1,0,0xff,0,0,0xff,0,0,0,0,0,0,256,1024,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  245.  
  246. static int messages[] =
  247. {
  248.     0x52780, /* Message_UpdatePlugInsPosition */
  249.     0
  250. };
  251.  
  252. int main(int argc, char* argv[])
  253. {
  254.     _kernel_oserror Error_Signal;
  255.     _kernel_swi_regs regs;
  256.     const _kernel_oserror* err = NULL;
  257.     const char* errfile = NULL;
  258.     int errline = 0;
  259.     int Time =0;
  260.     int NewTime = 0;
  261.     const char* pDCDTitle;
  262.     int count = -1;
  263.     int oldcount;
  264.     int dummy;
  265.     HTask TaskId;
  266.     bool bLoop = true;
  267.  
  268.     exception_initialise();
  269.  
  270.     if (argc > 1)
  271.     {
  272.         DCDUtils_SetPlayer(atoi(argv[1]));
  273.     }
  274.     else
  275.         DCDUtils_SetPlayer(0);
  276.  
  277. /*    Choices_Choices("DigitalCD.Plugins." TASKNAME ".Choices");
  278. */
  279.     /* Wimp_Initialise */
  280.     regs.r[0] = 310;
  281.     regs.r[1] = 0x4B534154;
  282.     regs.r[2] = (int) TaskName;
  283.     regs.r[3] = (int) messages;
  284.     throw_os(_kernel_swi(0x0600C0, ®s, ®s));
  285.     TaskId = regs.r[1];
  286.     throw_os(DCDUtils_RegisterPlugIn(TaskId, false));
  287.     Task_SetModeInfo();
  288.  
  289.     try
  290.     {
  291.         if ((pSprites = Sprites_LoadFile("PowerBars:Sprites")) == NULL)
  292.             throw_string("Failed to load sprites");
  293.  
  294.         spSize = GetSpriteSize(pSprites, "bar");
  295.         spDSize = Desktop_GetSpriteSize(pSprites, "bar");
  296.         w.o.o.cvt.box.x1 = spDSize.cx;
  297.         w.ex.x1 = spDSize.cx;
  298.  
  299.         /* Wimp_CreateWindow */
  300.         regs.r[1] = (int) &w.o.o.cvt;
  301.         throw_os(_kernel_swi(0x0600C1, ®s, ®s));
  302.         wleft = regs.r[0];
  303.         /* Wimp_CreateWindow */
  304.         regs.r[1] = (int) &w.o.o.cvt;
  305.         throw_os(_kernel_swi(0x0600C1, ®s, ®s));
  306.         wright = regs.r[0];
  307.  
  308.         /*
  309.          * Main loop
  310.          */
  311.         bLoop = true;
  312.  
  313.         do
  314.         {
  315.             bool bWait = true;
  316.  
  317.             /* XOS_ReadMonotonicTime */
  318.             _kernel_swi(0x020042, ®s, ®s);
  319.             Time = regs.r[0];
  320.  
  321.             /* Get song info */
  322.             oldcount = count;
  323.             DCDUtils_GetInfo(&DCDWindow, &count, &dummy, &pDCDTitle);
  324.             /* Process frame */
  325.             if (count)
  326.                 App_ProcessFrame();
  327.             else
  328.                 bLoop = false;
  329.  
  330.             /* Wimp_PollIdle */
  331.             NewTime = Time + 5;
  332.             while (bWait && bLoop)
  333.             {
  334.                 regs.r[0] = 0;
  335.                 regs.r[1] = (int) █
  336.                 regs.r[2] = NewTime;
  337.                 _kernel_swi(0x600E1, ®s, ®s);
  338.                 switch(regs.r[0])
  339.                 {
  340.                     case EEvent_Null:
  341.                     {
  342.                         bWait = false;
  343.                     }
  344.                     break;
  345.                     case EEvent_WindowRedraw:
  346.                     {
  347.                         if (block[0] == wleft)
  348.                             Window_Redraw(wleft, BarDrawer, (void*) LeftPower);
  349.                         else if (block[0] == wright)
  350.                             Window_Redraw(wright, BarDrawer, (void*) RightPower);
  351.                         else Window_Redraw(block[0], NULL, NULL);
  352.                     }
  353.                     break;
  354.                     case EEvent_WindowOpen:
  355.                     {
  356.                         CWindOpen* popen = (CWindOpen*) █
  357.  
  358.                         if (popen->w == wleft)
  359.                             BarOpenLeft();
  360.                         else if (popen->w == wright)
  361.                             BarOpenRight();
  362.                         else
  363.                             _kernel_swi(0x600C5, ®s, ®s);
  364.                     }
  365.                     break;
  366.                     case EEvent_WindowClose:
  367.                     {
  368.                         _kernel_swi(0x600C6, ®s, ®s);
  369.                     }
  370.                     break;
  371.                     case EEvent_Key:
  372.                     {
  373.                         Event_Key* pkey = (Event_Key*) █
  374.  
  375.                         if (!App_ProcessKey(pkey->code))
  376.                         {
  377.                             pkey->caret.pos.w = DCDWindow;
  378.                             pkey->caret.pos.i = -1;
  379.                             /* Wimp_SendMessage */
  380.                             regs.r[0] = EEvent_Key;
  381.                             regs.r[1] = (int) pkey;
  382.                             regs.r[2] = DCDWindow;
  383.                             regs.r[3] = -1;
  384.                             _kernel_swi(0x0600e7, ®s, ®s);
  385.                         }
  386.                     }
  387.                     break;
  388.                     case EEvent_Message:
  389.                     case EEvent_MessageWantAck:
  390.                     {
  391.                         switch(block[4])
  392.                         {
  393.                             case EMsg_Quit:
  394.                             {
  395.                                 bLoop = false;
  396.                             }
  397.                             break;
  398.                             case EMsg_ModeChange:
  399.                             {
  400.                                 /* Preprocessing */
  401.                                 Task_SetModeInfo();
  402.                             }
  403.                             break;
  404.                             case 0x52780:
  405.                             {
  406.                                 /* Player may send us it's new position */
  407.                                 BarOpenLeft();
  408.                                 BarOpenRight();
  409.                             }
  410.                             break;
  411.                         }
  412.                     }
  413.                     break;
  414.                 }
  415.             }
  416.         } while (bLoop);
  417.     }
  418.     catch
  419.     {
  420.         const exception* e = exception_current();
  421.  
  422.         switch(e->type)
  423.         {
  424.             case exception_os:
  425.             {
  426.                 /* Save error as it could be overwritten */
  427.                 Error_Signal = *e->error.os;
  428.                 err = &Error_Signal;
  429.                 errfile = e->file;
  430.                 errline = e->line;
  431.             }
  432.             break;
  433. /*            case exception_user:    err = &Task_Error_NoMem; break;
  434. */            default:
  435.             {
  436.                 if (e->error.signal_id != SIGINT)
  437.                 {
  438.                     err = &Error_Signal;
  439.                     sprintf(&Error_Signal.errmess[0], "Signal:%d\n\0", e->error.signal_id);
  440.                     errfile = NULL;
  441.                     errline = 0;
  442.                 }
  443.             }
  444.         }
  445.     }
  446.     catch_end
  447.  
  448.     DCDUtils_DeregisterPlugIn();
  449.  
  450.     /* Wimp_CloseDown */
  451.     regs.r[0] = TaskId;
  452.     regs.r[1] = 0x4b534154;
  453.     _kernel_swi(0x0600DD, ®s, ®s);
  454.  
  455.     if (err)
  456.     {
  457.         if (errfile)
  458.             App_Log("%s at line %d of file %s\n", err->errmess, errline, errfile);
  459.         else
  460.             App_Log("%s\n", err->errmess);
  461.  
  462.         printf("%s\n", err->errmess);
  463.         return EXIT_FAILURE;
  464.     }
  465.  
  466.     return EXIT_SUCCESS;
  467. }
  468.