using kprintf to output debug, which may be redirected to serial, is not a good idea...
[AROS-Contrib.git] / MultiMedia / AMP2 / amigaos / video.c
blob0ed8b3530029cbc7d7bbf765773bb505647113ef
1 /*
3 * video.c
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
12 #include <exec/types.h>
13 #include <exec/nodes.h>
14 #include <exec/lists.h>
15 #include <exec/memory.h>
17 #if !defined(__AROS__)
18 #include <powerup/ppcproto/intuition.h>
19 #include <powerup/ppclib/interface.h>
20 #include <powerup/ppclib/time.h>
21 #include <powerup/gcclib/powerup_protos.h>
22 #include <powerup/ppcproto/exec.h>
23 #include <powerup/ppcinline/graphics.h>
24 #include <powerup/ppcproto/dos.h>
25 #include <powerup/ppcproto/asl.h>
27 #include <powerup/ppcproto/gadtools.h>
28 #include <powerup/ppcinline/cybergraphics.h>
29 #include <proto/picasso96.h>
30 #else
32 #include "aros-inc.h"
34 #endif
36 #include <cybergraphx/cgxvideo.h>
37 #include <proto/cgxvideo.h>
38 #include <cybergraphx/cybergraphics.h>
40 #include <graphics/displayinfo.h>
42 #include "video.h"
43 #include "aga.h"
44 #include "cgfx.h"
45 #include "../main/main.h"
46 #include "../main/prefs.h"
47 #include "../refresh/refresh.h"
48 #include "../refresh/refresh_internal.h"
50 #define AGA 1
51 #define CGFX 2
53 extern struct IntuitionBase *IntuitionBase;
54 extern struct GfxBase *GfxBase;
55 extern struct Library *CyberGfxBase;
56 extern struct Library *CGXVideoBase;
57 extern struct Library *P96Base;
58 extern unsigned char *baseaddress[3];
59 extern unsigned long pixfmt, bpr, bpp;
60 extern struct BitMap agabitmap[3];
62 struct Screen *screen = NULL;
63 struct Window *window = NULL;
64 struct ScreenBuffer *sbuffer[3] = { NULL, NULL, NULL };
66 static struct ScreenModeRequester *screenreq = NULL;
67 static ULONG rgbtab[1+3*256+1];
68 static struct DimensionInfo dim;
69 #if !defined(__AROS__)
70 static VLayerHandle VLH = NULL;
71 #else
72 static struct VLayerHandle *VLH = NULL;
73 #endif
74 static UWORD *EmptyPointer = NULL;
75 static int cur_sbuffer = 0, free_sbuffer = 0;
76 static int use_vlayer = 0, screentype = 0;
77 static unsigned long *vlayerimage = NULL;
78 static struct PropInfo BotGadInfo = {0};
79 static struct Image BotGadImage = {0};
80 static struct Gadget BotGad = {0};
81 static unsigned long *aga_window_buffer = NULL;
82 static struct BitMap *window_bitmap = NULL;
83 static int amiga_depth = 0;
84 static char *window_text = NULL;
85 static int overlay_is_locked = 0;
86 static int down = 0, amiga_is_down = 0;
88 static char pixformats[][8] = {
89 "LUT8\0 ",
90 "RGB15\0 ",
91 "BGR15\0 ",
92 "RGB15PC\0",
93 "BGR15PC\0",
94 "RGB16\0 ",
95 "BGR16\0 ",
96 "RGB16PC\0",
97 "BGR16PC\0",
98 "RGB24\0 ",
99 "BGR24\0 ",
100 "ARGB32\0 ",
101 "BGRA32\0 ",
102 "RGBA32\0 "};
104 static struct {
105 unsigned long cgfx_mode;
106 unsigned long refresh_mode;
107 } mode_conv[] = {
108 { PIXFMT_LUT8, PIXEL_MODE_LUT8 },
109 { PIXFMT_RGB15, PIXEL_MODE_RGB15 },
110 { PIXFMT_RGB16, PIXEL_MODE_RGB16 },
111 { PIXFMT_ARGB32, PIXEL_MODE_ARGB32 },
112 { PIXFMT_BGR24, PIXEL_MODE_BGR24 },
113 { PIXFMT_RGB15PC, PIXEL_MODE_RGB15PC },
114 { PIXFMT_RGB16PC, PIXEL_MODE_RGB16PC },
115 { PIXFMT_BGRA32, PIXEL_MODE_BGRA32 },
116 { 0, 0}};
118 #define AMP_FLAGS (WFLG_NOCAREREFRESH|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_RMBTRAP|WFLG_GIMMEZEROZERO)
119 #define AMP_IDCMP (IDCMP_CLOSEWINDOW|IDCMP_RAWKEY|IDCMP_GADGETUP|IDCMP_GADGETDOWN)
121 void init_gadgets(void)
123 BotGadInfo.Flags = AUTOKNOB | FREEHORIZ | PROPNEWLOOK;
124 BotGadInfo.HorizPot = 0;
125 BotGadInfo.VertPot = 0;
126 BotGadInfo.HorizBody = MAXBODY/64;
127 BotGadInfo.VertBody = 0;
129 BotGad.LeftEdge = 3;
130 BotGad.TopEdge = -9;
131 BotGad.Width = -6;
132 BotGad.Height = 8;
134 BotGad.Flags = GFLG_RELBOTTOM | GFLG_RELWIDTH;
135 BotGad.Activation = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_BOTTOMBORDER;
136 BotGad.GadgetType = GTYP_PROPGADGET | GTYP_GZZGADGET;
137 BotGad.GadgetRender = (APTR)&BotGadImage;
138 BotGad.SpecialInfo = (APTR)&BotGadInfo;
139 BotGad.GadgetID = 0;
142 unsigned long get_screenmode_ID(int *width, int *height)
144 unsigned long id = 0;
146 if (prefs.screenmode == PREFS_BESTMODE) {
147 /* Best Mode, use custom implementation for CGFX */
148 if(CyberGfxBase != NULL) {
149 unsigned short cmodels_low[] = {PIXFMT_LUT8, -1};
150 unsigned short cmodels_high[] = {PIXFMT_RGB15, PIXFMT_RGB16, -1};
151 unsigned short cmodels_true[] = {PIXFMT_BGR24, PIXFMT_ARGB32, -1};
152 unsigned short *cmodels = NULL;
153 struct List *cmodelist = NULL;
154 struct CyberModeNode *mode;
156 if ((prefs.cgfx_depth == PREFS_LOWCOLOR) || (prefs.colormode == PREFS_GRAY)) {
157 cmodels = cmodels_low;
158 } else if (prefs.cgfx_depth == PREFS_HIGHCOLOR) {
159 cmodels = cmodels_high;
160 } else {
161 cmodels = cmodels_true;
164 cmodelist = AllocCModeListTags(CYBRMREQ_MinWidth, *width,
165 CYBRMREQ_MinHeight, *height,
166 CYBRMREQ_CModelArray, cmodels,
167 TAG_DONE);
169 if (cmodelist != NULL) {
170 if (!IsListEmpty(cmodelist)) {
171 int depth = 0;
172 *width = 16384; *height = 16384; /* Impossible values */
173 mode = (struct CyberModeNode *)cmodelist->lh_Head;
174 while (mode->Node.ln_Succ != NULL) {
176 debug_printf("MODE: %d x %d x %d, %08lx\n", mode->Width, mode->Height, mode->Depth, mode->DisplayID);
178 /* If the size of the previous best match is the same as the current, only swap
179 if we'll get a 24/16bit mode instead of a 32/15bit one */
180 if ((mode->Width == *width) && (mode->Height == *height)) {
181 if ((mode->Depth == 16) || (mode->Depth == 24)) {
182 depth = mode->Depth;
183 id = mode->DisplayID;
185 } else {
186 /* Choose the smallest suitable screenmode */
187 if ((mode->Width <= *width) || (mode->Height <= *height)) {
188 *width = mode->Width;
189 *height = mode->Height;
190 depth = mode->Depth;
191 id = mode->DisplayID;
194 mode = (struct CyberModeNode *)mode->Node.ln_Succ;
197 FreeCModeList(cmodelist);
200 if (id == 0) {
201 amp_printf("no suitable mode was found, try using the requester\n");
203 } else {
204 id = BestModeID(BIDTAG_DesiredWidth, *width,
205 BIDTAG_DesiredHeight, *height,
206 BIDTAG_NominalWidth, *width,
207 BIDTAG_NominalHeight, *height,
208 BIDTAG_Depth, 8);
209 if (id != INVALID_ID) {
210 if (GetDisplayInfoData(NULL, &dim, sizeof(dim), DTAG_DIMS, id) == 0) {
211 id = 0;
213 *width = dim.Nominal.MaxX + 1;
214 *height = dim.Nominal.MaxY + 1;
215 } else {
216 id = 0;
219 } else if (prefs.screenmode == PREFS_REQUESTER) {
220 /* Requester */
221 char asl_title[32];
222 sprintf(asl_title, "%dx%d", *width, *height);
223 screenreq = AllocAslRequestTags(ASL_ScreenModeRequest, TAG_END);
224 if (screenreq != NULL) {
225 int asl_done = 0;
226 if (AslRequestTags(screenreq, ASLSM_TitleText, asl_title, TAG_END)) {
227 id = screenreq->sm_DisplayID;
229 if (CyberGfxBase != NULL) {
230 if (IsCyberModeID(id)) {
231 *width = GetCyberIDAttr(CYBRIDATTR_WIDTH, id);
232 *height = GetCyberIDAttr(CYBRIDATTR_HEIGHT, id);
233 asl_done = 1;
237 if (asl_done == 0) {
238 if (GetDisplayInfoData(NULL, &dim, sizeof(dim), DTAG_DIMS, id) == 0) {
239 id = 0;
240 } else {
241 *width = dim.Nominal.MaxX + 1;
242 *height = dim.Nominal.MaxY + 1;
245 } else {
246 id = 0;
248 FreeAslRequest(screenreq);
249 } else {
250 id = 0;
252 } else if (prefs.screenmode == PREFS_HIPAL) {
253 /* PAL HiresLaced */
254 *width = 640;
255 *height = 512;
256 id = 0x00029004;
257 } else {
258 /* PAL Lores */
259 *width = 320;
260 *height = 256;
261 id = 0x00021000;
264 return id;
267 /* Free resources allocated by open_screen or open_audio_window */
268 void close_screen()
270 if (amiga_depth == 8) {
271 if (prefs.window == PREFS_ON) {
272 int i;
274 for (i=0; i<256; i++) {
275 ReleasePen(window->WScreen->ViewPort.ColorMap, refresh_rect.pixel[i]);
280 if (VLH != NULL) {
281 DetachVLayer(VLH);
282 DeleteVLayerHandle(VLH);
283 VLH = NULL;
286 if (window != NULL) {
287 CloseWindow(window);
288 window = NULL;
291 if (screen != NULL) {
292 if (screentype == AGA) {
293 close_screen_aga();
294 } else if (screentype == CGFX) {
295 close_screen_cgfx();
299 if (EmptyPointer != NULL) {
300 FreeVec(EmptyPointer);
301 EmptyPointer = NULL;
304 if (window_bitmap != NULL) {
305 FreeBitMap(window_bitmap);
306 window_bitmap = NULL;
309 if (refresh_rect.pixel != NULL) {
310 free(refresh_rect.pixel);
311 refresh_rect.pixel = NULL;
315 /* Triple buffering, call first, then render to free_buffer */
316 static void triple_refresh_init(void)
318 /* Next buffer please */
319 cur_sbuffer++;
320 if (cur_sbuffer > 2) {
321 cur_sbuffer = 0;
324 /* Display the next buffer */
325 sbuffer[cur_sbuffer]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = NULL;
326 while (!ChangeScreenBuffer(screen, sbuffer[cur_sbuffer]));
328 /* Always render to the buffer to be displayed next since touching the
329 previous or current is a "no no" since I don't check when the buffer
330 actually has been switched, so this is the only safe way */
332 free_sbuffer = cur_sbuffer + 1;
333 if (free_sbuffer > 2) {
334 free_sbuffer = 0;
337 if (screentype == AGA) {
338 refresh_rect.dst = (unsigned long *)agabitmap[free_sbuffer].Planes[0];
339 } else {
340 refresh_rect.dst = (unsigned long *)baseaddress[free_sbuffer];
345 static void triple_refresh_exit(void)
351 static void window_refresh_init()
356 static void window_refresh_exit()
358 BltBitMapRastPort(window_bitmap, 0, 0, window->RPort, 0, 0, refresh_rect.width, refresh_rect.height, 0xc0);
361 static void overlay_refresh_init()
363 if (LockVLayer(VLH)) {
364 vlayerimage = (unsigned long *)GetVLayerAttr(VLH, VOA_BaseAddress);
365 refresh_rect.dst = vlayerimage;
366 overlay_is_locked = 1;
367 } else {
368 overlay_is_locked = 0;
372 static void overlay_refresh_exit()
374 if (overlay_is_locked == 1) {
375 UnlockVLayer(VLH);
380 static void aga_window_refresh_init()
385 static void aga_window_refresh_exit()
387 WriteChunkyPixels(window->RPort, 0, 0, refresh_rect.width, refresh_rect.height, refresh_rect.dst, refresh_rect.width);
390 /* Returns "depth", i.e. 8 or 32 which are the only supported ones or -1 on error */
392 int open_screen(int width, int height, int mode)
394 int screen_width, screen_height;
395 unsigned long error, dispid;
396 unsigned long my_depth = 0;
397 int i, b;
399 refresh_rect.pixel = malloc(256);
401 screen_width = width;
402 screen_height = height;
404 cur_sbuffer = 0;
405 free_sbuffer = 0;
406 use_vlayer = 0;
407 screentype = 0;
408 down = 0;
409 amiga_is_down = 0;
411 init_gadgets();
413 /* Disable triple buffering when not used anyway */
414 if ((prefs.window == PREFS_ON) || (prefs.overlay == PREFS_ON)) {
415 prefs.triple = PREFS_OFF;
418 if (prefs.window == PREFS_ON) {
419 /* HAM not supported in window mode */
420 if (prefs.colormode == PREFS_HAM) {
421 prefs.colormode = PREFS_COLOR;
424 if ((CGXVideoBase != NULL) && (prefs.overlay == PREFS_ON)) {
425 BotGad.Width = -23;
426 window = OpenWindowTags(NULL,
427 WA_Title, prefs.window_title,
428 WA_ScreenTitle, prefs.registered,
429 WA_Flags, AMP_FLAGS|WFLG_SIZEGADGET|WFLG_SIZEBBOTTOM,
430 WA_IDCMP, AMP_IDCMP,
431 WA_Gadgets, &BotGad,
432 WA_Left, 100,
433 WA_Top, 100,
434 WA_InnerWidth, width,
435 WA_InnerHeight, height,
436 WA_MaxWidth, width*24,
437 WA_MaxHeight, height*24,
438 WA_Activate, TRUE,
439 TAG_DONE);
440 } else {
441 BotGad.Width = -6;
442 window = OpenWindowTags(NULL,
443 WA_Title, prefs.window_title,
444 WA_ScreenTitle, prefs.registered,
445 WA_Flags, AMP_FLAGS,
446 WA_IDCMP, AMP_IDCMP,
447 WA_Gadgets, &BotGad,
448 WA_Left, 100,
449 WA_Top, 100,
450 WA_InnerWidth, width,
451 WA_InnerHeight, height,
452 WA_Activate, TRUE,
453 TAG_DONE);
456 if (window == NULL) {
457 return -1;
460 if (GetCyberMapAttr(window->RPort->BitMap, CYBRMATTR_ISCYBERGFX)) {
461 screentype = CGFX;
462 } else {
463 screentype = AGA;
466 if ((CyberGfxBase != NULL) && (screentype == CGFX)) {
467 UnLockBitMap(LockBitMapTags(window->RPort->BitMap,
468 LBMI_PIXFMT, (ULONG)&pixfmt,
469 LBMI_BASEADDRESS, (ULONG)&baseaddress[free_sbuffer],
470 LBMI_BYTESPERPIX, (ULONG)&bpp,
471 LBMI_BYTESPERROW, (ULONG)&bpr,
472 LBMI_DEPTH, (ULONG)&my_depth,
473 TAG_END));
475 if (pixfmt == PIXFMT_LUT8) {
476 amiga_depth = 8;
477 } else {
478 amiga_depth = 32;
480 } else {
481 amiga_depth = 8; /* AGA is less than or equal to 8bit */
484 if ((CGXVideoBase != NULL) && (prefs.overlay == PREFS_ON) && (screentype = CGFX)) {
485 if ((mode == REFRESH_YUV420) || (prefs.colormode == PREFS_GRAY)) {
486 VLH = CreateVLayerHandleTags(window->WScreen,
487 VOA_SrcType, SRCFMT_YCbCr16,
488 VOA_SrcWidth, width,
489 VOA_SrcHeight, height,
490 VOA_Error, &error,
491 TAG_DONE);
492 } else {
493 VLH = CreateVLayerHandleTags(window->WScreen,
494 VOA_SrcType, SRCFMT_RGB16PC,
495 VOA_SrcWidth, width,
496 VOA_SrcHeight, height,
497 VOA_Error, &error,
498 TAG_DONE);
501 if (VLH != NULL) {
502 if (!AttachVLayerTags(VLH, window, TAG_DONE)) {
503 use_vlayer = 1;
504 if(LockVLayer(VLH)) {
505 vlayerimage = (unsigned long *)GetVLayerAttr(VLH, VOA_BaseAddress);
506 UnlockVLayer(VLH);
508 } else {
509 amp_printf("could not attach VLayer\n");
510 DeleteVLayerHandle(VLH);
511 VLH = NULL;
512 return -1;
514 } else {
515 amp_printf("could not create VLayer handle (%ld)\n", error);
516 return -1;
520 if ((use_vlayer == 0) && (CyberGfxBase != NULL) && (screentype == CGFX)) {
521 window_bitmap = AllocBitMap(width, height, my_depth, BMF_CLEAR|BMF_DISPLAYABLE|BMF_INTERLEAVED|BMF_MINPLANES, window->RPort->BitMap);
523 UnLockBitMap(LockBitMapTags(window_bitmap,
524 LBMI_PIXFMT, (ULONG)&pixfmt,
525 LBMI_BASEADDRESS, (ULONG)&baseaddress[free_sbuffer],
526 LBMI_BYTESPERROW, (ULONG)&bpr,
527 LBMI_BYTESPERPIX, (ULONG)&bpp,
528 TAG_END));
530 prefs.gray_depth = 8; /* Always use as many grays as possible for window playback */
531 } else {
532 /* Get screenmode */
533 dispid = get_screenmode_ID(&screen_width, &screen_height);
535 if (dispid == 0) {
536 return -1;
539 screentype = AGA;
541 /* Disable HAM for 8bit movies */
542 if ((mode == REFRESH_LUT8) && (prefs.colormode == PREFS_HAM)) {
543 prefs.colormode = PREFS_COLOR;
546 if (CyberGfxBase != NULL) {
547 if (IsCyberModeID(dispid)) {
548 screentype = CGFX;
552 screen_height &= ~1; /* mod 2 */
553 if (screentype == AGA) {
554 screen_width &= ~63; /* mod 64 */
555 } else {
556 screen_width &= ~15; /* mod 16 */
559 /* Open requested screen, or no screen at all */
560 if (screentype == AGA) {
561 if (open_screen_aga(screen_width, screen_height, dispid) < 0) {
562 return -1;
564 } else if (screentype == CGFX) {
565 prefs.half = PREFS_OFF; /* Not supported for CGFX */
566 prefs.gray_depth = 8; /* CGFX only support 8bit screens */
567 if (prefs.colormode == PREFS_HAM) {
568 prefs.colormode = PREFS_COLOR;
570 if (open_screen_cgfx(screen_width, screen_height, dispid) < 0) {
571 return -1;
575 /* Open window */
576 window = OpenWindowTags(NULL,
577 WA_CustomScreen,(int)screen,
578 WA_Width,screen->Width,
579 WA_Height,screen->Height,
580 WA_Flags,WFLG_RMBTRAP,
581 WA_IDCMP,IDCMP_RAWKEY,
582 WA_Backdrop,TRUE,
583 WA_Borderless,TRUE,
584 WA_Activate,TRUE,
585 TAG_DONE);
587 if (window == NULL) {
588 amp_printf("could not open the window\n");
589 return -1;
592 if ((screentype == CGFX) && (pixfmt != PIXFMT_LUT8)) {
593 /* Clear the screen with black pixels */
594 FillPixelArray(&screen->RastPort, 0, 0, screen->Width, screen->Height, 0x00000000);
597 if ((screentype == AGA) && (prefs.colormode == PREFS_HAM)) {
598 unsigned char val;
600 if (prefs.triple == PREFS_ON) {
601 b = 3;
602 } else {
603 b = 1;
606 for (i=0; i<b; i++) {
607 /* Init planes for fast HAM modes */
608 if (prefs.ham_width == 4) {
609 val = 0xcc;
610 } else {
611 val = 0x77;
613 memset(agabitmap[i].Planes[prefs.ham_depth - 1], val, RASSIZE(screen->Width, screen->Height));
615 if (prefs.ham_width == 4) {
616 val = 0x77;
617 } else {
618 val = 0xdd;
620 memset(agabitmap[i].Planes[prefs.ham_depth - 2], val, RASSIZE(screen->Width, screen->Height));
624 /* Hide the pointer */
625 EmptyPointer = AllocVec(512, MEMF_CHIP|MEMF_CLEAR);
626 if (EmptyPointer != NULL) {
627 SetPointer(window, EmptyPointer, 1, 1, 0, 0);
630 use_vlayer = 0;
632 if (screentype == CGFX) {
633 if (pixfmt == PIXFMT_LUT8) {
634 amiga_depth = 8;
635 } else {
636 amiga_depth = 32;
639 if ((CGXVideoBase != NULL) && (prefs.overlay == PREFS_ON)) {
640 if ((mode == REFRESH_YUV420) || (prefs.colormode == PREFS_GRAY)) {
641 VLH = CreateVLayerHandleTags(screen,
642 VOA_SrcType, SRCFMT_YCbCr16,
643 VOA_SrcWidth, width,
644 VOA_SrcHeight, height,
645 VOA_Error, &error,
646 TAG_DONE);
647 } else {
648 VLH = CreateVLayerHandleTags(screen,
649 VOA_SrcType, SRCFMT_RGB16PC,
650 VOA_SrcWidth, width,
651 VOA_SrcHeight, height,
652 VOA_Error, &error,
653 TAG_DONE);
656 if (VLH != NULL) {
657 if (!AttachVLayerTags(VLH, window, TAG_DONE)) {
658 use_vlayer = 1;
659 if(LockVLayer(VLH)) {
660 vlayerimage = (unsigned long *)GetVLayerAttr(VLH, VOA_BaseAddress);
661 UnlockVLayer(VLH);
663 } else {
664 amp_printf("could not attach VLayer\n");
665 DeleteVLayerHandle(VLH);
666 VLH = NULL;
667 return -1;
669 } else {
670 amp_printf("could not create VLayer handle (%ld)\n", error);
671 return -1;
674 } else {
675 if (prefs.colormode == PREFS_HAM) {
676 amiga_depth = 32;
677 } else {
678 amiga_depth = 8;
683 /* Get refresh mode */
684 refresh_rect.pixel_mode = 0;
685 i = 0;
686 while (mode_conv[i].refresh_mode != 0) {
687 if (pixfmt == mode_conv[i].cgfx_mode) {
688 refresh_rect.pixel_mode = mode_conv[i].refresh_mode;
689 break;
691 i++;
694 if ((use_vlayer == 0) && (refresh_rect.pixel_mode == 0)) {
695 amp_printf("unsupported pixel format %s\n", pixformats[pixfmt]);
696 return -1;
699 amp_printf("Video: %dx%d\n", width, height);
701 if (screen != NULL) {
702 verbose_printf("Screen: %dx%d\n", screen->Width, screen->Height);
703 } else {
704 verbose_printf("Window: %dx%d\n", width, height);
707 if (screentype == CGFX) {
708 verbose_printf("Pixel Format: %s\n", pixformats[pixfmt]);
709 } else {
710 verbose_printf("Pixel Format: PLANAR\n");
713 /* init/exit */
714 refresh_rect.init = NULL;
715 refresh_rect.exit = NULL;
716 if (screen != NULL) {
717 if (use_vlayer == 1) {
718 printf("OVERLAY screen\n");
719 refresh_rect.init = overlay_refresh_init;
720 refresh_rect.exit = overlay_refresh_exit;
721 } else if (prefs.triple == PREFS_ON) {
722 printf("TRIPLE screen\n");
723 refresh_rect.init = triple_refresh_init;
724 } else {
725 printf("SINGLE screen\n");
727 } else {
728 if (use_vlayer == 1) {
729 printf("OVERLAY window\n");
730 refresh_rect.init = overlay_refresh_init;
731 refresh_rect.exit = overlay_refresh_exit;
732 } else if (screentype == CGFX) {
733 printf("CGFX window\n");
734 refresh_rect.exit = window_refresh_exit;
735 } else {
736 printf("AGA window\n");
737 aga_window_buffer = malloc(refresh_rect.width * refresh_rect.height);
738 refresh_rect.exit = aga_window_refresh_exit;
742 /* size */
743 if (screen != NULL) {
744 refresh_rect.screen_width = screen->Width;
745 refresh_rect.screen_height = screen->Height;
746 } else {
747 refresh_rect.screen_width = refresh_rect.width;
748 refresh_rect.screen_height = refresh_rect.height;
751 refresh_rect.dst = (unsigned long *)baseaddress[free_sbuffer];
753 if (use_vlayer == 1) {
754 refresh_rect.dst = vlayerimage;
755 bpr = refresh_rect.width * 2;
756 refresh_rect.init();
757 for (i=0; i<refresh_rect.screen_width * refresh_rect.screen_height / 2; i++) {
758 refresh_rect.dst[i] = 0x00800080;
760 refresh_rect.exit();
763 if (screentype == AGA) {
764 bpp = 1;
765 if (screen != NULL) {
766 refresh_rect.dst = (unsigned long *)agabitmap[free_sbuffer].Planes[0];
767 bpr = screen->Width;
768 } else {
769 refresh_rect.dst = aga_window_buffer;
770 bpr = refresh_rect.width;
774 refresh_rect.bpr = bpr;
775 refresh_rect.bpp = bpp;
777 if (use_vlayer == 1) {
778 refresh_rect.screen_type = TYPE_OVERLAY;
779 } else if (screentype == AGA) {
780 refresh_rect.screen_type = TYPE_PLANAR;
781 } else {
782 refresh_rect.screen_type = TYPE_CHUNKY;
785 if (amiga_depth == 8) {
786 return 8;
787 } else {
788 return 32;
792 void open_audio_window(char *text)
794 /* Window already open? */
795 if (window != NULL) {
796 return;
799 init_gadgets();
801 window_text = strdup(text);
803 BotGad.Width = -6;
804 window = OpenWindowTags(NULL,
805 WA_Title, prefs.window_title,
806 WA_ScreenTitle, prefs.registered,
807 WA_Flags, AMP_FLAGS,
808 WA_IDCMP, AMP_IDCMP|IDCMP_CHANGEWINDOW,
809 WA_Gadgets, &BotGad,
810 WA_Left, 100,
811 WA_Top, 100,
812 WA_Width, 220,
813 WA_Height, 42,
814 WA_Activate, TRUE,
815 TAG_DONE);
817 if (window == NULL) {
818 amp_printf("could NOT open window\n");
819 return;
820 } else {
821 struct IntuiMessage *imsg = NULL;
822 ULONG imCode, imClass;
824 /* Resize window and set pens */
825 int length = TextLength(window->RPort, window_text, strlen(window_text));
826 ChangeWindowBox(window, 100, 100, window->BorderLeft+length+window->BorderRight+8, window->BorderTop+window->IFont->tf_YSize*2+window->BorderBottom);
827 SetAPen(window->RPort, 1);
828 SetBPen(window->RPort, 0);
830 /* Wait until window has been resized */
831 for(;;) {
832 /* Wait for IDCMP message */
833 WaitPort(window->UserPort);
835 /* Check for IDCMP messages */
836 if ((imsg = (struct IntuiMessage *)GetMsg(window->UserPort))) {
837 imClass = imsg->Class;
838 imCode = imsg->Code;
840 ReplyMsg((struct Message *)imsg);
842 if (imClass == IDCMP_CHANGEWINDOW) {
843 Move(window->RPort, 4, window->IFont->tf_YSize);
844 Text(window->RPort, window_text, strlen(window_text));
845 break; /* We are done waiting */
852 static char chapter[3] = "00\0"; /* FIXME */
854 int dvd_input_hack = -1;
856 int check_window(int new_position, int do_wait)
858 struct IntuiMessage *imsg = NULL;
859 ULONG imCode, imClass;
860 int ret = CHECK_OK;
862 /* No window !? Then quit! */
863 if (window == NULL) {
864 return CHECK_QUIT;
867 if (do_wait) {
868 WaitPort(window->UserPort);
871 dvd_input_hack = -1;
873 /* Check for IDCMP messages */
874 if ((imsg = (struct IntuiMessage *)GetMsg(window->UserPort))) {
875 imClass = imsg->Class;
876 imCode = imsg->Code;
878 ReplyMsg((struct Message *)imsg);
880 if (imClass == IDCMP_CLOSEWINDOW) {
881 ret = CHECK_QUIT;
882 } else if (imClass == IDCMP_RAWKEY) {
883 if (imCode & 0x80) {
884 /* key is released */
885 imCode &= 0x7f;
887 dvd_input_hack = imCode;
889 switch (imCode) {
890 /* ESC */
891 case 69:
892 ret = CHECK_QUIT;
893 break;
895 /* 1 - 9 */
896 case 1: case 2: case 3:
897 case 4: case 5: case 6:
898 case 7: case 8: case 9:
899 ret = imCode * 10;
900 break;
903 #define KEY_0_PAD 15
904 #define KEY_1_PAD 29
905 #define KEY_2_PAD 30
906 #define KEY_3_PAD 31
907 #define KEY_4_PAD 45
908 #define KEY_5_PAD 46
909 #define KEY_6_PAD 47
910 #define KEY_7_PAD 61
911 #define KEY_8_PAD 62
912 #define KEY_9_PAD 63
913 #define KEY_DEL_PAD 60
914 #define KEY_ENTER_PAD 67
915 #define KEY_BACKSPACE 65
918 case 15:
919 chapter[0] = chapter[1];
920 chapter[1] = '0';
921 break;
923 case 29: case 30: case 31:
924 chapter[0] = chapter[1];
925 chapter[1] = '0' + (imCode - 29 + 1);
926 break;
928 case 45: case 46: case 47:
929 chapter[0] = chapter[1];
930 chapter[1] = '0' + (imCode - 45 + 4);
931 break;
933 case 61: case 62: case 63:
934 chapter[0] = chapter[1];
935 chapter[1] = '0' + (imCode - 61 + 7);
936 break;
938 case 60: case 65:
939 chapter[0] = '0';
940 chapter[1] = '0';
941 break;
943 case 67:
944 sscanf(chapter, "%d", &ret);
945 debug_printf("CHAPTER: %d\n", ret);
946 chapter[0] = '0';
947 chapter[1] = '0';
948 break;
950 /* 0 */
951 case 10:
952 ret = 0;
953 break;
955 case 64:
956 ret = CHECK_PAUSE;
957 break;
959 case 68:
960 ret = CHECK_CONT;
961 if (amiga_is_down) {
962 ret = CHECK_FLIP;
964 break;
966 case 102: case 103:
967 amiga_is_down = 0;
968 break;
970 /* DVD hack
971 #define KEY_LEFT 79
972 #define KEY_RIGHT 78
973 #define KEY_UP 76
974 #define KEY_DOWN 77
975 #define KEY_TAB 66
977 case KEY_LEFT:
978 case KEY_RIGHT:
979 case KEY_UP:
980 case KEY_DOWN:
981 case KEY_TAB:
982 ret = imCode;
983 break;
986 default:
987 break;
989 } else {
990 switch (imCode) {
991 case 102: case 103:
992 amiga_is_down = 1;
993 break;
995 default:
996 break;
999 } else if (imClass == IDCMP_GADGETUP) {
1000 down = 0;
1001 ret = ((BotGadInfo.HorizPot) * 100) / 65535; /* I want % */
1003 else if (imClass == IDCMP_GADGETDOWN) {
1004 down = 1;
1008 if ((down == 0) && (new_position >= 0)) {
1009 /* This test belongs here */
1010 if (new_position > 65535) {
1011 new_position = 65535;
1013 NewModifyProp(&BotGad, window, NULL, AUTOKNOB | FREEHORIZ | PROPNEWLOOK, new_position, 0, MAXBODY/64, 0, 1);
1016 return ret;
1019 void set_palette(int colors)
1021 int i;
1023 if (amiga_depth == 8) {
1024 if (prefs.window == PREFS_ON) {
1025 static int pens_allocated = 0;
1026 int R, G, B;
1028 if (pens_allocated == 1) {
1029 for (i=0; i<256; i++) {
1030 ReleasePen(window->WScreen->ViewPort.ColorMap, refresh_rect.pixel[i]);
1034 memset(refresh_rect.pixel, 0, 256);
1036 for(i=0; i<256; i++) {
1037 R = (refresh_rect.palette[i]<< 8)&0xff000000;
1038 G = (refresh_rect.palette[i]<<16)&0xff000000;
1039 B = (refresh_rect.palette[i]<<24)&0xff000000;
1040 refresh_rect.pixel[i] = ObtainBestPen(window->WScreen->ViewPort.ColorMap, R, G, B, TAG_DONE);
1043 pens_allocated = 1;
1044 } else {
1045 for(i=0; i<colors; i++) {
1046 rgbtab[1+i*3+0] = (refresh_rect.palette[i]<< 8)&0xff000000;
1047 rgbtab[1+i*3+1] = (refresh_rect.palette[i]<<16)&0xff000000;
1048 rgbtab[1+i*3+2] = (refresh_rect.palette[i]<<24)&0xff000000;
1051 rgbtab[0] = (colors<<16)|0;
1052 rgbtab[1+colors*3] = 0;
1053 LoadRGB32(&screen->ViewPort, rgbtab);