Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
8557 maxcodehac 1
// ID_VL.C
2
 
3
#include 
4
#include "wl_def.h"
5
#pragma hdrstop
6
 
7
// Uncomment the following line, if you get destination out of bounds
8
// assertion errors and want to ignore them during debugging
9
//#define IGNORE_BAD_DEST
10
 
11
#ifdef IGNORE_BAD_DEST
12
#undef assert
13
#define assert(x) if(!(x)) return
14
#define assert_ret(x) if(!(x)) return 0
15
#else
16
#define assert_ret(x) assert(x)
17
#endif
18
 
19
boolean fullscreen = true;
20
#if defined(_arch_dreamcast)
21
boolean usedoublebuffering = false;
22
unsigned screenWidth = 320;
23
unsigned screenHeight = 200;
24
unsigned screenBits = 8;
25
#elif defined(GP2X)
26
boolean usedoublebuffering = true;
27
unsigned screenWidth = 320;
28
unsigned screenHeight = 240;
29
#if defined(GP2X_940)
30
unsigned screenBits = 8;
31
#else
32
unsigned screenBits = 16;
33
#endif
34
#else
35
boolean usedoublebuffering = true;
36
unsigned screenWidth = 640;
37
unsigned screenHeight = 400;
38
unsigned screenBits = -1;      // use "best" color depth according to libSDL
39
#endif
40
 
41
SDL_Surface *screen = NULL;
42
unsigned screenPitch;
43
 
44
SDL_Surface *screenBuffer = NULL;
45
unsigned bufferPitch;
46
 
47
SDL_Surface *curSurface = NULL;
48
unsigned curPitch;
49
 
50
unsigned scaleFactor;
51
 
52
boolean	 screenfaded;
53
unsigned bordercolor;
54
 
55
SDL_Color palette1[256], palette2[256];
56
SDL_Color curpal[256];
57
 
58
 
59
#define CASSERT(x) extern int ASSERT_COMPILE[((x) != 0) * 2 - 1];
60
#define RGB(r, g, b) {(r)*255/63, (g)*255/63, (b)*255/63, 0}
61
 
62
SDL_Color gamepal[]={
63
#ifdef SPEAR
64
    #include "sodpal.inc"
65
#else
66
    #include "wolfpal.inc"
67
#endif
68
};
69
 
70
CASSERT(lengthof(gamepal) == 256)
71
 
72
//===========================================================================
73
 
74
 
75
/*
76
=======================
77
=
78
= VL_Shutdown
79
=
80
=======================
81
*/
82
 
83
void	VL_Shutdown (void)
84
{
85
	//VL_SetTextMode ();
86
}
87
 
88
 
89
/*
90
=======================
91
=
92
= VL_SetVGAPlaneMode
93
=
94
=======================
95
*/
96
 
97
void	VL_SetVGAPlaneMode (void)
98
{
99
#ifdef SPEAR
100
    SDL_WM_SetCaption("Spear of Destiny", NULL);
101
#else
102
    SDL_WM_SetCaption("Wolfenstein 3D", NULL);
103
#endif
104
 
105
    if(screenBits == -1)
106
    {
107
        const SDL_VideoInfo *vidInfo = SDL_GetVideoInfo();
108
        screenBits = vidInfo->vfmt->BitsPerPixel;
109
    }
110
 
111
    screen = SDL_SetVideoMode(screenWidth, screenHeight, screenBits,
112
          (usedoublebuffering ? SDL_HWSURFACE | SDL_DOUBLEBUF : 0)
113
        | (screenBits == 8 ? SDL_HWPALETTE : 0)
114
        | (fullscreen ? SDL_FULLSCREEN : 0));
115
    if(!screen)
116
    {
117
        printf("Unable to set %ix%ix%i video mode: %s\n", screenWidth,
118
            screenHeight, screenBits, SDL_GetError());
119
        exit(1);
120
    }
121
    if((screen->flags & SDL_DOUBLEBUF) != SDL_DOUBLEBUF)
122
        usedoublebuffering = false;
123
    SDL_ShowCursor(SDL_DISABLE);
124
 
125
    SDL_SetColors(screen, gamepal, 0, 256);
126
    memcpy(curpal, gamepal, sizeof(SDL_Color) * 256);
127
 
128
    screenBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, screenWidth,
129
        screenHeight, 8, 0, 0, 0, 0);
130
    if(!screenBuffer)
131
    {
132
        printf("Unable to create screen buffer surface: %s\n", SDL_GetError());
133
        exit(1);
134
    }
135
    SDL_SetColors(screenBuffer, gamepal, 0, 256);
136
 
137
    screenPitch = screen->pitch;
138
    bufferPitch = screenBuffer->pitch;
139
 
140
    curSurface = screenBuffer;
141
    curPitch = bufferPitch;
142
 
143
    scaleFactor = screenWidth/320;
144
    if(screenHeight/200 < scaleFactor) scaleFactor = screenHeight/200;
145
 
146
    pixelangle = (short *) malloc(screenWidth * sizeof(short));
147
    CHECKMALLOCRESULT(pixelangle);
148
    wallheight = (int *) malloc(screenWidth * sizeof(int));
149
    CHECKMALLOCRESULT(wallheight);
150
}
151
 
152
/*
153
=============================================================================
154
 
155
						PALETTE OPS
156
 
157
		To avoid snow, do a WaitVBL BEFORE calling these
158
 
159
=============================================================================
160
*/
161
 
162
/*
163
=================
164
=
165
= VL_ConvertPalette
166
=
167
=================
168
*/
169
 
170
void VL_ConvertPalette(byte *srcpal, SDL_Color *destpal, int numColors)
171
{
172
    for(int i=0; i
173
    {
174
        destpal[i].r = *srcpal++ * 255 / 63;
175
        destpal[i].g = *srcpal++ * 255 / 63;
176
        destpal[i].b = *srcpal++ * 255 / 63;
177
    }
178
}
179
 
180
/*
181
=================
182
=
183
= VL_FillPalette
184
=
185
=================
186
*/
187
 
188
void VL_FillPalette (int red, int green, int blue)
189
{
190
    int i;
191
    SDL_Color pal[256];
192
 
193
    for(i=0; i<256; i++)
194
    {
195
        pal[i].r = red;
196
        pal[i].g = green;
197
        pal[i].b = blue;
198
    }
199
 
200
    VL_SetPalette(pal, true);
201
}
202
 
203
//===========================================================================
204
 
205
/*
206
=================
207
=
208
= VL_SetColor
209
=
210
=================
211
*/
212
 
213
void VL_SetColor	(int color, int red, int green, int blue)
214
{
215
    SDL_Color col = { red, green, blue };
216
    curpal[color] = col;
217
 
218
    if(screenBits == 8)
219
        SDL_SetPalette(screen, SDL_PHYSPAL, &col, color, 1);
220
    else
221
    {
222
        SDL_SetPalette(curSurface, SDL_LOGPAL, &col, color, 1);
223
        SDL_BlitSurface(curSurface, NULL, screen, NULL);
224
        SDL_Flip(screen);
225
    }
226
}
227
 
228
//===========================================================================
229
 
230
/*
231
=================
232
=
233
= VL_GetColor
234
=
235
=================
236
*/
237
 
238
void VL_GetColor	(int color, int *red, int *green, int *blue)
239
{
240
    SDL_Color *col = &curpal[color];
241
    *red = col->r;
242
    *green = col->g;
243
    *blue = col->b;
244
}
245
 
246
//===========================================================================
247
 
248
/*
249
=================
250
=
251
= VL_SetPalette
252
=
253
=================
254
*/
255
 
256
void VL_SetPalette (SDL_Color *palette, bool forceupdate)
257
{
258
    memcpy(curpal, palette, sizeof(SDL_Color) * 256);
259
 
260
    if(screenBits == 8)
261
        SDL_SetPalette(screen, SDL_PHYSPAL, palette, 0, 256);
262
    else
263
    {
264
        SDL_SetPalette(curSurface, SDL_LOGPAL, palette, 0, 256);
265
        if(forceupdate)
266
        {
267
            SDL_BlitSurface(curSurface, NULL, screen, NULL);
268
            SDL_Flip(screen);
269
        }
270
    }
271
}
272
 
273
 
274
//===========================================================================
275
 
276
/*
277
=================
278
=
279
= VL_GetPalette
280
=
281
=================
282
*/
283
 
284
void VL_GetPalette (SDL_Color *palette)
285
{
286
    memcpy(palette, curpal, sizeof(SDL_Color) * 256);
287
}
288
 
289
 
290
//===========================================================================
291
 
292
/*
293
=================
294
=
295
= VL_FadeOut
296
=
297
= Fades the current palette to the given color in the given number of steps
298
=
299
=================
300
*/
301
 
302
void VL_FadeOut (int start, int end, int red, int green, int blue, int steps)
303
{
304
	int		    i,j,orig,delta;
305
	SDL_Color   *origptr, *newptr;
306
 
307
    red = red * 255 / 63;
308
    green = green * 255 / 63;
309
    blue = blue * 255 / 63;
310
 
311
	VL_WaitVBL(1);
312
	VL_GetPalette(palette1);
313
	memcpy(palette2, palette1, sizeof(SDL_Color) * 256);
314
 
315
//
316
// fade through intermediate frames
317
//
318
	for (i=0;i
319
	{
320
		origptr = &palette1[start];
321
		newptr = &palette2[start];
322
		for (j=start;j<=end;j++)
323
		{
324
			orig = origptr->r;
325
			delta = red-orig;
326
			newptr->r = orig + delta * i / steps;
327
			orig = origptr->g;
328
			delta = green-orig;
329
			newptr->g = orig + delta * i / steps;
330
			orig = origptr->b;
331
			delta = blue-orig;
332
			newptr->b = orig + delta * i / steps;
333
			origptr++;
334
			newptr++;
335
		}
336
 
337
		if(!usedoublebuffering || screenBits == 8) VL_WaitVBL(1);
338
		VL_SetPalette (palette2, true);
339
	}
340
 
341
//
342
// final color
343
//
344
	VL_FillPalette (red,green,blue);
345
 
346
	screenfaded = true;
347
}
348
 
349
 
350
/*
351
=================
352
=
353
= VL_FadeIn
354
=
355
=================
356
*/
357
 
358
void VL_FadeIn (int start, int end, SDL_Color *palette, int steps)
359
{
360
	int i,j,delta;
361
 
362
	VL_WaitVBL(1);
363
	VL_GetPalette(palette1);
364
	memcpy(palette2, palette1, sizeof(SDL_Color) * 256);
365
 
366
//
367
// fade through intermediate frames
368
//
369
	for (i=0;i
370
	{
371
		for (j=start;j<=end;j++)
372
		{
373
			delta = palette[j].r-palette1[j].r;
374
			palette2[j].r = palette1[j].r + delta * i / steps;
375
			delta = palette[j].g-palette1[j].g;
376
			palette2[j].g = palette1[j].g + delta * i / steps;
377
			delta = palette[j].b-palette1[j].b;
378
			palette2[j].b = palette1[j].b + delta * i / steps;
379
		}
380
 
381
		if(!usedoublebuffering || screenBits == 8) VL_WaitVBL(1);
382
		VL_SetPalette(palette2, true);
383
	}
384
 
385
//
386
// final color
387
//
388
	VL_SetPalette (palette, true);
389
	screenfaded = false;
390
}
391
 
392
/*
393
=============================================================================
394
 
395
							PIXEL OPS
396
 
397
=============================================================================
398
*/
399
 
400
byte *VL_LockSurface(SDL_Surface *surface)
401
{
402
    if(SDL_MUSTLOCK(surface))
403
    {
404
        if(SDL_LockSurface(surface) < 0)
405
            return NULL;
406
    }
407
    return (byte *) surface->pixels;
408
}
409
 
410
void VL_UnlockSurface(SDL_Surface *surface)
411
{
412
    if(SDL_MUSTLOCK(surface))
413
    {
414
        SDL_UnlockSurface(surface);
415
    }
416
}
417
 
418
/*
419
=================
420
=
421
= VL_Plot
422
=
423
=================
424
*/
425
 
426
void VL_Plot (int x, int y, int color)
427
{
428
    byte *ptr;
429
 
430
    assert(x >= 0 && (unsigned) x < screenWidth
431
            && y >= 0 && (unsigned) y < screenHeight
432
            && "VL_Plot: Pixel out of bounds!");
433
 
434
    ptr = VL_LockSurface(curSurface);
435
    if(ptr == NULL) return;
436
 
437
    ptr[y * curPitch + x] = color;
438
 
439
    VL_UnlockSurface(curSurface);
440
}
441
 
442
/*
443
=================
444
=
445
= VL_GetPixel
446
=
447
=================
448
*/
449
 
450
byte VL_GetPixel (int x, int y)
451
{
452
    byte *ptr;
453
    byte col;
454
 
455
    assert_ret(x >= 0 && (unsigned) x < screenWidth
456
            && y >= 0 && (unsigned) y < screenHeight
457
            && "VL_GetPixel: Pixel out of bounds!");
458
 
459
    ptr = VL_LockSurface(curSurface);
460
    if(ptr == NULL) return 0;
461
 
462
    col = ((byte *) curSurface->pixels)[y * curPitch + x];
463
 
464
    VL_UnlockSurface(curSurface);
465
 
466
    return col;
467
}
468
 
469
 
470
/*
471
=================
472
=
473
= VL_Hlin
474
=
475
=================
476
*/
477
 
478
void VL_Hlin (unsigned x, unsigned y, unsigned width, int color)
479
{
480
    byte *ptr;
481
 
482
    assert(x >= 0 && x + width <= screenWidth
483
            && y >= 0 && y < screenHeight
484
            && "VL_Hlin: Destination rectangle out of bounds!");
485
 
486
    ptr = VL_LockSurface(curSurface);
487
    if(ptr == NULL) return;
488
 
489
    memset(ptr + y * curPitch + x, color, width);
490
 
491
    VL_UnlockSurface(curSurface);
492
}
493
 
494
 
495
/*
496
=================
497
=
498
= VL_Vlin
499
=
500
=================
501
*/
502
 
503
void VL_Vlin (int x, int y, int height, int color)
504
{
505
	byte *ptr;
506
 
507
	assert(x >= 0 && (unsigned) x < screenWidth
508
			&& y >= 0 && (unsigned) y + height <= screenHeight
509
			&& "VL_Vlin: Destination rectangle out of bounds!");
510
 
511
	ptr = VL_LockSurface(curSurface);
512
	if(ptr == NULL) return;
513
 
514
	ptr += y * curPitch + x;
515
 
516
	while (height--)
517
	{
518
		*ptr = color;
519
		ptr += curPitch;
520
	}
521
 
522
	VL_UnlockSurface(curSurface);
523
}
524
 
525
 
526
/*
527
=================
528
=
529
= VL_Bar
530
=
531
=================
532
*/
533
 
534
void VL_BarScaledCoord (int scx, int scy, int scwidth, int scheight, int color)
535
{
536
	byte *ptr;
537
 
538
	assert(scx >= 0 && (unsigned) scx + scwidth <= screenWidth
539
			&& scy >= 0 && (unsigned) scy + scheight <= screenHeight
540
			&& "VL_BarScaledCoord: Destination rectangle out of bounds!");
541
 
542
	ptr = VL_LockSurface(curSurface);
543
	if(ptr == NULL) return;
544
 
545
	ptr += scy * curPitch + scx;
546
 
547
	while (scheight--)
548
	{
549
		memset(ptr, color, scwidth);
550
		ptr += curPitch;
551
	}
552
	VL_UnlockSurface(curSurface);
553
}
554
 
555
/*
556
============================================================================
557
 
558
							MEMORY OPS
559
 
560
============================================================================
561
*/
562
 
563
/*
564
=================
565
=
566
= VL_MemToLatch
567
=
568
=================
569
*/
570
 
571
void VL_MemToLatch(byte *source, int width, int height,
572
    SDL_Surface *destSurface, int x, int y)
573
{
574
    byte *ptr;
575
    int xsrc, ysrc, pitch;
576
 
577
    assert(x >= 0 && (unsigned) x + width <= screenWidth
578
            && y >= 0 && (unsigned) y + height <= screenHeight
579
            && "VL_MemToLatch: Destination rectangle out of bounds!");
580
 
581
    ptr = VL_LockSurface(destSurface);
582
    if(ptr == NULL) return;
583
 
584
    pitch = destSurface->pitch;
585
    ptr += y * pitch + x;
586
    for(ysrc = 0; ysrc < height; ysrc++)
587
    {
588
        for(xsrc = 0; xsrc < width; xsrc++)
589
        {
590
            ptr[ysrc * pitch + xsrc] = source[(ysrc * (width >> 2) + (xsrc >> 2))
591
                + (xsrc & 3) * (width >> 2) * height];
592
        }
593
    }
594
    VL_UnlockSurface(destSurface);
595
}
596
 
597
//===========================================================================
598
 
599
 
600
/*
601
=================
602
=
603
= VL_MemToScreenScaledCoord
604
=
605
= Draws a block of data to the screen with scaling according to scaleFactor.
606
=
607
=================
608
*/
609
 
610
void VL_MemToScreenScaledCoord (byte *source, int width, int height, int destx, int desty)
611
{
612
    byte *ptr;
613
    int i, j, sci, scj;
614
    unsigned m, n;
615
 
616
    assert(destx >= 0 && destx + width * scaleFactor <= screenWidth
617
            && desty >= 0 && desty + height * scaleFactor <= screenHeight
618
            && "VL_MemToScreenScaledCoord: Destination rectangle out of bounds!");
619
 
620
    ptr = VL_LockSurface(curSurface);
621
    if(ptr == NULL) return;
622
 
623
    for(j = 0, scj = 0; j < height; j++, scj += scaleFactor)
624
    {
625
        for(i = 0, sci = 0; i < width; i++, sci += scaleFactor)
626
        {
627
            byte col = source[(j * (width >> 2) + (i >> 2)) + (i & 3) * (width >> 2) * height];
628
            for(m = 0; m < scaleFactor; m++)
629
            {
630
                for(n = 0; n < scaleFactor; n++)
631
                {
632
                    ptr[(scj + m + desty) * curPitch + sci + n + destx] = col;
633
                }
634
            }
635
        }
636
    }
637
    VL_UnlockSurface(curSurface);
638
}
639
 
640
/*
641
=================
642
=
643
= VL_MemToScreenScaledCoord
644
=
645
= Draws a part of a block of data to the screen.
646
= The block has the size origwidth*origheight.
647
= The part at (srcx, srcy) has the size width*height
648
= and will be painted to (destx, desty) with scaling according to scaleFactor.
649
=
650
=================
651
*/
652
 
653
void VL_MemToScreenScaledCoord (byte *source, int origwidth, int origheight, int srcx, int srcy,
654
                                int destx, int desty, int width, int height)
655
{
656
    byte *ptr;
657
    int i, j, sci, scj;
658
    unsigned m, n;
659
 
660
    assert(destx >= 0 && destx + width * scaleFactor <= screenWidth
661
            && desty >= 0 && desty + height * scaleFactor <= screenHeight
662
            && "VL_MemToScreenScaledCoord: Destination rectangle out of bounds!");
663
 
664
    ptr = VL_LockSurface(curSurface);
665
    if(ptr == NULL) return;
666
 
667
    for(j = 0, scj = 0; j < height; j++, scj += scaleFactor)
668
    {
669
        for(i = 0, sci = 0; i < width; i++, sci += scaleFactor)
670
        {
671
            byte col = source[((j + srcy) * (origwidth >> 2) + ((i + srcx) >>2 ))
672
                + ((i + srcx) & 3) * (origwidth >> 2) * origheight];
673
 
674
            for(m = 0; m < scaleFactor; m++)
675
            {
676
                for(n = 0; n < scaleFactor; n++)
677
                {
678
                    ptr[(scj + m + desty) * curPitch + sci + n + destx] = col;
679
                }
680
            }
681
        }
682
    }
683
    VL_UnlockSurface(curSurface);
684
}
685
 
686
//==========================================================================
687
 
688
/*
689
=================
690
=
691
= VL_LatchToScreen
692
=
693
=================
694
*/
695
 
696
void VL_LatchToScreenScaledCoord(SDL_Surface *source, int xsrc, int ysrc,
697
    int width, int height, int scxdest, int scydest)
698
{
699
	assert(scxdest >= 0 && scxdest + width * scaleFactor <= screenWidth
700
			&& scydest >= 0 && scydest + height * scaleFactor <= screenHeight
701
			&& "VL_LatchToScreenScaledCoord: Destination rectangle out of bounds!");
702
 
703
	if(scaleFactor == 1)
704
    {
705
        // HACK: If screenBits is not 8 and the screen is faded out, the
706
        //       result will be black when using SDL_BlitSurface. The reason
707
        //       is that the logical palette needed for the transformation
708
        //       to the screen color depth is not equal to the logical
709
        //       palette of the latch (the latch is not faded). Therefore,
710
        //       SDL tries to map the colors...
711
        //       The result: All colors are mapped to black.
712
        //       So, we do the blit on our own...
713
        if(screenBits != 8)
714
        {
715
            byte *src, *dest;
716
            unsigned srcPitch;
717
            int i, j;
718
 
719
            src = VL_LockSurface(source);
720
            if(src == NULL) return;
721
 
722
            srcPitch = source->pitch;
723
 
724
            dest = VL_LockSurface(curSurface);
725
            if(dest == NULL) return;
726
 
727
            for(j = 0; j < height; j++)
728
            {
729
                for(i = 0; i < width; i++)
730
                {
731
                    byte col = src[(ysrc + j)*srcPitch + xsrc + i];
732
                    dest[(scydest + j) * curPitch + scxdest + i] = col;
733
                }
734
            }
735
            VL_UnlockSurface(curSurface);
736
            VL_UnlockSurface(source);
737
        }
738
        else
739
        {
740
            SDL_Rect srcrect = { xsrc, ysrc, width, height };
741
            SDL_Rect destrect = { scxdest, scydest, 0, 0 }; // width and height are ignored
742
            SDL_BlitSurface(source, &srcrect, curSurface, &destrect);
743
        }
744
    }
745
    else
746
    {
747
        byte *src, *dest;
748
        unsigned srcPitch;
749
        int i, j, sci, scj;
750
        unsigned m, n;
751
 
752
        src = VL_LockSurface(source);
753
        if(src == NULL) return;
754
 
755
        srcPitch = source->pitch;
756
 
757
        dest = VL_LockSurface(curSurface);
758
        if(dest == NULL) return;
759
 
760
        for(j = 0, scj = 0; j < height; j++, scj += scaleFactor)
761
        {
762
            for(i = 0, sci = 0; i < width; i++, sci += scaleFactor)
763
            {
764
                byte col = src[(ysrc + j)*srcPitch + xsrc + i];
765
                for(m = 0; m < scaleFactor; m++)
766
                {
767
                    for(n = 0; n < scaleFactor; n++)
768
                    {
769
                        dest[(scydest + scj + m) * curPitch + scxdest + sci + n] = col;
770
                    }
771
                }
772
            }
773
        }
774
        VL_UnlockSurface(curSurface);
775
        VL_UnlockSurface(source);
776
    }
777
}
778
 
779
//===========================================================================
780
 
781
/*
782
=================
783
=
784
= VL_ScreenToScreen
785
=
786
=================
787
*/
788
 
789
void VL_ScreenToScreen (SDL_Surface *source, SDL_Surface *dest)
790
{
791
    SDL_BlitSurface(source, NULL, dest, NULL);
792
}