1 /*
2 	Scaled sprite code.
3 */
4 
5 
6 #include "types.h"
7 #include "sprite.h"
8 
9 
10 
11 
12 static int screenwidth = 16;
13 static int screenheight = 16;
14 
15 
16 static int s_pos;
17 static int g_scale;
18 static int g_step;
19 
20 
21 // Returns 1 if end of screen was reached.
scale_span(char * dest,int x,char * src,int width)22 static int scale_span(char *dest, int x, char *src, int width){
23 
24 	int ss_pos = s_pos & 255;
25 
26 	if(x >= screenwidth) return 1;
27 	if(x < 0){
28 		// Start left of screen
29 		ss_pos -= (x*g_step);
30 		x = 0;
31 	}
32 
33 	while(ss_pos/256<width && x<screenwidth){
34 		dest[x] = src[ss_pos/256];
35 		ss_pos += g_step;
36 		++x;
37 	}
38 	return x>=screenwidth;
39 }
40 
41 
42 
43 // Dest = pointer to line in screen
scale_line(int x_pos,unsigned long * linedata,char * dest)44 static void scale_line(int x_pos, unsigned long * linedata, char *dest){
45 	unsigned long clearcount, viscount;
46 
47 	if(x_pos/256 >= screenwidth) return;
48 
49 	for(;;){
50 		clearcount = *linedata;
51 		linedata++;
52 		x_pos += clearcount * g_scale;
53 		s_pos += clearcount * g_step;
54 
55 		viscount = *linedata;
56 		if(viscount<1) return;
57 		linedata++;
58 		if(scale_span(dest, x_pos/256, (void*)linedata, viscount)) return;
59 
60 		x_pos += viscount * g_scale;
61 		s_pos += viscount * g_step;
62 
63 		linedata += (viscount+3) / 4;
64 	}
65 }
66 
67 
68 
69 
putsprite_scaled(int x,int y,s_sprite * frame,s_screen * screen,int scale)70 void putsprite_scaled(int x, int y, s_sprite *frame, s_screen *screen, int scale){
71 	int top, left, bottom;
72 	unsigned long *linetab;
73 	unsigned long *linedata;
74 	int curline;
75 	int line_pos;
76 	// int pix_pos; unused variable, makes a warning
77 	char *destline;
78 
79 	if(scale==256){
80 		putsprite(x, y, frame, screen);
81 		return;
82 	}
83 
84 	if(scale <= 0) return;
85 	g_step = (256*256) / scale;
86 	if(g_step <= 0) return;
87 	g_scale = scale;
88 
89 	// Get screen size
90 	screenwidth = screen->width;
91 	screenheight = screen->height;
92 
93 	left = x*256 - frame->centerx*scale;
94 	top = y - ((frame->centery * scale)/256);
95 	bottom = top + ((frame->height * scale)/256);
96 
97 	// Bottom = line _under_ sprite!
98 	if(top>=bottom) return;
99 
100 	line_pos = g_step/2;
101 	if(top<0){
102 		line_pos = -top * g_step;
103 		top = 0;
104 	}
105 	if(bottom > screenheight){
106 		bottom = screenheight;
107 	}
108 
109 	destline = screen->data + top*screenwidth;
110 	linetab = (void*)frame->data;
111 	do{
112 		// Get ready to draw a line
113 		curline = (line_pos/256);
114 		linedata = linetab + curline + (linetab[curline] / 4);
115 		line_pos += g_step;
116 
117 		s_pos = g_step/2;
118 
119 		scale_line(left, linedata, destline);
120 		destline += screenwidth;
121 	}while((++top) < bottom);
122 }
123 
124 
125