2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
5 Desc: Graphics function BestModeIDA()
9 #include <aros/debug.h>
10 #include <cybergraphx/cybergraphics.h>
11 #include <graphics/modeid.h>
12 #include <hidd/graphics.h>
13 #include <proto/graphics.h>
14 #include <proto/utility.h>
15 #include <proto/oop.h>
17 #include "graphics_intern.h"
20 /*****************************************************************************
23 #include <proto/graphics.h>
25 AROS_LH1(ULONG
, BestModeIDA
,
28 AROS_LHA(struct TagItem
*, TagItems
, A0
),
31 struct GfxBase
*, GfxBase
, 175, Graphics
)
36 TagItems - pointer to an array of TagItems
39 BIDTAG_ViewPort (struct ViewPort *) - Viewport for which a mode is searched. Default: NULL
40 BIDTAG_MonitorID (ULONG) - Returned ID must use this monitor
41 BIDTAG_SourceID (ULONG) - Use this ModeID instead of a ViewPort.
42 DIPFMustHave mask is made up of the
43 ((DisplayInfo->PropertyFlags of this ID & SPECIAL_FLAGS) |
46 if BIDTAG_ViewPort was passed: VPModeID(vp), else the
47 DIPFMustHave and DIPFMustNotHave are unchanged.
48 BIDTAG_Depth (UBYTE) - Minimal depth. Default:
49 if BIDTAG_ViewPort is passed: vp->RasInfo->BitMap->Depth,
51 BIDTAG_NominalWidth (UWORD),
52 BIDTAG_NominalHeight (UWORD) - Aspect radio. Default:
53 if BIDTAG_SourceID: SourceID NominalDimensionInfo
54 if BIDTAG_ViewPort: vp->DWidth and vp->DHeight
56 BIDTAG_DesiredWidth (UWORD) - Width. Default: DIBTAG_NominalWidth.
57 BIDTAG_DesiredHeight (UWORD) - Height. Default: BIDTAG_NominalHeight.
58 BIDTAG_RedBits (UBYTE),
59 BIDTAG_GreenBits (UBYTE),
60 BIDTAG_BlueBits (UBYTE) - Bits per gun the mode must support. Default: 4
61 BIDTAG_DIPFMustHave (ULONG) - DIPF flags the resulting mode must have
62 BIDTAG_DIPFMustNotHave (ULONG) - DIPF flags the resulting mode must not have
65 ID - ID of the best mode to use, or INVALID_ID if a match
75 graphics/modeid.h, graphics/displayinfo.h
78 This function also processes CYBRBIDTG_BoardName tag. This is private
79 to AROS, do not rely on it!
83 ******************************************************************************/
88 UWORD nominal_width
, nominal_height
;
89 UWORD desired_width
, desired_height
;
91 ULONG sourceid
, monitorid
;
92 UBYTE redbits
, greenbits
, bluebits
;
93 ULONG dipf_musthave
, dipf_mustnothave
;
96 struct DisplayInfoHandle
*dinfo
;
97 struct DisplayInfo disp
;
98 struct DimensionInfo dims
;
99 ULONG found_id
= INVALID_ID
;
100 UWORD found_depth
= -1;
101 UWORD found_width
= -1;
102 UWORD found_height
= -1;
104 /* Get defaults which can be overriden */
105 dipf_musthave
= GetTagData(BIDTAG_DIPFMustHave
, 0 , TagItems
);
106 dipf_mustnothave
= GetTagData(BIDTAG_DIPFMustNotHave
, SPECIAL_FLAGS
, TagItems
);
107 monitorid
= GetTagData(BIDTAG_MonitorID
, INVALID_ID
, TagItems
);
108 redbits
= GetTagData(BIDTAG_RedBits
, 4 , TagItems
);
109 greenbits
= GetTagData(BIDTAG_GreenBits
, 4 , TagItems
);
110 bluebits
= GetTagData(BIDTAG_BlueBits
, 4 , TagItems
);
112 /* Try to get viewport */
113 vp
= (struct ViewPort
*)GetTagData(BIDTAG_ViewPort
, 0, TagItems
);
115 nominal_width
= vp
->DWidth
;
116 nominal_height
= vp
->DHeight
;
117 sourceid
= GetVPModeID(vp
);
118 depth
= vp
->RasInfo
->BitMap
->Depth
;
120 sourceid
= INVALID_ID
;
122 nominal_height
= 200;
126 /* Then process SourceID, it overrides ViewPort size and mode */
127 sourceid
= GetTagData(BIDTAG_SourceID
, sourceid
, TagItems
);
128 if (sourceid
!= INVALID_ID
) {
129 if (GetDisplayInfoData(NULL
, (UBYTE
*)&disp
, sizeof(disp
), DTAG_DISP
, sourceid
) >= offsetof(struct DisplayInfo
, Resolution
))
130 dipf_musthave
|= (disp
.PropertyFlags
& SPECIAL_FLAGS
);
132 if (GetDisplayInfoData(NULL
, (UBYTE
*)&dims
, sizeof(dims
), DTAG_DIMS
, sourceid
) >= offsetof(struct DimensionInfo
, MaxOScan
)) {
133 nominal_width
= dims
.Nominal
.MaxX
- dims
.Nominal
.MinX
+ 1;
134 nominal_height
= dims
.Nominal
.MaxY
- dims
.Nominal
.MinY
+ 1;
138 /* Get high-priority parameters */
139 nominal_width
= GetTagData(BIDTAG_NominalWidth
, nominal_width
, TagItems
);
140 nominal_height
= GetTagData(BIDTAG_NominalHeight
, nominal_height
, TagItems
);
141 desired_width
= GetTagData(BIDTAG_DesiredWidth
, nominal_width
, TagItems
);
142 desired_height
= GetTagData(BIDTAG_DesiredHeight
, nominal_height
, TagItems
);
143 depth
= GetTagData(BIDTAG_Depth
, depth
, TagItems
);
145 boardname
= (STRPTR
)GetTagData(CYBRBIDTG_BoardName
, 0, TagItems
);
147 /* Exclude flags in MustHave from MustNotHave (CHECKME: if this correct?) */
148 dipf_mustnothave
&= ~dipf_musthave
;
149 /* Mask out bit 12 in monitorid because the user may (and will) pass in IDs defined in include/graphics/modeid.h
150 (like PAL_MONITOR_ID, VGA_MONITOR_ID, etc) which have bit 12 set) */
151 if (monitorid
!= INVALID_ID
)
152 monitorid
&= AROS_MONITOR_ID_MASK
;
154 D(bug("[BestModeIDA] Desired mode: %dx%dx%d, MonitorID 0x%08lX, MustHave 0x%08lX, MustNotHave 0x%08lX\n",
155 desired_width
, desired_height
, depth
, monitorid
, dipf_musthave
, dipf_mustnothave
));
157 /* OK, now we try to search for a mode that has the supplied charateristics */
158 for (modeid
= INVALID_ID
;;)
160 UWORD gm_width
, gm_height
;
162 modeid
= NextDisplayInfo(modeid
);
163 if (modeid
== INVALID_ID
)
166 D(bug("[BestModeIDA] Checking ModeID 0x%08lX... ", modeid
));
168 if ((monitorid
!= INVALID_ID
) && ((modeid
& AROS_MONITOR_ID_MASK
) != monitorid
)) {
169 D(bug("MonitorID does not match\n"));
173 dinfo
= FindDisplayInfo(modeid
);
175 D(bug("No DisplayInfoHandle!\n"));
182 OOP_GetAttr(dinfo
->drv
->gfxhidd
, aHidd_Gfx_DriverName
, (IPTR
*)&name
);
183 if (strcmp(boardname
, name
))
187 if (GetDisplayInfoData(dinfo
, (UBYTE
*)&disp
, sizeof(disp
), DTAG_DISP
, modeid
) < offsetof(struct DisplayInfo
, pad2
)) {
188 D(bug("No DisplayInfo!\n"));
191 if (disp
.NotAvailable
) { /* Filter out not available modes */
192 D(bug("Not available: %u\n", disp
.NotAvailable
));
195 if (disp
.PropertyFlags
& dipf_mustnothave
) { /* Filter out modes which do not meet out special needs */
196 D(bug("Has MustNotHave flags: 0x%08lX\n", disp
.PropertyFlags
));
199 if ((disp
.PropertyFlags
& dipf_musthave
) != dipf_musthave
) {
200 D(bug("Does not have MustHave flags: 0x%08lX\n", disp
.PropertyFlags
));
204 if (GetDisplayInfoData(dinfo
, (UBYTE
*)&dims
, sizeof(dims
), DTAG_DIMS
, modeid
) < offsetof(struct DimensionInfo
, MaxOScan
)) {
205 D(bug("No DimensionInfo!\n"));
208 gm_width
= dims
.Nominal
.MaxX
- dims
.Nominal
.MinX
+ 1;
209 gm_height
= dims
.Nominal
.MaxY
- dims
.Nominal
.MinY
+ 1;
210 D(bug("%ux%ux%u", gm_width
, gm_height
, dims
.MaxDepth
));
212 /* FIXME: Take aspect ratio into account (nominal_width : nominal_height) */
214 /* Check if mode is not worse than requested */
215 if ( disp
.RedBits
>= redbits
216 && disp
.GreenBits
>= greenbits
217 && disp
.BlueBits
>= bluebits
218 && dims
.MaxDepth
>= depth
219 && gm_width
>= desired_width
220 && gm_height
>= desired_height
)
222 /* Check if this mode matches closer than the one we already found */
223 if ((dims
.MaxDepth
<= found_depth
) &&
224 (gm_width
<= found_width
) && (gm_height
<= found_height
)) {
226 found_depth
= dims
.MaxDepth
;
227 found_width
= gm_width
;
228 found_height
= gm_height
;
234 } /* for (each modeid) */
236 D(bug("[BestModeIDA] Returning mode ID 0x%08lX\n", found_id
));