home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / programs / emulaton / utilities / magicasm / assembler / c / pcx < prev    next >
Encoding:
Text File  |  1998-04-14  |  5.7 KB  |  305 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "defs.h"
  5. #include "externs.h"
  6.  
  7. char  *pcx_buf;
  8. char   pcx_pal[256][3];
  9. char   pcx_name[128];
  10. struct pcx_header pcx;
  11. int    pcx_w, pcx_h;
  12. short  buffer[256];
  13.  
  14. /* .incchr/spr/pal pseudo */
  15.  
  16. do_pcx(int *ip)
  17. {
  18.     FILE *f;
  19.     char c;
  20.     int val[5];
  21.     int size;
  22.     int i, n = 0;
  23.  
  24.     labldef(loccnt, 1);
  25.     if (!get_filename(ip))
  26.         return;
  27.     for (;;) {
  28.         while (isspace(c = prlnbuf[(*ip)++]));
  29.         if ((c != ',') && (c != ';') && (c != 0)) {
  30.             error("Syntax error!");
  31.             return;
  32.         }
  33.         if (c != ',')
  34.             break;
  35.         if (!evaluate(ip, 0))
  36.             return;
  37.         val[n++] = value;
  38.         if (n == 5)
  39.             break;
  40.     }            
  41.     if (optype & (1 << n)) {
  42.         error("Invalid number of arguments!");
  43.         return;
  44.     }
  45.     if (!load_pcx(filename))
  46.         return;
  47.     if (pass == LAST_PASS) {
  48.         loadlc(loccnt, 0);
  49.         println();
  50.     }
  51.     switch (opval) {
  52.     case 8:
  53.         do_chr(n, val);
  54.         break;
  55.     case 9:
  56.         do_spr(n, val);
  57.            break;
  58.        case 10:
  59.            do_pal(n, val);
  60.            break;
  61.     }
  62. }
  63.  
  64. /*  convert a pcx to characters  */
  65.  
  66. int do_chr(int n, unsigned int *val)
  67. {
  68.     unsigned char *ptr;
  69.     unsigned int   i, j, k, l, x, y, w, h;
  70.     unsigned int   a, b;
  71.     unsigned char  c;
  72.  
  73.     switch (n) {
  74.     case 0:
  75.         x = 0; y = 0;
  76.         w = (pcx_w / 8); h = (pcx_h / 8);
  77.         break;
  78.     case 2:
  79.         x = 0; y = 0;
  80.         w = val[0]; h = val[1];
  81.         if (((w * 8) > pcx_w) || ((h * 8) > pcx_h)) {
  82.             error("Index out of range!");
  83.             return;
  84.         }
  85.         break;
  86.     case 4:
  87.         x = val[0]; y = val[1];
  88.         w = val[2]; h = val[3];
  89.         if (((x + w * 8) > pcx_w) || ((y + h * 8) > pcx_h)) {
  90.             error("Index out of range!");
  91.             return;
  92.         }
  93.         break;
  94.     }
  95.     if (pass == LAST_PASS) {
  96.         for (i = 0; i < h; i++) {
  97.             for (j = 0; j < w; j++) {
  98.                 ptr = pcx_buf + (x + (j * 8)) + ((y + (i * 8)) * pcx_w);
  99.                 for (k = 0; k < 8; k++) {
  100.                     a = 0;
  101.                     b = 0;
  102.                     for (l = 0; l < 8; l++) {
  103.                         c = ptr[l];
  104.                         a = (a << 1) | ((c & 0x01))      | ((c & 0x02) << 7);
  105.                         b = (b << 1) | ((c & 0x04) >> 2) | ((c & 0x08) << 5);
  106.                     }                
  107.                     buffer[k] = a;
  108.                     buffer[k+8] = b;
  109.                     ptr += pcx_w;
  110.                 }
  111.                 copy_buffer(32);
  112.             }
  113.         }
  114.     }
  115.     else
  116.         copy_buffer(32 * w * h);
  117. }
  118.  
  119. /*  convert a pcx to sprites  */
  120.  
  121. int do_spr(int n, unsigned int *val)
  122. {
  123.     unsigned char *ptr;
  124.     unsigned int   i, j, k, l, x, y, w, h;
  125.     unsigned int   a, b, c, d;
  126.     unsigned char  e, f;
  127.  
  128.     switch (n) {
  129.     case 0:
  130.         x = 0; y = 0;
  131.         w = (pcx_w / 16); h = (pcx_h / 16);
  132.         break;
  133.     case 2:
  134.         x = 0; y = 0;
  135.         w = val[0]; h = val[1];
  136.         if (((w * 16) > pcx_w) || ((h * 16) > pcx_h)) {
  137.             error("Index out of range!");
  138.             return;
  139.         }
  140.         break;
  141.     case 4:
  142.         x = val[0]; y = val[1];
  143.         w = val[2]; h = val[3];
  144.         if (((x + w * 16) > pcx_w) || ((y + h * 16) > pcx_h)) {
  145.             error("Index out of range!");
  146.             return;
  147.         }
  148.         break;
  149.     }
  150.     if (pass == LAST_PASS) {
  151.         for (i = 0; i < h; i++) {
  152.             for (j = 0; j < w; j++) {
  153.                 ptr = pcx_buf + (x + (j * 16)) + ((y + (i * 16)) * pcx_w);
  154.                 for (k = 0; k < 16; k++) {
  155.                     a = 0; b = 0;
  156.                     c = 0; d = 0;
  157.                     for (l = 0; l < 8; l++) {
  158.                         e = ptr[l + 8]; f = ptr[l];
  159.                         a = (a << 1) | ((e & 0x01))      | ((f & 0x01) << 8);
  160.                         b = (b << 1) | ((e & 0x02) >> 1) | ((f & 0x02) << 7);
  161.                         c = (c << 1) | ((e & 0x04) >> 2) | ((f & 0x04) << 6);
  162.                         d = (d << 1) | ((e & 0x08) >> 3) | ((f & 0x08) << 5);
  163.                     }                
  164.                     buffer[k     ] = a;
  165.                     buffer[k + 16] = b;
  166.                     buffer[k + 32] = c;
  167.                     buffer[k + 48] = d;
  168.                     ptr += pcx_w;
  169.                 }
  170.                 copy_buffer(128);
  171.             }
  172.         }
  173.     }
  174.     else
  175.         copy_buffer(128 * w * h);
  176. }
  177.  
  178. /*  convert a pcx to palette  */
  179.  
  180. int do_pal(int n, unsigned int *val)
  181. {
  182.     int i, start, nb;
  183.     int r, g, b;
  184.  
  185.     switch (n) {
  186.     case 0:
  187.         start = 0;
  188.         nb = 256;
  189.         break;
  190.     case 1:
  191.         if (val[0] > 15) {
  192.             error("Index out of range!");
  193.             return;
  194.         }
  195.         start = val[0] << 4;
  196.         nb = 16;
  197.         break;
  198.     case 2:
  199.         if (((val[0] + val[1]) > 16) || (val[1] == 0)) {
  200.             error("Index out of range!");
  201.             return;
  202.         }
  203.         start = val[0] << 4;
  204.         nb = val[1] << 4;
  205.         break;
  206.     }
  207.     if (pass == LAST_PASS) {
  208.         for (i = 0; i < nb; i++) {
  209.             r = pcx_pal[start + i][0];
  210.             g = pcx_pal[start + i][1];
  211.             b = pcx_pal[start + i][2];
  212.             buffer[i] = ((r & 0xE0) >> 2) | ((g & 0xE0) << 1) | ((b & 0xE0) >> 5);
  213.         }
  214.     }
  215.     copy_buffer(nb << 1);
  216. }
  217.  
  218. /* copy a buffer to the current location */
  219.  
  220. copy_buffer(int size)
  221. {
  222.     if (((bank << 13) + loccnt + size) > (8192 * 128)) {
  223.         error("File too big!");
  224.         return;
  225.     }
  226.     if (pass == LAST_PASS) {
  227.         memcpy(&rom[bank][loccnt], buffer, size);
  228.     }
  229.     bank  += (loccnt + size) >> 13;
  230.     loccnt = (loccnt + size) & 0x1FFF;
  231.     if (bank > max_bank) {
  232.         if (loccnt)
  233.             max_bank = bank;
  234.         else
  235.             max_bank = bank - 1;
  236.     }
  237. }
  238.  
  239. /*  load a pcx image and unpack it  */
  240.  
  241. int load_pcx(char *name)
  242. {
  243.     int   i, c, x, y, w, h;
  244.     char *ptr;
  245.     FILE *f;
  246.  
  247.     if (!strcmp(pcx_name, name) && strlen(name))
  248.         return (1);
  249.     else {
  250.         if (pcx_buf)
  251.             free(pcx_buf);
  252.         pcx_buf = NULL;
  253.         pcx_name[0] = '\0';
  254.     }
  255.     if ((f = fopen(name, "rb")) == NULL) {
  256.         error("Can not open file!");
  257.         return (0);
  258.     }
  259.     fread(&pcx, 128, 1, f);
  260.     x = 0;
  261.     y = 0;
  262.     pcx_w = (pcx.xmax - pcx.xmin + 1);
  263.     pcx_h = (pcx.ymax - pcx.ymin + 1);
  264.     if ((pcx_w <= 640) && (pcx_h <= 480) && (pcx_w >= 16) && (pcx_h >= 16)) {
  265.         pcx_buf = malloc(pcx_w * pcx_h);
  266.         if ((pcx.encoding == 1) && (pcx.bpp == 8) && (pcx.np == 1) && (pcx_buf)) {
  267.             strcpy(pcx_name, name);
  268.             ptr = pcx_buf;
  269.             do {
  270.                 c = fgetc(f);
  271.                 if (c == EOF)
  272.                     break;
  273.                 if ((c & 0xC0) == 0xC0) {
  274.                     i = (c & 0x3F);
  275.                     c = fgetc(f);
  276.                 } else
  277.                     i = 1;
  278.                 do {
  279.                     *ptr++ = c;
  280.                     x++;
  281.                     if (x == pcx_w) {
  282.                         x = 0;
  283.                         y++;
  284.                     }
  285.                 } while (--i);
  286.             } while (y < pcx_h);
  287.             if (c != EOF)
  288.                 c = fgetc(f);
  289.             while ((c != 12) && (c != EOF))
  290.                 c = fgetc(f);
  291.             if (c == 12)
  292.                 fread(pcx_pal, 768, 1, f);
  293.             fclose(f);
  294.             return (1);
  295.         }
  296.     }
  297.     fclose(f);
  298.     if (pcx_buf)
  299.         error("Can not load file, invalid format!");
  300.     else
  301.         error("Can not load file, not enough memory!");
  302.     return (0);
  303. }
  304.  
  305.