home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / h / harmonica / !Harmonica / c / !RunImage
Encoding:
Text File  |  1993-04-09  |  8.5 KB  |  419 lines

  1. /* Includes for OS routines */
  2.  
  3. #include "baricon.h"
  4. #include "dbox.h"
  5. #include "event.h"
  6. #include "flex.h"
  7. #include "heap.h"
  8. #include "menu.h"
  9. #include "msgs.h"
  10. #include "os.h"
  11. #include "res.h"
  12. #include "coords.h"
  13. #include "resspr.h"
  14. #include "template.h"
  15. #include "visdelay.h"
  16. #include "wimp.h"
  17. #include "wimpt.h"
  18. #include "saveas.h"
  19. #include "xferrecv.h"
  20. #include "werr.h"
  21. #include "win.h"
  22. #include "bbc.h"
  23. #include "coords.h"
  24.  
  25. /* Includes for ANSI routines */
  26.  
  27. #include <string.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <math.h>
  31.  
  32. #define PI 3.141592654
  33.  
  34.  
  35. BOOL quit,dragging;
  36. wimp_w win_main;
  37. wimp_box wave;
  38. int harmonic[16];
  39. int sint[16][256];
  40. int harm_val[256];
  41. char *harm_table;
  42. wimp_box harm_icons[16];
  43. int drag_y,drag_h,odx,ody,max_harm;
  44. char modname[ ] = "Harmonica";
  45. int *modbase;
  46.  
  47. char convert_byte(char);
  48.  
  49. double get_double(wimp_i icon)
  50.  {
  51.  wimp_icon i;
  52.  wimp_get_icon_info(win_main,icon,&i);
  53.  return atof(i.data.indirecttext.buffer);
  54.  }
  55.  
  56. void redraw_wave(wimp_box *b)
  57.  {
  58.  int y,x,dx = wimpt_dx(),dy = wimpt_dy();
  59.  wimp_setcolour(0);
  60.  bbc_rectanglefill(b->x0,b->y0,b->x1-b->x0-dx,b->y1-b->y0-dy);
  61.  wimp_setcolour(11);
  62.  bbc_move(b->x0,128+b->y0);
  63.  for (x = 0 ; x < 512 ; x += dx)
  64.    {
  65.    y = 128 + harm_val[x/2] * 128/max_harm;
  66.    bbc_draw(x+b->x0,y+b->y0);
  67.    }
  68.  }
  69.  
  70. void recalc_harms(void)
  71.  {
  72.  int x,h,r;
  73.  max_harm = 1;
  74.  for (x = 0 ; x < 256 ; x++)
  75.    {
  76.    harm_val[x] = 0;
  77.    for (h = 0 ; h < 16 ; h++)
  78.      harm_val[x] += harmonic[h] * sint[h][x];
  79.    if (harm_val[x] > max_harm)
  80.      max_harm = harm_val[x];
  81.    }
  82.  for (x = 0 ; x < 256 ; x++)
  83.    {
  84.    r = 127 + harm_val[x]*128/max_harm;
  85.    if (r < 0)   r = 0;
  86.    if (r > 255) r = 255;
  87.    harm_table[x] = convert_byte(r);
  88.    }
  89.  visdelay_percent(25*x/64);
  90.  visdelay_end();
  91.  }
  92.  
  93. void load_harm(char *fname)
  94.  {
  95.  int h;
  96.  FILE *file;
  97.  file = fopen(fname,"rb");
  98.  for (h = 0 ; h < 16 ; h++)
  99.    harmonic[h] = fgetc(file);
  100.  fclose(file);
  101.  xferrecv_insertfileok();
  102.  }
  103.  
  104. void redraw_harmonics(wimp_box *r,wimp_box *scr)
  105.  {
  106.  int dx,dy,h,y;
  107.  dx = wimpt_dx();
  108.  dy = wimpt_dy();
  109.  y = harm_icons[0].y1 - harm_icons[0].y0 - dy;
  110.  for (h = 0 ; h < 16 ; h ++)
  111.    if (coords_boxesoverlap(r,&harm_icons[h]))
  112.      {
  113.      wimp_setcolour(11);
  114.      bbc_rectanglefill(
  115.        harm_icons[h].x0+dx - r->x0 + scr->x0,
  116.        harm_icons[h].y0+dy - r->y0 + scr->y0,
  117.        36-dx, y*harmonic[h]/256);
  118.      wimp_setcolour(0);
  119.      bbc_rectanglefill(
  120.        harm_icons[h].x0+dx - r->x0 + scr->x0,
  121.        harm_icons[h].y0+y+dy  - r->y0 + scr->y0,
  122.        36-dx, -(y-y*harmonic[h]/256));
  123.      }
  124.  }
  125.  
  126. BOOL save_sample(char *fname,void *handle)
  127.  {
  128.  char temp[256] = "SetType ";
  129.  double pr,rr;
  130.  int pos,ptr;
  131.  FILE *file;
  132.  file = fopen(fname,"wb");
  133.  rr = get_double(26) * 1000.0;
  134.  if (rr == 0) rr = 20000.0;
  135.  pr = get_double(27);
  136.  if (pr == 0) pr = 256;
  137.  for (ptr = 0 ; ptr < (int) rr ; ptr ++)
  138.    {
  139.    pos = (int) ((double)ptr * pr/rr * 256.0);
  140.    pos = pos % 256;
  141.    fputc(harm_table[pos],file);
  142.    }
  143.  fclose(file);
  144.  strcat(temp,fname);
  145.  strcat(temp," &631");
  146.  os_cli(temp);
  147.  return 1;
  148.  }
  149.  
  150. BOOL save_harms(char *fname,void *handle)
  151.  {
  152.  char temp[256] = "SetType ";
  153.  int h;
  154.  FILE *file;
  155.  handle = handle;
  156.  file = fopen(fname,"wb");
  157.  for (h = 0 ; h < 16 ; h++)
  158.    fputc(harmonic[h],file);
  159.  fclose(file);
  160.  strcat(temp,fname);
  161.  strcat(temp," &635");
  162.  os_cli(temp);
  163.  return 1; 
  164.  }
  165.  
  166. void scr_box(wimp_box *b,wimp_redrawstr *r)
  167.  {
  168.  b->x0 += r->box.x0 - r->scx;
  169.  b->x1 += r->box.x0 - r->scx;
  170.  b->y0 += r->box.y1 - r->scy;
  171.  b->y1 += r->box.y1 - r->scy;
  172.  }
  173.  
  174. void work_box(wimp_box *b,wimp_redrawstr *r)
  175.  {
  176.  b->x0 -= r->box.x0 - r->scx;
  177.  b->x1 -= r->box.x0 - r->scx;
  178.  b->y0 -= r->box.y1 - r->scy;
  179.  b->y1 -= r->box.y1 - r->scy;
  180.  }
  181.  
  182. int work_to_val(int y)
  183.  {
  184.  int val = (y - harm_icons[0].y0);
  185.  if (val < 0) val = 0;
  186.  if (val > 255) val = 255;
  187.  return val;
  188.  }
  189.  
  190. int scr_to_val(int y)
  191.  {
  192.  int val = (y - drag_y);
  193.  if (val < 0) val = 0;
  194.  if (val > 255) val = 255;
  195.  return val;
  196.  }
  197.  
  198. void redraw_main(void)
  199.  {
  200.  int more;
  201.  wimp_redrawstr r;
  202.  wimp_box red;
  203.  wimp_box wave2;
  204.  wimpt_checkmode();
  205.  r.w = win_main;
  206.  wimpt_noerr(wimp_redraw_wind(&r,&more));
  207.  wave2 = wave;
  208.  scr_box(&wave2,&r);
  209.  while (more)
  210.    {
  211.    red = r.g;
  212.    work_box(&red,&r);
  213.    redraw_wave(&wave2);
  214.    redraw_harmonics(&red,&r.g);
  215.    wimp_get_rectangle(&r,&more);
  216.    }
  217.  }
  218.  
  219. void redraw_icon(int i)
  220.  {
  221.  int more;
  222.  wimp_redrawstr r;
  223.  wimp_box red;
  224.  wimpt_checkmode();
  225.  r.w   = win_main;
  226.  r.box = harm_icons[i];
  227.  wimpt_noerr(wimp_update_wind(&r,&more));
  228.  while (more)
  229.    {
  230.    red = r.g;
  231.    work_box(&red,&r);
  232.    redraw_harmonics(&red,&r.g);
  233.    wimp_get_rectangle(&r,&more);
  234.    }
  235.  }
  236.  
  237. void mouse_harm(int x,int y,int harm)
  238.  {
  239.  wimp_dragstr d;
  240.  wimp_wstate w;
  241.  if (dragging) return;
  242.  d.window = win_main;
  243.  d.type   = wimp_USER_HIDDEN;
  244.  d.box.x0 = d.box.x1 = x;
  245.  d.box.y0 = d.box.y1 = y;
  246.  d.parent = harm_icons[harm];
  247.  wimp_get_wind_state(win_main,&w);
  248.  scr_box(&d.parent,(wimp_redrawstr *)&w.o);
  249.  drag_y   = d.parent.y0;
  250.  drag_h   = harm;
  251.  wimp_drag_box(&d);
  252.  dragging = 1;
  253.  win_claim_idle_events(win_main);
  254.  odx = x; ody = -y;
  255.  }
  256.  
  257. void open_win(wimp_w handle)
  258.  {
  259.  wimp_wstate w;
  260.  wimp_get_wind_state(handle,&w);
  261.  w.o.behind = -1;
  262.  wimp_open_wind(&w.o);
  263.  }
  264.  
  265. void play_harm(void)
  266.  {
  267.  os_regset r;
  268.  double pitch;
  269.  pitch = get_double(27);
  270.  if (pitch == 0.0) pitch = 256.0;
  271.  pitch = (double)0x4000 + (double)0x1000 * log(pitch/(double)256) / log((double)2);
  272.  r.r[0] = 1;
  273.  r.r[1] = 0x1d0;
  274.  r.r[2] = (int) pitch;
  275.  r.r[3] = 0x14;
  276.  os_swi(0x60189,&r);
  277.  }
  278.  
  279. void handler(wimp_eventstr *e,void *handle)
  280.  {
  281.  char *name;
  282.  wimp_mousestr mse;
  283.  handle = handle;
  284.  switch (e->e)
  285.    {
  286.    case wimp_ENULL:
  287.      if (dragging)
  288.        {
  289.        wimp_get_point_info(&mse);
  290.        if (mse.y != ody && mse.bbits != 0)
  291.          {
  292.          ody = mse.y;
  293.          harmonic[drag_h] = scr_to_val(mse.y);
  294.          redraw_icon(drag_h);
  295.          }
  296.        if (mse.bbits == 0)
  297.          {
  298.          dragging = 0;
  299.          win_claim_idle_events(-1);
  300.          recalc_harms();
  301.          wimp_close_wind(win_main);
  302.          open_win(win_main);
  303.          }
  304.        }
  305.      break;
  306.    case wimp_EREDRAW:
  307.      if (e->data.o.w == win_main)
  308.        {
  309.        if (dragging) redraw_icon(drag_h);
  310.        else redraw_main();
  311.        }
  312.      break;
  313.    case wimp_EOPEN:
  314.      wimp_open_wind(&e->data.o);
  315.      break;
  316.    case wimp_ECLOSE:
  317.      quit = 1;
  318.      wimp_close_wind(e->data.o.w);
  319.      break;
  320.    case wimp_EBUT:
  321.      if (e->data.but.m.w == win_main)
  322.        {
  323.        if (e->data.but.m.i == 25)
  324.          play_harm();
  325.        if (e->data.but.m.i == 31)
  326.          saveas(0x631,"LogSample",20000,save_sample,0,0,0);
  327.        if (e->data.but.m.i == 30)
  328.          saveas(0x635,"Harmonics",16,save_harms,0,0,0);
  329.        if (e->data.but.m.i >= 1 && e->data.but.m.i <= 16)
  330.          mouse_harm(e->data.but.m.x,e->data.but.m.y,(int) e->data.but.m.i-1);
  331.        }
  332.      break;
  333.    case wimp_EKEY:
  334.      wimp_processkey(e->data.key.chcode);
  335.      break;
  336.    case 17:
  337.    case 18:
  338.      switch (e->data.msg.hdr.action)
  339.        {
  340.        case wimp_MDATALOAD:
  341.        case wimp_MDATAOPEN:
  342.          if (xferrecv_checkinsert(&name) == 0x635)
  343.            {
  344.            e->data.msg.hdr.your_ref = e->data.msg.hdr.my_ref;
  345.            e->data.msg.hdr.action   = 4;
  346.            e->data.msg.data.dataload.size = -1;
  347.            load_harm(e->data.msg.data.dataload.name);
  348.            recalc_harms();
  349.            wimp_close_wind(win_main);
  350.            open_win(win_main);
  351.            }
  352.          break;
  353.        }
  354.      break;
  355.    }
  356.  }
  357.  
  358. BOOL create_win(char *name,wimp_w *handle)
  359.  {
  360.  wimp_wind *win;
  361.  win = template_syshandle(name);
  362.  if (win == 0) return FALSE;
  363.  return (wimpt_complain(wimp_create_wind(win,handle)) == 0);
  364.  }
  365.  
  366. void init(void)
  367.  {
  368.  int c,s;
  369.  os_regset r;
  370.  double d;
  371.  wimp_icon i;
  372.  visdelay_init();
  373.  visdelay_begin();
  374.  wimpt_init("Harmonica");
  375.  res_init("Harmonica");
  376.  resspr_init();
  377.  template_init();
  378.  dbox_init();
  379.  flex_init();
  380.  heap_init(TRUE);
  381.  r.r[0] = 18;
  382.  r.r[1] = (int)modname;
  383.  os_swi(0x2001e,&r);
  384.  modbase = (int *)r.r[3];
  385.  harm_table = (char *)modbase[24];
  386.  create_win("main",&win_main);
  387.  win_activeinc();
  388.  win_register_event_handler(win_main,handler,0);
  389.  event_setmask(0);
  390.  open_win(win_main);
  391.  wimp_get_icon_info(win_main,0,&i);
  392.  wave = i.box;
  393.  for (c = 0 ; c < 16 ; c++)
  394.    {
  395.    for (s = 0 ; s < 256 ; s++)
  396.      {
  397.      d = ((double)(c+(double)1)*(double)s*2*PI/256);
  398.      sint[c][s] = (int)(((double) 256) * sin(d));
  399.      }
  400.    harmonic[c] = 128/(c+1);
  401.    if (c != 0) harmonic[c] = 0;
  402.    wimp_get_icon_info(win_main,1+c,&i);
  403.    harm_icons[c] = i.box;
  404.    visdelay_percent(25*c/4);
  405.    }
  406.  recalc_harms();
  407. }
  408.  
  409. int main(int argc,char *argv[ ])
  410.  {
  411.  quit = 0;
  412.  init();
  413.  bbc_vdu(7);
  414.  if (argc >= 2 && argv[1][0] == 45)
  415.    load_harm(&argv[1][1]);
  416.  while (!quit)
  417.    event_process();
  418.  }
  419.