1 /* $Id: ibitblt.c,v 1.4 2002-07-17 21:55:19 bradleyb Exp $ */
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
15 * Routines to to inverse bitblitting -- well not really.
16 * We don't inverse bitblt like in the PC, but this code
17 * does set up a structure that blits around the cockpit
31 //added 05/17/99 Matt Mueller
38 #define MAX_WIDTH 1280
39 #define MAX_SCANLINES 1024
42 static short start_points[MAX_SCANLINES][MAX_HOLES];
43 static short hole_length[MAX_SCANLINES][MAX_HOLES];
44 static double *scanline = NULL;
46 // adb: gr_linear_movsd assumes c >= 4
47 #define gr_linear_movsd(s,d,c) memcpy(d,s,c)
49 void gr_ibitblt(grs_bitmap *src_bmp, grs_bitmap *dest_bmp, ubyte pixel_double)
51 int x, y, sw, sh, srowsize, drowsize, dstart, sy, dy;
53 short *current_hole, *current_hole_length;
59 srowsize = src_bmp->bm_rowsize;
60 drowsize = dest_bmp->bm_rowsize;
61 src = src_bmp->bm_data;
62 dest = dest_bmp->bm_data;
65 while (start_points[sy][0] == -1) {
71 ubyte *scan = (ubyte *)scanline; // set up for byte processing of scanline
74 for (y = sy; y < sy + sh; y++) {
75 gr_linear_rep_movsd_2x(src, scan, sw);
76 current_hole = start_points[dy];
77 current_hole_length = hole_length[dy];
78 for (x = 0; x < MAX_HOLES; x++) {
79 if (*current_hole == -1)
81 dstart = *current_hole;
82 gr_linear_movsd(&(scan[dstart]), &(dest[dstart]), *current_hole_length);
84 current_hole_length++;
88 current_hole = start_points[dy];
89 current_hole_length = hole_length[dy];
90 for (x = 0;x < MAX_HOLES; x++) {
91 if (*current_hole == -1)
93 dstart = *current_hole;
94 gr_linear_movsd(&(scan[dstart]), &(dest[dstart]), *current_hole_length);
96 current_hole_length++;
103 Assert(sw <= MAX_WIDTH);
104 Assert(sh <= MAX_SCANLINES);
105 for (y = sy; y < sy + sh; y++) {
106 for (x = 0; x < MAX_HOLES; x++) {
107 if (start_points[y][x] == -1)
109 dstart = start_points[y][x];
110 gr_linear_movsd(&(src[dstart]), &(dest[dstart]), hole_length[y][x]);
118 void gr_ibitblt_create_mask(grs_bitmap *mask_bmp, int sx, int sy, int sw, int sh, int srowsize)
124 Assert( (!(mask_bmp->bm_flags&BM_FLAG_RLE)) );
126 for (y = 0; y < MAX_SCANLINES; y++) {
127 for (x = 0; x < MAX_HOLES; x++) {
128 start_points[y][x] = -1;
129 hole_length[y][x] = -1;
133 for (y = sy; y < sy+sh; y++) {
136 for (x = sx; x < sx + sw; x++) {
137 if ((mode == FIND_START) && (mask_bmp->bm_data[mask_bmp->bm_rowsize*y+x] == TRANSPARENCY_COLOR)) {
138 start_points[y][count] = x;
140 } else if ((mode == FIND_STOP) && (mask_bmp->bm_data[mask_bmp->bm_rowsize*y+x] != TRANSPARENCY_COLOR)) {
141 hole_length[y][count] = x - start_points[y][count];
146 if (mode == FIND_STOP) {
147 hole_length[y][count] = x - start_points[y][count];
150 Assert(count <= MAX_HOLES);
154 //added 7/11/99 by adb to prevent memleaks
155 static void free_scanline(void)
157 if (scanline) d_free(scanline);
159 //end additions - adb
162 void gr_ibitblt_find_hole_size(grs_bitmap *mask_bmp, int *minx, int *miny, int *maxx, int *maxy)
167 Assert( (!(mask_bmp->bm_flags&BM_FLAG_RLE)) );
168 Assert( mask_bmp->bm_flags&BM_FLAG_TRANSPARENT );
170 *minx = mask_bmp->bm_w - 1;
172 *miny = mask_bmp->bm_h - 1;
175 //changed 7/11/99 by adb to prevent memleaks
176 if (scanline == NULL) {
177 scanline = (double *)d_malloc(sizeof(double) * (MAX_WIDTH / sizeof(double)));
178 atexit(free_scanline);
182 for (y = 0; y < mask_bmp->bm_h; y++) {
183 for (x = 0; x < mask_bmp->bm_w; x++) {
184 c = mask_bmp->bm_data[mask_bmp->bm_rowsize*y+x];
185 if (c == TRANSPARENCY_COLOR) { // don't look for transparency color here.
187 if (x < *minx) *minx = x;
188 if (y < *miny) *miny = y;
189 if (x > *maxx) *maxx = x;
190 if (y > *maxy) *maxy = y;