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