home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / toollib_2 / Examples / GFXView / Builds / c / sprite_pic < prev    next >
Encoding:
Text File  |  1995-12-06  |  4.7 KB  |  170 lines

  1. /*** sprite_pic.c ***/
  2. /* Routines for loading and displaying a sprite
  3.  * (c) Paul Field 1995
  4.  */
  5.  
  6.  
  7. #include "sprite_pic.h"
  8.  
  9. #include <assert.h>
  10. #include "colourtrans.h"
  11. #include "osspriteop.h"
  12. #include "osfile.h"
  13. #include "wimp.h"
  14. #include "wimpreadsysinfo.h"
  15.  
  16. #include "allocate.h"
  17. #include "exception.h"
  18. #include "shifting.h"
  19.  
  20.  
  21.  
  22. struct sprite_pic_str
  23.  { osspriteop_area *sprite;
  24.  };
  25.  
  26.  
  27.  
  28.  
  29. sprite_pic *sprite_pic_create(const char *file_name)
  30.  { int        size;
  31.    bits       file_type;
  32.    sprite_pic *pic;
  33.  
  34.    osfile_read_stamped_no_path(file_name, NULL, NULL, &size, NULL, &file_type);
  35.    assert(file_type == osfile_TYPE_SPRITE);
  36.  
  37.    /* Sprite files miss off part of the sprite area header
  38.     * so add this missing bit to the file size to give the amount of memory we need
  39.     */
  40.    size += offsetof(osspriteop_area, sprite_count);
  41.  
  42.    pic = memory_allocate(sizeof(*pic));
  43.    pic->sprite = NULL;   /* It's OK to 'free' a NULL */
  44.  
  45.    try
  46.     { shifting_allocate((shifting_ptr)&pic->sprite, size);
  47.  
  48.       pic->sprite->size         = size;
  49.       pic->sprite->sprite_count = 0;
  50.       pic->sprite->first        = sizeof(osspriteop_area);
  51.       pic->sprite->used         = pic->sprite->first;
  52.       osspriteop_load_sprite_file(osspriteop_USER_AREA, pic->sprite, file_name);
  53.     }
  54.    catch
  55.     { sprite_pic_destroy(pic);
  56.       throw();
  57.     }
  58.    catch_end
  59.  
  60.    return pic;
  61.  }
  62.  
  63.  
  64.  
  65.  
  66. void sprite_pic_destroy(sprite_pic *pic)
  67.  { if (pic != NULL)
  68.     { shifting_free((shifting_ptr)&pic->sprite);
  69.       memory_free(pic);
  70.     }
  71.  }
  72.  
  73.  
  74.  
  75.  
  76. void sprite_pic_draw(const sprite_pic *pic, int origin_x, int origin_y, unsigned scale_percent, const os_box *clip)
  77.  { osspriteop_header                     *sprite;
  78.    os_factors                            scale_factors;
  79.    osspriteop_TRANS_TAB(256*sizeof(int)) colour_translation;  /* The largest possible translation table */
  80.    int                             log2_bpp;
  81.    bool                                  wide_translation_entries;
  82.  
  83.    assert(pic != NULL);
  84.    NOT_USED(clip);
  85.  
  86.    sprite = (osspriteop_header *)((byte *)pic->sprite + pic->sprite->first);
  87.  
  88.    /* Find out how the Wimp would plot the sprite */
  89.    /* This gives us scale factors and a colour translation table.
  90.     * The translation table assumes that palette-less sprites use desktop
  91.     * colours - colourtrans assumes the default palette
  92.     */
  93.    wimp_read_pix_trans
  94.     ( osspriteop_PTR,
  95.       pic->sprite,
  96.       (osspriteop_id) sprite,
  97.       &scale_factors,
  98.       (osspriteop_trans_tab *) &colour_translation
  99.     );
  100.    wide_translation_entries = FALSE;
  101.  
  102.  
  103.    /* The wimp gives an undefined colour translation table for 8 bits-per-pixel and above modes
  104.     * so we ask colourtrans for help.
  105.     */
  106.    os_read_mode_variable(sprite->mode, os_MODEVAR_LOG2_BPP, &log2_bpp);
  107.    if (log2_bpp >= 3)
  108.     { /* Wide translation table entries are available in RISC OS 3.5 and above
  109.        * but we can only pass them to osspriteop_put_sprite_scaled() in RISC OS 3.6 and above
  110.        */
  111.       wide_translation_entries = (wimpreadsysinfo_version() >= 360);
  112.  
  113.       colourtrans_select_table_for_sprite
  114.        ( pic->sprite,
  115.          (osspriteop_id) sprite,
  116.          colourtrans_CURRENT_MODE,
  117.          colourtrans_CURRENT_PALETTE,
  118.          (osspriteop_trans_tab *) &colour_translation,
  119.          colourtrans_GIVEN_SPRITE + (wide_translation_entries ? colourtrans_RETURN_WIDE_ENTRIES : 0)
  120.        );
  121.     }
  122.  
  123.    /* Adjust scale factors to include the scale of scale_percent/100 */
  124.    scale_factors.xmul *= scale_percent;
  125.    scale_factors.xdiv *= 100;
  126.  
  127.    scale_factors.ymul *= scale_percent;
  128.    scale_factors.ydiv *= 100;
  129.  
  130.    /* Draw the sprite */
  131.    osspriteop_put_sprite_scaled
  132.     ( osspriteop_PTR,
  133.       pic->sprite,
  134.       (osspriteop_id) sprite,
  135.       origin_x,
  136.       origin_y,
  137.       os_ACTION_OVERWRITE + osspriteop_USE_MASK + (wide_translation_entries ? osspriteop_GIVEN_WIDE_ENTRIES : 0),
  138.       &scale_factors,
  139.       (osspriteop_trans_tab *) &colour_translation
  140.     );
  141.  }
  142.  
  143.  
  144.  
  145.  
  146. void sprite_pic_size(const sprite_pic *pic, unsigned *width, unsigned *height)
  147.  { osspriteop_id  sprite;
  148.    os_mode        mode;
  149.    int            sprite_width;
  150.    int            sprite_height;
  151.    int            x_eig;
  152.    int            y_eig;
  153.  
  154.    assert(pic != NULL);
  155.    assert(width != NULL);
  156.    assert(height != NULL);
  157.  
  158.    sprite = (osspriteop_id)((byte *)pic->sprite + pic->sprite->first);
  159.    osspriteop_read_sprite_size(osspriteop_PTR, pic->sprite, sprite, &sprite_width, &sprite_height, NULL, &mode);
  160.  
  161.    /* Read x_eig and y_eig for the sprite's mode so we can convert from pixels
  162.     * (the units of sprite_width and sprite_height) to OS units
  163.     */
  164.    os_read_mode_variable(mode, os_MODEVAR_XEIG_FACTOR, &x_eig);
  165.    os_read_mode_variable(mode, os_MODEVAR_YEIG_FACTOR, &y_eig);
  166.  
  167.    *width  = (sprite_width  << x_eig);
  168.    *height = (sprite_height << y_eig);
  169.  }
  170.