summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/csh3blit.c
blob: e30a6f5fbff6eecff13b9b91c378724dcaa0fcf2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
// #included multiple times from cavesh3.c

#ifdef FLIPX
#define LOOP_INCREMENTS \
			bmp++;  \
			gfx2--; \

#else

#define LOOP_INCREMENTS \
			bmp++;  \
			gfx2++; \

#endif

const void FUNCNAME(bitmap_t *bitmap,
					 const rectangle *clip,
					 UINT32 *gfx,
					 int src_x,
					 int src_y,
					 int dst_x_start,
					 int dst_y_start,
					 int dimx,
					 int dimy,
					 int flipy,
					 const UINT8 s_alpha,
					 const UINT8 d_alpha,
					// int tint,
					 clr_t *tint_clr )
{


	UINT32* gfx2;
	int y, yf;

#ifndef REALLY_SIMPLE
	colour_t s_clr;
#endif

#ifdef BLENDED
	colour_t d_clr;

#if _SMODE == 2
#if _DMODE != 0
	colour_t clr0;
#endif
#elif _SMODE == 0
#if _DMODE != 0
#if _DMODE != 5
#if _DMODE != 1
	colour_t clr0;
#endif
#endif
#endif
#else
	colour_t clr0;
#endif


#endif

#ifdef REALLY_SIMPLE
#if TRANSPARENT == 1
	UINT32 pen;
#endif
#else
	UINT32 pen;
#endif
	UINT32 *bmp;

#ifdef FLIPX
	src_x += (dimx-1);
#endif

	if (flipy)	{	yf = -1;	src_y += (dimy-1);	}
	else		{	yf = +1;						}

	int starty = 0;
	int dst_y_end = dst_y_start+dimy;

	if (dst_y_start < clip->min_y)
		starty = clip->min_y - dst_y_start;

	if (dst_y_end > clip->max_y)
		dimy -= (dst_y_end-1) - clip->max_y;

	// check things are safe to draw (note, if the source would wrap round an edge of the 0x2000*0x1000 vram we don't draw.. not sure what the hw does anyway)
#ifdef FLIPX
	if ((src_x &0x1fff) < ((src_x-(dimx-1))&0x1fff))
	{
		printf("sprite gets clipped off src_x %04x dimx %04x\n", src_x, dimx);
		return;
	}
#else
	if ((src_x &0x1fff) > ((src_x+(dimx-1))&0x1fff))
	{
		printf("sprite gets clipped off src_x %04x dimx %04x\n", src_x, dimx);
		return;
	}
#endif

	int startx = 0;
	int dst_x_end = dst_x_start+dimx;

	if (dst_x_start < clip->min_x)
		startx = clip->min_x - dst_x_start;

	if (dst_x_end > clip->max_x)
		dimx -= (dst_x_end-1) - clip->max_x;


#ifdef BLENDED
#if _SMODE == 0
#if _DMODE == 0
	UINT8* salpha_table = cavesh3_colrtable[s_alpha];
	UINT8* dalpha_table = cavesh3_colrtable[d_alpha];
#endif

#if _DMODE == 5
	UINT8* salpha_table = cavesh3_colrtable[s_alpha];
#endif
#if _DMODE == 1
	UINT8* salpha_table = cavesh3_colrtable[s_alpha];
#endif

#endif

#if _SMODE == 2
#if _DMODE == 0

	UINT8* dalpha_table = cavesh3_colrtable[d_alpha];
#endif
#endif
#endif



	for (y = starty; y < dimy; y++)
	{
		bmp = BITMAP_ADDR32(bitmap, dst_y_start + y, dst_x_start+startx);
		int ysrc_index =  ((src_y + yf * y) & 0x0fff) * 0x2000;
		gfx2 = gfx + ysrc_index;

		#ifdef FLIPX
			gfx2 += (src_x-startx);
		#else
			gfx2 += (src_x+startx);
		#endif

		const UINT32* end = bmp+(dimx-startx);


		while (bmp<end)
		{




/*************** REALLY SIMPLE INNER LOOP, NON-BLENDED, NON-TINTED, SIMPLEST CASE ****************/
#ifdef REALLY_SIMPLE

#if TRANSPARENT == 1
			pen = *gfx2;
			if (pen & 0x20000000)
			{
			*bmp = pen;
#else
			*bmp = *gfx2;
#endif

/*************** REGULAR INNER LOOPS ****************/
#else // NOT REALLY_SIMPLE

			pen = *gfx2;

#if TRANSPARENT == 1
			if (pen & 0x20000000)
			{
#endif

			// convert source to clr
			pen_to_clr(pen, &s_clr.trgb);
			//s_clr.u32 = (pen >> 3); // using the union is actually significantly slower than our pen_to_clr to function!
			// source * intesity and clamp

#ifdef TINT
			clr_mul(&s_clr.trgb, tint_clr);
#endif

			#ifdef BLENDED

				// convert destination to clr
				pen_to_clr(*bmp, &d_clr.trgb);
                //d_clr.u32 = *bmp >> 3; // using the union is actually significantly slower than our pen_to_clr to function!
				#if _SMODE == 0
				//g_profiler.start(PROFILER_USER7);


					#if _DMODE == 0
					//g_profiler.start(PROFILER_USER1);
					// this is used extensively in the games (ingame, futari title screens etc.)

					s_clr.trgb.r = cavesh3_colrtable_add[salpha_table[(s_clr.trgb.r)]][dalpha_table[(d_clr.trgb.r)]];
					s_clr.trgb.g = cavesh3_colrtable_add[salpha_table[(s_clr.trgb.g)]][dalpha_table[(d_clr.trgb.g)]];
					s_clr.trgb.b = cavesh3_colrtable_add[salpha_table[(s_clr.trgb.b)]][dalpha_table[(d_clr.trgb.b)]];
					#elif _DMODE == 1
					//g_profiler.start(PROFILER_USER2);
					// futari ~7%
					s_clr.trgb.r = cavesh3_colrtable_add[salpha_table[(s_clr.trgb.r)]][cavesh3_colrtable[(s_clr.trgb.r)][(d_clr.trgb.r)]];
					s_clr.trgb.g = cavesh3_colrtable_add[salpha_table[(s_clr.trgb.g)]][cavesh3_colrtable[(s_clr.trgb.g)][(d_clr.trgb.g)]];
					s_clr.trgb.b = cavesh3_colrtable_add[salpha_table[(s_clr.trgb.b)]][cavesh3_colrtable[(s_clr.trgb.b)][(d_clr.trgb.b)]];
					#elif _DMODE == 2
					//g_profiler.start(PROFILER_USER3);
					clr_mul_fixed(&clr0.trgb, s_alpha, &s_clr.trgb);
					clr_add_with_clr_square(&s_clr.trgb, &clr0.trgb, &d_clr.trgb);
					#elif _DMODE == 3
					//g_profiler.start(PROFILER_USER4);
					clr_mul_fixed(&clr0.trgb, s_alpha, &s_clr.trgb);
					clr_add(&s_clr.trgb, &s_clr.trgb, &d_clr.trgb);

					#elif _DMODE == 4
					//g_profiler.start(PROFILER_USER5);
					clr_mul_fixed(&clr0.trgb, s_alpha, &s_clr.trgb);
					clr_add_with_clr_mul_fixed_rev(&s_clr.trgb, &clr0.trgb, d_alpha, &d_clr.trgb);
					#elif _DMODE == 5
					// futari black character select ~13%
					//g_profiler.start(PROFILER_USER6);
					s_clr.trgb.r =  cavesh3_colrtable_add[salpha_table[(s_clr.trgb.r)]][cavesh3_colrtable_rev[(s_clr.trgb.r)][(d_clr.trgb.r)]];
					s_clr.trgb.g =  cavesh3_colrtable_add[salpha_table[(s_clr.trgb.g)]][cavesh3_colrtable_rev[(s_clr.trgb.g)][(d_clr.trgb.g)]];
					s_clr.trgb.b =  cavesh3_colrtable_add[salpha_table[(s_clr.trgb.b)]][cavesh3_colrtable_rev[(s_clr.trgb.b)][(d_clr.trgb.b)]];

					#elif _DMODE == 6
					//g_profiler.start(PROFILER_USER7);
					clr_mul_fixed(&clr0.trgb, s_alpha, &s_clr.trgb);
					clr_add_with_clr_mul_rev_square(&s_clr.trgb, &clr0.trgb, &d_clr.trgb);
					#elif _DMODE == 7
					//g_profiler.start(PROFILER_USER8);
					clr_mul_fixed(&clr0.trgb, s_alpha, &s_clr.trgb);
					clr_add(&s_clr.trgb, &s_clr.trgb, &d_clr.trgb);
					#endif

				//g_profiler.stop();
				#elif _SMODE == 1
				//g_profiler.start(PROFILER_USER6);
				clr_square(&clr0.trgb, &s_clr.trgb);

				#elif _SMODE == 2
			//  g_profiler.start(PROFILER_USER4);
					#if _DMODE == 0
					// this is used heavily on espgal2 highscore screen (~28%) optimized to avoid use of temp clr0 variable
					s_clr.trgb.r = cavesh3_colrtable_add[cavesh3_colrtable[(d_clr.trgb.r)][(s_clr.trgb.r)]][dalpha_table[(d_clr.trgb.r)]];
					s_clr.trgb.g = cavesh3_colrtable_add[cavesh3_colrtable[(d_clr.trgb.g)][(s_clr.trgb.g)]][dalpha_table[(d_clr.trgb.g)]];
					s_clr.trgb.b = cavesh3_colrtable_add[cavesh3_colrtable[(d_clr.trgb.b)][(s_clr.trgb.b)]][dalpha_table[(d_clr.trgb.b)]];
					#elif _DMODE == 1
					clr_mul_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
					clr_add_with_clr_mul_3param(&s_clr.trgb, &clr0.trgb, &d_clr.trgb, &s_clr.trgb);
					#elif _DMODE == 2
					clr_mul_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
					clr_add_with_clr_square(&s_clr.trgb, &clr0.trgb, &d_clr.trgb);
					#elif _DMODE == 3
					clr_mul_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
					clr_add(&s_clr.trgb, &s_clr.trgb, &d_clr.trgb);

					#elif _DMODE == 4
					clr_mul_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
					clr_add_with_clr_mul_fixed_rev(&s_clr.trgb, &clr0.trgb, d_alpha, &d_clr.trgb);
					#elif _DMODE == 5
					clr_mul_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
					clr_add_with_clr_mul_rev_3param(&s_clr.trgb, &clr0.trgb, &d_clr.trgb, &s_clr.trgb);
					#elif _DMODE == 6
					clr_mul_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
					clr_add_with_clr_mul_rev_square(&s_clr.trgb, &clr0.trgb, &d_clr.trgb);
					#elif _DMODE == 7
					clr_mul_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
					clr_add(&s_clr.trgb, &s_clr.trgb, &d_clr.trgb);
					#endif
				//g_profiler.stop();

				#elif _SMODE == 3
				//g_profiler.start(PROFILER_USER1);
				clr_copy(&clr0.trgb, &s_clr.trgb);

				#elif _SMODE == 4
				//g_profiler.start(PROFILER_USER2);
				clr_mul_fixed_rev(&clr0.trgb, s_alpha, &s_clr.trgb);
				#elif _SMODE == 5
				//g_profiler.start(PROFILER_USER3);
				clr_mul_rev_square(&clr0.trgb, &s_clr.trgb);
				#elif _SMODE == 6
				//g_profiler.start(PROFILER_USER4);
				clr_mul_rev_3param(&clr0.trgb, &s_clr.trgb, &d_clr.trgb);
				#elif _SMODE == 7
				//g_profiler.start(PROFILER_USER5);
				clr_copy(&clr0.trgb, &s_clr.trgb);
				#endif


// smode 0/2 cases are already split up and handled above.
#if _SMODE != 2
#if _SMODE != 0

				#if _DMODE == 0
				clr_add_with_clr_mul_fixed(&s_clr.trgb, &clr0.trgb, d_alpha, &d_clr.trgb);
				#elif _DMODE == 1
				clr_add_with_clr_mul_3param(&s_clr.trgb, &clr0.trgb, &d_clr.trgb, &s_clr.trgb);
				#elif _DMODE == 2
				clr_add_with_clr_square(&s_clr.trgb, &clr0.trgb, &d_clr.trgb);
				#elif _DMODE == 3
				clr_add(&s_clr.trgb, &s_clr.trgb, &d_clr.trgb);

				#elif _DMODE == 4
				clr_add_with_clr_mul_fixed_rev(&s_clr.trgb, &clr0.trgb, d_alpha, &d_clr.trgb);
				#elif _DMODE == 5
				clr_add_with_clr_mul_rev_3param(&s_clr.trgb, &clr0.trgb, &d_clr.trgb, &s_clr.trgb);
				#elif _DMODE == 6
				clr_add_with_clr_mul_rev_square(&s_clr.trgb, &clr0.trgb, &d_clr.trgb);
				#elif _DMODE == 7
				clr_add(&s_clr.trgb, &s_clr.trgb, &d_clr.trgb);
				#endif

				//g_profiler.stop();
#endif
#endif


			#endif

			// write result
			*bmp = clr_to_pen(&s_clr.trgb)|(pen&0x20000000);
			//*bmp = (s_clr.u32<<3)|(pen&0x20000000); // using the union is actually significantly slower than our clr_to_pen function!

#endif // END NOT REALLY SIMPLE

#if TRANSPARENT == 1
			}
#endif
			LOOP_INCREMENTS
		}

	}

//  g_profiler.stop();
}

#undef LOOP_INCREMENTS