source: abuse/tags/pd/macabuse/imlib/port/mac/video.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 25.0 KB
Line 
1#include <QDOffscreen.h>
2#include <Palettes.h>
3#include <Displays.h>
4#include <Video.h>
5#include <Menus.h>
6
7#include "video.hpp"
8#include "dev.hpp"
9
10#include "filter.hpp"
11#include "globals.hpp"
12#include "system.h"
13#include "dos.h"
14#include "macs.hpp"
15#include "bitmap.h"
16#include "image.hpp"
17#include "jmalloc.hpp"
18#include "dprint.hpp"
19
20#include "RequestVideo.h"
21
22#include "hack.hpp"
23
24// Resource id for crack window
25#define         WIND_CRACK      1000
26
27#define PAL_DIRECT    // direct palette routines - yes!
28#define VIDEO_DIRECT  // direct video routines - yes!
29
30unsigned char current_background;
31
32// Some number for jollies
33int vmode;
34image *screen;
35
36Rect Bounds;
37CWindowPtr mainwin,backwin;
38CTabHandle MacCT,saved_pal;
39#ifndef PAL_DIRECT
40PaletteHandle MacPal;
41#endif
42int PixMult;
43int PixMode;
44
45int HackMode = 0;
46
47// Menu Globals
48short OldMBarHeight = 0;
49RgnHandle OldVisRgn = 0;
50
51// DM stuff
52VideoRequestRec requestRec;
53VideoRequestRec originalRec;
54short           currentDepth;
55short           currentHorizontal;
56short           currentVertical;
57
58// Direct Video globals
59GDHandle gd;
60short gVideoRowBytes;
61char *gVideoMem;
62char *gGame1VideoMem;
63char *gGame2VideoMem;
64char *gRealVideoMem;
65Rect *gRect;
66
67#ifdef VIDEO_DIRECT
68void (*SpeedCopyBits)(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
69void SpeedCopyBits11(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
70void SpeedCopyBits21Fast(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
71void SpeedCopyBits21Slow(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
72void SpeedCopyBits22Fast(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
73void SpeedCopyBits22Slow(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy);
74#endif
75
76class CMacStartup {
77public:
78
79        void ToolBoxInit()
80        {
81                // Initialize mac toolboxes
82                InitGraf(&qd.thePort);
83    InitFonts();
84    FlushEvents(everyEvent - osMask - diskMask, 0);
85    InitWindows();
86    InitMenus();
87//    TEInit();
88    InitDialogs(0L);
89    InitCursor();
90
91                SetApplLimit(GetApplLimit() - 327680);
92
93//    MaxApplZone();
94        }
95
96        void BuildMenuBar();
97        void HideMenu();
98        void RestoreMenu();
99       
100        void SetMode();
101        void GrabScreen();     
102        void MakeWindows();
103        void DestroyWindows();
104       
105        CMacStartup()
106        {
107                ToolBoxInit();
108               
109                PixMode = 3;
110
111                xres = 640;
112                yres = 480;
113        }
114       
115        void Init();
116        void Quit();
117        ~CMacStartup();
118       
119} MacStartup;
120
121void CMacStartup::SetMode()
122{
123        requestRec.screenDevice = nil;                                  // find any screen
124        requestRec.reqBitDepth = 8;                                                     // bit depth request
125        requestRec.reqHorizontal = 640;                                 // H request
126        requestRec.reqVertical = 480;                                           // V request
127        requestRec.displayMode = nil;                                           // must init to nil
128        requestRec.depthMode = nil;                                                     // must init to nil
129        requestRec.requestFlags = 1<<kAllValidModesBit;                                         
130                                                                                                                                                                        // give me the HxV over bit depth, and only safe video modes
131
132        // make the request and set it if we have one....
133        RVRequestVideoSetting(&requestRec);
134
135        if (requestRec.screenDevice == nil)             // make sure we found a device...possible if there are no "safe" video modes
136        {
137                dprintf("Can't get current video mode\n");
138                exit(1);
139        }
140
141        // Get current setting
142        originalRec.screenDevice = requestRec.screenDevice;             // this screen
143        RVGetCurrentVideoSetting(&originalRec);
144       
145        HackSetRequest (&requestRec);
146//              if (noErr != RVConfirmVideoRequest (&requestRec))
147//                      RVSetVideoRequest (&originalRec);
148}
149
150void CMacStartup::BuildMenuBar()
151{
152  #define MENUBARID             128
153        #define APPLEMENUID     128
154  Handle menuBarH;
155
156  menuBarH = GetNewMBar(MENUBARID);
157
158  if (menuBarH != NULL)
159  {
160    SetMenuBar(menuBarH);
161    AddResMenu(GetMHandle(APPLEMENUID), 'DRVR');
162    DrawMenuBar();             
163  }
164  else
165  {
166    dprintf("Can't get Menu!\n");
167        exit(1);
168  }
169}
170
171void CMacStartup::HideMenu()
172{
173        RgnHandle DesktopRgn;
174
175        if (OldMBarHeight == 0)
176        {
177                // Get and copy the current gray region
178                DesktopRgn = LMGetGrayRgn();
179                OldVisRgn = NewRgn();
180                CopyRgn(DesktopRgn, OldVisRgn);
181               
182                // Fudge the menu bar height
183                OldMBarHeight = GetMBarHeight();
184                LMSetMBarHeight(0);
185
186                // Turn the gray into the old gray region plus the menu bar region
187                Rect MenuRect;
188                MenuRect.left = 0;
189                MenuRect.top = 0;
190                MenuRect.right = qd.screenBits.bounds.right;
191                MenuRect.bottom = OldMBarHeight;
192                RgnHandle MenuRgn = NewRgn();
193                RectRgn(MenuRgn, &MenuRect);
194
195                UnionRgn(OldVisRgn, MenuRgn, DesktopRgn);
196                DisposeRgn(MenuRgn);
197        }
198}
199
200void CMacStartup::RestoreMenu()
201{
202        if (OldMBarHeight && OldVisRgn)
203        {
204                // Restore the menu bar height
205                LMSetMBarHeight(OldMBarHeight);
206                OldMBarHeight = 0;
207
208                // Restore the old desktop region
209                CopyRgn(OldVisRgn, LMGetGrayRgn());
210                DisposeRgn(OldVisRgn);
211                OldVisRgn = 0;
212               
213                // Redraw the menu bar
214                HiliteMenu(0);
215                DrawMenuBar();
216        }
217}
218
219void CMacStartup::GrabScreen()
220{
221        PixMapHandle PMH;
222
223        gd = requestRec.screenDevice;
224        PMH = (*gd)->gdPMap;
225        LockPixels(PMH);
226        gVideoRowBytes = (*PMH)->rowBytes & 0x3FFF;
227        gVideoMem = gRealVideoMem = GetPixBaseAddr(PMH);
228        gRect = &(*gd)->gdRect;
229
230        // set color table for 8 bit mode
231#ifdef PAL_DIRECT
232        MacCT = (**((**gd).gdPMap)).pmTable;
233#else
234        MacCT = GetCTable(8);
235        MacPal = NewPalette(256,nil,pmTolerant,0);
236        (**MacCT).ctSeed = GetCTSeed();
237#endif
238
239        xres = gRect->right - gRect->left;
240        yres = gRect->bottom - gRect->top;
241       
242        gGame1VideoMem = gRealVideoMem + ((xres/2 - 320/2)&~7) + gVideoRowBytes
243                                                                * ( yres/2 - 200/2 );
244        gGame2VideoMem = gRealVideoMem + ((xres/2 - 640/2)&~7) + gVideoRowBytes
245                                                                * ( yres/2 - 400/2 );
246}
247
248void CMacStartup::MakeWindows()
249{
250        Rect CurBounds;
251        GrafPtr savePort;
252
253#ifdef VIDEO_DIRECT
254
255        // use hack to get pixel mode
256        SpeedCopyBits = &SpeedCopyBits11; PixMult = 1;
257
258#endif
259
260        Bounds = *gRect;
261       
262        backwin = (CWindowPtr)NewCWindow(nil, &Bounds, "\p", TRUE, 2, (WindowPtr)-1L, FALSE, 0);
263        SetGWorld((GWorldPtr)backwin,gd);
264
265        char *p = gVideoMem;
266        for (int y=Bounds.top; y<Bounds.bottom; y++)
267        {
268                memset(p,0xff,Bounds.right-Bounds.left);
269                p += gVideoRowBytes;
270        }               
271
272#ifndef VIDEO_DIRECT
273        Bounds.left = (gRect->left+gRect->right)/2 - xres/2 * PixMult;
274        Bounds.right = (gRect->left+gRect->right)/2 + xres/2 * PixMult;
275        Bounds.top = (gRect->top+gRect->bottom)/2 - yres/2 * PixMult;
276        Bounds.bottom = (gRect->top+gRect->bottom)/2 + yres/2 * PixMult;
277        mainwin = (CWindowPtr)NewCWindow(nil, &Bounds, "\p", TRUE, 2, (WindowPtr)-1L, FALSE, 0);
278        SetGWorld((GWorldPtr)mainwin,gd);
279        CurBounds = mainwin->portRect;
280
281        xres = (Bounds.right - Bounds.left)/PixMult;
282        yres = (Bounds.bottom - Bounds.top)/PixMult;
283#endif
284
285        // save old palette
286        saved_pal = (**((**gd).gdPMap)).pmTable;
287        HandToHand((Handle*)&saved_pal);
288}
289
290void CMacStartup::DestroyWindows()
291{
292#ifdef PAL_DIRECT
293        ColorSpec *spec,*spec2;
294        VDSetEntryRecord setEntriesRec;
295        Ptr                              csPtr;
296        QDErr                   error;
297        RgnHandle junkRgn;
298
299        spec = (**MacCT).ctTable;
300        spec2 = (**saved_pal).ctTable;
301        for (int i=0; i<(**MacCT).ctSize; i++)
302        {
303                spec[i].rgb.red = spec2[i].rgb.red;
304                spec[i].rgb.green = spec2[i].rgb.green;
305                spec[i].rgb.blue = spec2[i].rgb.blue;
306                spec[i].value = spec2[i].value;
307        }
308        setEntriesRec.csTable = (ColorSpec *)&(**MacCT).ctTable;
309        setEntriesRec.csStart = 0;
310        setEntriesRec.csCount = (**MacCT).ctSize;
311        csPtr = (Ptr) &setEntriesRec;
312        error = Control ((**gd).gdRefNum, cscSetEntries, (Ptr) &csPtr);
313        if (error)
314                dprintf("aieee! palette problem!\n");
315#else
316        // restore palette
317        MacPal = NewPalette((**saved_pal).ctSize,saved_pal,pmTolerant,0);
318        NSetPalette((WindowPtr)mainwin,MacPal,pmAllUpdates);
319        ActivatePalette((WindowPtr)mainwin);
320#endif
321#ifndef VIDEO_DIRECT   
322        CloseWindow((WindowPtr)mainwin);
323#endif
324        CloseWindow((WindowPtr)backwin);       
325}
326
327void CMacStartup::Init()
328{
329        HideMenu();     
330
331#ifdef VIDEO_DIRECT
332        HideCursor();
333#else
334        // erase cursor
335        ShieldCursor(&CurBounds,topLeft((**(mainwin->portPixMap)).bounds));
336#endif
337
338        SetMode();
339//              BuildMenuBar();
340        GrabScreen();
341//      fprintf(stderr,"Initting Screen.\n");
342
343        MakeWindows();
344}
345
346void CMacStartup::Quit()
347{
348        DestroyWindows();
349}
350
351CMacStartup::~CMacStartup()
352{
353        HackRestoreRequest (&originalRec);
354//      RVSetVideoAsScreenPrefs ();
355        RestoreMenu();
356        FlushEvents(everyEvent, 0);
357
358        // restore cursor
359        ShowCursor();
360}
361       
362void InitMacScreen()
363{
364        MacStartup.Init();
365}
366
367void QuitMacScreen()
368{
369        MacStartup.Quit();
370}
371
372int get_vmode()
373{
374        return vmode;
375}
376
377void image::make_page(short width, short height, unsigned char *page_buffer)
378//  creates memory that will be touched externally, for routines to copy to
379//  something will copy this memory to video memory
380{
381  if (special && !special->static_mem)
382  {
383#ifdef VIDEO_DIRECT
384    data=(unsigned char *)jmalloc(width*height,"image::direct_data");
385#else
386                GWorldPtr gw;
387                PixMapHandle pixmaph;
388                QDErr err;
389                Rect r;
390
391        r.left = 0;
392        r.top = 0;
393        r.right = width;
394        r.bottom = height;
395        // use mac image, but set
396                err = NewGWorld( &gw, 8, &r, MacCT, nil, 0 );
397        special->extended_descriptor = gw;
398                pixmaph = GetGWorldPixMap(gw);
399                HLockHi((Handle)pixmaph);
400                LockPixels(pixmaph);
401        data = (unsigned char *)GetPixBaseAddr(pixmaph);
402        (**pixmaph).pmTable = MacCT;
403       
404        // yikes! hack the row bytes
405        (**pixmaph).rowBytes = 0x8000 | width;
406        w = (**pixmaph).rowBytes & 0x3fffl;
407        h = height;
408 #endif
409  }
410  else
411  {
412    if (!page_buffer)
413        // no preallocated image, so allocate some
414      data=(unsigned char *)jmalloc(width*height,"image::data");
415    else
416        // we want to use a preallocated image as this image's memory
417        data=page_buffer;
418  }
419
420  if (special)
421        // set clipping area
422    special->resize(width,height);
423}
424
425void image::delete_page()
426//  frees page memory
427{
428        if (special && !special->static_mem) {
429#ifdef VIDEO_DIRECT
430                jfree(data);
431#else
432                GWorldPtr gw;
433       
434                gw = (GWorldPtr)special->extended_descriptor;
435               
436                if (gw)
437                        DisposeGWorld(gw);
438#endif
439                special->extended_descriptor = 0;
440        }
441        else if (!special)
442                jfree(data);
443}
444
445void set_mode(video_mode new_mode, int argc, char **argv)
446{
447        // create screen memory
448  screen=new image(xres,yres,NULL,2); 
449
450        // clear screen
451  screen->clear();
452  update_dirty(screen);
453 
454  if (new_mode==VMODE_320x200)
455    Pre_Hack_Mode();
456}
457
458void RestoreMac()
459{
460        ColorSpec *spec,*spec2;
461        VDSetEntryRecord setEntriesRec;
462        Ptr                              csPtr;
463        QDErr                   error;
464
465        char *p = gVideoMem;
466        for (int y=Bounds.top; y<Bounds.bottom; y++)
467        {
468                memset(p,0xff,Bounds.right-Bounds.left);
469                p += gVideoRowBytes;
470        }               
471
472        spec = (**MacCT).ctTable;
473        spec2 = (**saved_pal).ctTable;
474        for (int i=0; i<(**MacCT).ctSize; i++)
475        {
476                spec[i].rgb.red = spec2[i].rgb.red;
477                spec[i].rgb.green = spec2[i].rgb.green;
478                spec[i].rgb.blue = spec2[i].rgb.blue;
479                spec[i].value = spec2[i].value;
480        }
481        setEntriesRec.csTable = (ColorSpec *)&(**MacCT).ctTable;
482        setEntriesRec.csStart = 0;
483        setEntriesRec.csCount = (**MacCT).ctSize;
484        csPtr = (Ptr) &setEntriesRec;
485        error = Control ((**gd).gdRefNum, cscSetEntries, (Ptr) &csPtr);
486        if (error)
487                dprintf("aieee! palette problem!\n");
488               
489        ShowCursor();
490}
491
492void UnRestoreMac()
493{
494        HideCursor();
495}
496
497void close_graphics()
498{
499  delete screen;
500}
501
502#ifdef VIDEO_DIRECT
503
504void SpeedCopyBits11(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy)
505{
506        int x,y;
507        unsigned char *p,*q,*pp,*qq;
508        unsigned long srclen = im->width();
509       
510        p = (unsigned char *)im->scan_line(sy1) + sx1;
511        q = (unsigned char *)gVideoMem + gVideoRowBytes*(dy+Bounds.top) + (dx+Bounds.left);
512        for (y=sy1; y<=sy2; y++)
513        {
514#if 0
515                pp = p;
516                qq = q;
517                for (x=sx1; x<=sx2; x++)
518                        *(qq++) = *(pp++);
519#else
520                memcpy(q,p,sx2-sx1+1);
521#endif
522                p += srclen;
523                q += gVideoRowBytes;
524        }
525}
526
527#ifdef __POWERPC__
528asm void SCB21InnerLoop(unsigned char *p, unsigned char *q, unsigned char *q2,
529                                                                                                 long src_margin_width, long margin_width,
530                                                                                                 int xcount, int ycount )
531{
532                                stmw            r22,-40(SP)                                     // save registers used
533                                addi            r3,r3,-4                                                        // predecrement pointers, so that we can use load w/ update
534                                addi            r4,r4,-4
535                                addi            r6,r6,-4                                                        //  "hacked" optimization to reduce a substraction:
536                                                                                                                                                        //  since we preload data, we need to adjust the pointer
537lupe0:
538                                mr                      r29,r8                                                          //  reset counter to xcount
539                                lwzu            r31,4(r3)                                                       //  preload first data
540lupe1:
541                                lwzu            r26,4(r3)                                                       // preload next data
542
543                                rlwimi  r30,r31, 0, 0, 7                        // cool shift & mask to expand low pixels
544                                rlwimi  r30,r31,24, 8,15
545                                rlwimi  r30,r31,24,16,23
546                                rlwimi  r30,r31,16,24,31
547
548                                stwu            r30,4(r4)                                                       // save off 1 "fat" pixels
549                               
550                                rlwimi  r28,r31,16, 0, 7                        // shift for high pixels
551                                rlwimi  r28,r31,8 , 8,15
552                                rlwimi  r28,r31,8 ,16,23
553                                rlwimi  r28,r31,0 ,24,31
554
555                                stwu            r28,4(r4)                                                       // another "fat" pixels
556                               
557                                // singly unrolled loop iteration
558                                lwzu            r31,4(r3)
559                               
560                                rlwimi  r30,r26, 0, 0, 7
561                                rlwimi  r30,r26,24, 8,15
562                                rlwimi  r30,r26,24,16,23
563                                rlwimi  r30,r26,16,24,31
564
565                                stwu            r30,4(r4)
566                               
567                                rlwimi  r28,r26,16, 0, 7
568                                rlwimi  r28,r26,8 , 8,15
569                                rlwimi  r28,r26,8 ,16,23
570                                rlwimi  r28,r26,0 ,24,31
571
572                                stwu            r28,4(r4)
573
574                                addic.  r29,r29,-8                                              // update xcount
575                                bgt                     lupe1                                                                   // done with line?
576                               
577                                add                     r3,r3,r6                                                        // skip to next row
578                                add                     r4,r4,r7
579                                addic.  r9,r9,-1                                                        // update ycount
580                               
581                                bgt                     lupe0                                                                   // done?
582                                nop
583                               
584                                lmw                     r22,-40(SP)                                             // restore registers, how nice
585                                blr
586}
587#else
588
589#if 1
590asm void SCB21InnerLoop(unsigned char *p, unsigned char *q, unsigned char *q2,
591                                                                                                 long src_margin_width, long margin_width,
592                                                                                                 int xcount, int ycount )
593{
594                                link            a6,#0x0000
595                                movem.l d4-d7/a4,-(a7)
596                                movea.l 8(a6),a4                                                        // p
597                                movea.l 12(a6),a1                                                       // q
598                                move.l  24(a6),d6                                                       // margin_width
599                                move.l  28(a6),d7                                                       // xcount
600                                move.l  32(a6),d5                                                       // ycount
601lupe0:
602                                move.l  d7,d4                                                                   // copy xcount
603lupe1:
604                                move.l  (a4)+,d1                                                        // get 4 pixels
605                                move.l  d1,d0                                                                   // copy
606                                lsr.l           #8,d0                                                                   // expand pixel pair
607                                lsr.w           #8,d0
608                                move.l  d0,d2
609                                lsl.l           #8,d0
610                                or.l            d0,d2
611                                move.l  d2,(a1)+                                                        // write pixel pair
612                               
613                                swap            d1                                                                              // move pair into position
614                                lsr.l           #8,d1                                                                   // expand pixel pair
615                                lsr.w           #8,d1
616                                move.l  d1,d2
617                                lsl.l           #8,d1
618                                or.l            d1,d2
619                                move.l  d2,(a1)+                                                        // write pixel pair
620                               
621                                subq.l  #4,d4                                                                   // next pixel quad
622                                bgt.s           lupe1
623                               
624                                adda.l  20(a6),a4                                                       // advance scanline pointers
625                                adda.l  d6,a1
626                               
627                                subq.l  #1,d5                                                                   // next row
628                                bgt.s           lupe0
629                               
630                                movem.l (a7)+,d4-d7/a4
631                                unlk            a6
632                                rts
633}
634#else
635void SCB21InnerLoop(unsigned char *p, unsigned char *q, unsigned char *q2,
636                                                                                                 long src_margin_width, long margin_width,
637                                                                                                 int xcount, int ycount )
638{
639        short dat;
640       
641        for (; ycount>0; ycount--)
642        {
643                for (int x=xcount; x>0; x--) {
644                        dat = *(p++);
645                        dat |= dat<<8;
646                        *((unsigned short *)q) = dat; q+=2;
647                }
648                p += src_margin_width;
649                q += margin_width;
650        }
651}
652#endif
653
654#endif
655
656void SpeedCopyBits21Fast(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy)
657{
658        if ((sx1&7)!=0 || (sx2&7)!=7)
659                SpeedCopyBits21Slow(im,sx1,sy1,sx2,sy2,dx,dy);
660        else
661        {
662                unsigned char *p;
663                unsigned char *q;
664                unsigned long srclen = im->width();
665                unsigned long src_width = sx2 - sx1 + 1;
666               
667                p = (unsigned char *)im->scan_line(sy1) + sx1;
668                q = (unsigned char *)gVideoMem + gVideoRowBytes*(dy*2+Bounds.top) + (dx*2+Bounds.left);
669       
670                SCB21InnerLoop(p,q,0,
671                                                                         srclen - src_width, (gVideoRowBytes - src_width)*2,
672                                                                         src_width, (sy2 - sy1 + 1));
673        }
674}
675
676void SpeedCopyBits21Slow(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy)
677{
678        int x,y;
679        unsigned char *p,*pp;
680        unsigned short *q,*qq,dat;
681        unsigned long srclen = im->width();
682       
683        p = (unsigned char *)im->scan_line(sy1) + sx1;
684        q = (unsigned short*)((unsigned char *)gVideoMem +
685                                                                                                gVideoRowBytes*(dy*2+Bounds.top) + (dx*2+Bounds.left));
686        for (y=sy1; y<=sy2; y++)
687        {
688                pp = p;
689                qq = q;
690                for (x=sx1; x<=sx2; x++) {
691                        dat = *(pp++);
692                        dat |= dat<<8;
693                        *(qq++) = dat;
694                }
695                p += srclen;
696                q += gVideoRowBytes;
697        }
698}
699
700#ifdef __POWERPC__
701asm void SCB22InnerLoop(unsigned char *p, unsigned char *q, unsigned char *q2,
702                                                                                                 long src_margin_width, long margin_width,
703                                                                                                 int xcount, int ycount )
704{
705                                stmw            r22,-40(SP)                                     // save registers used
706                                addi            r3,r3,-4                                                        // predecrement pointers, so that we can use load w/ update
707                                addi            r4,r4,-4
708                                addi            r5,r5,-4
709                                addi            r6,r6,-4                                                        //  "hacked" optimization to reduce a substraction:
710                                                                                                                                                        //  since we preload data, we need to adjust the pointer
711lupe0:
712                                mr                      r29,r8                                                          //  reset counter to xcount
713                                lwzu            r31,4(r3)                                                       //  preload first data
714lupe1:
715                                lwzu            r26,4(r3)                                                       // preload next data
716
717                                rlwimi  r30,r31, 0, 0, 7                        // cool shift & mask to expand low pixels
718                                rlwimi  r30,r31,24, 8,15
719                                rlwimi  r30,r31,24,16,23
720                                rlwimi  r30,r31,16,24,31
721
722                                stwu            r30,4(r4)                                                       // save off 2 "fat" pixels
723                                stwu            r30,4(r5)
724                               
725                                rlwimi  r28,r31,16, 0, 7                        // shift for high pixels
726                                rlwimi  r28,r31,8 , 8,15
727                                rlwimi  r28,r31,8 ,16,23
728                                rlwimi  r28,r31,0 ,24,31
729
730                                stwu            r28,4(r4)                                                       // two more "fat" pixels
731                                stwu            r28,4(r5)
732                               
733                                // singly unrolled loop iteration
734                                lwzu            r31,4(r3)
735                               
736                                rlwimi  r30,r26, 0, 0, 7
737                                rlwimi  r30,r26,24, 8,15
738                                rlwimi  r30,r26,24,16,23
739                                rlwimi  r30,r26,16,24,31
740
741                                stwu            r30,4(r4)
742                                stwu            r30,4(r5)
743                               
744                                rlwimi  r28,r26,16, 0, 7
745                                rlwimi  r28,r26,8 , 8,15
746                                rlwimi  r28,r26,8 ,16,23
747                                rlwimi  r28,r26,0 ,24,31
748
749                                stwu            r28,4(r4)
750                                stwu            r28,4(r5)
751
752                                addic.  r29,r29,-8                                              // update xcount
753                                bgt                     lupe1                                                                   // done with line?
754                               
755                                add                     r3,r3,r6                                                        // skip to next row
756                                add                     r4,r4,r7
757                                add                     r5,r5,r7
758                                addic.  r9,r9,-1                                                        // update ycount
759                               
760                                bgt                     lupe0                                                                   // done?
761                                nop
762                               
763                                lmw                     r22,-40(SP)                                             // restore registers, how nice
764                                blr
765}
766#else
767
768#if 1
769asm void SCB22InnerLoop(unsigned char *p, unsigned char *q, unsigned char *q2,
770                                                                                                 long src_margin_width, long margin_width,
771                                                                                                 int xcount, int ycount )
772{
773                                link            a6,#0x0000
774                                movem.l d4-d7/a4,-(a7)
775                                movea.l 8(a6),a4                                                        // p
776                                movea.l 12(a6),a1                                                       // q
777                                movea.l 16(a6),a0                                                       // q2
778                                move.l  24(a6),d6                                                       // margin_width
779                                move.l  28(a6),d7                                                       // xcount
780                                move.l  32(a6),d5                                                       // ycount
781lupe0:
782                                move.l  d7,d4                                                                   // copy xcount
783lupe1:
784                                move.l  (a4)+,d1                                                        // get 4 pixels
785                                move.l  d1,d0                                                                   // copy
786                                lsr.l           #8,d0                                                                   // expand pixel pair
787                                lsr.w           #8,d0
788                                move.l  d0,d2
789                                lsl.l           #8,d0
790                                or.l            d0,d2
791                                move.l  d2,(a1)+                                                        // write pixel pair
792                                move.l  d2,(a0)+
793                               
794                                swap            d1                                                                              // move pair into position
795                                lsr.l           #8,d1                                                                   // expand pixel pair
796                                lsr.w           #8,d1
797                                move.l  d1,d2
798                                lsl.l           #8,d1
799                                or.l            d1,d2
800                                move.l  d2,(a1)+                                                        // write pixel pair
801                                move.l  d2,(a0)+
802                               
803                                subq.l  #4,d4                                                                   // next pixel quad
804                                bgt.s           lupe1
805                               
806                                adda.l  20(a6),a4                                                       // advance scanline pointers
807                                adda.l  d6,a1
808                                adda.l  d6,a0
809                               
810                                subq.l  #1,d5                                                                   // next row
811                                bgt.s           lupe0
812                               
813                                movem.l (a7)+,d4-d7/a4
814                                unlk            a6
815                                rts
816}
817#else
818void SCB22InnerLoop(unsigned char *p, unsigned char *q, unsigned char *q2,
819                                                                                                 long src_margin_width, long margin_width,
820                                                                                                 int xcount, int ycount )
821{
822        short dat;
823       
824        for (; ycount>0; ycount--)
825        {
826                for (int x=xcount; x>0; x--) {
827                        dat = *(p++);
828                        dat |= dat<<8;
829                        *((unsigned short *)q) = dat; q+=2;
830                        *((unsigned short *)q2) = dat; q2+=2;
831                }
832                p += src_margin_width;
833                q += margin_width;
834                q2 += margin_width;
835        }
836}
837#endif
838
839#endif
840
841void SpeedCopyBits22Fast(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy)
842{
843        if ((sx1&7)!=0 || (sx2&7)!=7)
844                SpeedCopyBits22Slow(im,sx1,sy1,sx2,sy2,dx,dy);
845        else
846        {
847                unsigned char *p;
848                unsigned char *q;
849                unsigned long srclen = im->width();
850                unsigned long src_width = sx2 - sx1 + 1;
851               
852                p = (unsigned char *)im->scan_line(sy1) + sx1;
853                q = (unsigned char *)gVideoMem + gVideoRowBytes*(dy*2+Bounds.top) + (dx*2+Bounds.left);
854       
855                SCB22InnerLoop(p,q,((unsigned char*)q + gVideoRowBytes),
856                                                                         srclen - src_width, (gVideoRowBytes - src_width)*2,
857                                                                         src_width, (sy2 - sy1 + 1));
858        }
859}
860
861void SpeedCopyBits22Slow(image *im, int sx1,int sy1, int sx2,int sy2, int dx,int dy)
862{
863        int x,y;
864        unsigned char *p,*pp;
865        unsigned short *q,*qq,*qq2,dat;
866        unsigned long srclen = im->width();
867       
868        p = (unsigned char *)im->scan_line(sy1) + sx1;
869        q = (unsigned short*)((unsigned char *)gVideoMem +
870                                                                                                gVideoRowBytes*(dy*2+Bounds.top) + (dx*2+Bounds.left));
871
872        for (y=sy1; y<=sy2; y++)
873        {
874                pp = p;
875                qq = q;
876                qq2 = (unsigned short*)((unsigned char*)q + gVideoRowBytes);
877                for (x=sx1; x<=sx2; x++) {
878                        dat = *(pp++);
879                        dat |= dat<<8;
880                        *(qq++) = dat;
881                        *(qq2++) = dat;
882                }
883                p += srclen;
884                q += gVideoRowBytes;
885        }
886}
887
888#endif
889
890void update_dirty(image *im, int xoff, int yoff)
891// go through list of dirty rects & display
892{
893  int count;
894  dirty_rect *dr,*q;
895  image *Xim;
896  CHECK(im->special);  // make sure the image has the ablity to contain dirty areas
897  if (im->special->keep_dirt==0)
898//    put_image(im,xoff,yoff);
899                q = 0;
900  else
901  {
902    count=im->special->dirties.number_nodes();
903    if (!count) return;  // if nothing to update, return
904    dr= (dirty_rect *) (im->special->dirties.first());
905    while (count>0)
906    {
907#ifdef VIDEO_DIRECT
908                        int x1 = dr->dx1,y1 = dr->dy1,x2 = dr->dx2,y2 = dr->dy2,dx1 = xoff + dr->dx1,dy1 = yoff + dr->dy1;
909                       
910        if (dx1<0)
911        {
912                x1 -= dx1;
913                dx1 = 0;
914        }
915        if (dy1<0)
916        {
917                y1 -= dy1;
918                dy1 = 0;
919        }
920        if (dx1 + x2-x1 >= xres)
921                x2 = (xres - 1) - dx1 + x1;
922        if (dy1 + y2-y1 >= yres)
923                y2 = (yres - 1) - dy1 + y1;
924
925                        if (x2>=x1 && y2>=y1)
926                                (*SpeedCopyBits)(im, x1,y1,x2,y2,dx1,dy1);
927#else
928                GWorldPtr gw;
929                Rect src,dst;
930
931        gw = (GWorldPtr)im->special->extended_descriptor;
932
933        dst.left = (xoff + dr->dx1)*PixMult;
934        dst.top = (yoff + dr->dy1)*PixMult;
935        dst.right = (xoff + dr->dx2 + 1)*PixMult;
936        dst.bottom = (yoff + dr->dy2 + 1)*PixMult;
937        src.left = dr->dx1;
938        src.top = dr->dy1;
939        src.right = dr->dx2 + 1;
940        src.bottom = dr->dy2 + 1;
941       
942                        CopyBits((BitMap *) (*(gw->portPixMap)),
943                                        (BitMap*) (*(mainwin->portPixMap)),
944                                        &src,
945                                        &dst,
946                                        srcCopy, nil);
947//      put_part_image(win,im,xoff+dr->dx1,yoff+dr->dy1,dr->dx1,dr->dy1,dr->dx2,dr->dy2);     
948//      XDrawRectangle(display,mainwin,gc,xoff+dr->dx1,yoff+dr->dy1,
949//                   xoff+dr->dx2-dr->dx1+1,yoff+dr->dy2-dr->dy1+1);
950#endif
951      q=dr;
952      dr=(dirty_rect *) (dr->next());
953      im->special->dirties.unlink((linked_node *)q);
954      delete q;
955      count--;
956    }
957  }
958//  XFlush(display);
959}
960
961void fill_image(image *im, int x1, int y1, int x2, int y2);
962void clear_put_image(image *im, int x, int y);
963
964int DEBUG_PAL = 0;
965
966void palette::load()
967{
968        if (DEBUG_PAL)
969                return;
970       
971#ifdef PAL_DIRECT
972        ColorSpec *spec;
973        VDSetEntryRecord setEntriesRec;
974        Ptr                              csPtr;
975        QDErr                   error;
976
977        spec = (**MacCT).ctTable;
978        for (int i=0; i<(**MacCT).ctSize; i++)
979        {
980                spec[i].rgb.red = red(i) * 256;
981                spec[i].rgb.green = green(i) * 256;
982                spec[i].rgb.blue = blue(i) * 256;
983                spec[i].value = i;
984        }
985        setEntriesRec.csTable = (ColorSpec *)&(**MacCT).ctTable;
986        setEntriesRec.csStart = 0;
987        setEntriesRec.csCount = (**MacCT).ctSize;
988        csPtr = (Ptr) &setEntriesRec;
989        error = Control ((**gd).gdRefNum, cscSetEntries, (Ptr) &csPtr);
990        if (error)
991                dprintf("aieee! palette problem!\n");
992#else
993        ColorSpec *spec;
994        spec = (**MacCT).ctTable;
995        for (int i=0; i<pal_size(); i++)
996        {
997                spec[i].rgb.red = red(i) * 256;
998                spec[i].rgb.green = green(i) * 256;
999                spec[i].rgb.blue = blue(i) * 256;
1000                spec[i].value = i;
1001        }
1002//      (**MacCT).ctSeed = GetCTSeed();
1003        CTab2Palette(MacCT,MacPal,pmTolerant,0);
1004        NSetPalette((WindowPtr)mainwin,MacPal,pmAllUpdates);
1005//              HLockHi((Handle)mainwin->portPixMap);
1006//              LockPixels(mainwin->portPixMap);
1007//      (**mainwin->portPixMap).pmTable = MacCT;
1008        ActivatePalette((WindowPtr)mainwin);
1009#endif
1010}
1011
1012void palette::load_nice()
1013{
1014        // adapt palette to system's
1015        load();
1016}
1017
1018extern void fade_in(image *im, int steps);
1019extern void fade_out(int steps);
1020
1021void Pre_Hack_Mode()
1022{
1023#ifdef VIDEO_DIRECT
1024  // select copy routine
1025  switch (PixMode)
1026  {
1027        case 1:
1028                SpeedCopyBits = &SpeedCopyBits11;
1029                PixMult = 1;
1030                gVideoMem = gGame1VideoMem;
1031                        break;
1032        case 2:
1033                SpeedCopyBits = &SpeedCopyBits21Fast;
1034                PixMult = 2;
1035                gVideoMem = gGame2VideoMem;
1036                break;
1037        case 3:
1038                SpeedCopyBits = &SpeedCopyBits22Fast;
1039                PixMult = 2; 
1040                gVideoMem = gGame2VideoMem;
1041                break;
1042        default:
1043                dprintf("Aiiieee!  Can't set direct video copier.. it's gonna blow!\n");
1044                exit(0);
1045                break;
1046  }
1047#endif
1048        xres = 320;
1049        yres = 200;
1050        screen->HackW(xres);
1051        screen->HackH(yres);
1052        screen->special->resize(xres,yres);
1053}
1054
1055void Hack_Mode()
1056{
1057//      if (dev & EDIT_MODE)
1058//              return;
1059
1060        if (HackMode)
1061                return;
1062               
1063        char *p = gVideoMem;
1064        for (int y=Bounds.top; y<Bounds.bottom; y++)
1065        {
1066                memset(p,0xff,Bounds.right-Bounds.left);
1067                p += gVideoRowBytes;
1068        }               
1069
1070        HackMode = 1;
1071        Pre_Hack_Mode();
1072}
1073
1074void Unhack_Mode()
1075{
1076//      if (dev & EDIT_MODE)
1077//              return;
1078
1079        HackMode = 0;
1080        SpeedCopyBits = &SpeedCopyBits11;
1081        PixMult = 1;
1082        xres = gRect->right - gRect->left;
1083        yres = gRect->bottom - gRect->top;
1084        screen->HackW(xres);
1085        screen->HackH(yres);
1086        screen->special->resize(xres,yres);
1087        gVideoMem = gRealVideoMem;
1088}
1089
1090void switch_mode(video_mode new_mode)
1091{
1092  if (new_mode==VMODE_320x200)
1093    Hack_Mode();
1094  else if (new_mode==VMODE_640x480)
1095    Unhack_Mode();
1096}
1097
1098/*
1099unsigned char SmoothTable[256][256];
1100
1101void MakeSmoothTable()
1102{
1103        for (int i=0; i<256; i++)
1104                for (int j=i; j<256; j++)
1105                {
1106                        int r,b,g,v;
1107                       
1108                        r = (pal->red(i) + pal->red(j))/2;
1109                        g = (pal->green(i) + pal->green(j))/2;
1110                        b = (pal->blue(i) + pal->blue(j))/2;
1111                       
1112                        v = pal->find_color(r,g,b);
1113                       
1114                        SmoothTable[i][j] = v;
1115                        SmoothTable[j][i] = v;
1116                }
1117}
1118
1119*/
Note: See TracBrowser for help on using the repository browser.