]>
Commit | Line | Data |
---|---|---|
c7de829c WD |
1 | /**************************************************************************** |
2 | * | |
3 | * SciTech Nucleus Graphics Architecture | |
4 | * | |
5 | * Copyright (C) 1991-1998 SciTech Software, Inc. | |
6 | * All rights reserved. | |
7 | * | |
8 | * ====================================================================== | |
9 | * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW| | |
10 | * | | | |
11 | * |This copyrighted computer code contains proprietary technology | | |
12 | * |owned by SciTech Software, Inc., located at 505 Wall Street, | | |
13 | * |Chico, CA 95928 USA (http://www.scitechsoft.com). | | |
14 | * | | | |
15 | * |The contents of this file are subject to the SciTech Nucleus | | |
16 | * |License; you may *not* use this file or related software except in | | |
17 | * |compliance with the License. You may obtain a copy of the License | | |
18 | * |at http://www.scitechsoft.com/nucleus-license.txt | | |
19 | * | | | |
20 | * |Software distributed under the License is distributed on an | | |
21 | * |"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | | |
22 | * |implied. See the License for the specific language governing | | |
23 | * |rights and limitations under the License. | | |
24 | * | | | |
25 | * |REMOVAL OR MODIFICATION OF THIS HEADER IS STRICTLY PROHIBITED BY LAW| | |
26 | * ====================================================================== | |
27 | * | |
28 | * Language: ANSI C | |
29 | * Environment: Win32 | |
30 | * | |
31 | * Description: OS specific Nucleus Graphics Architecture services for | |
32 | * the Win32 operating system environments. | |
33 | * | |
34 | ****************************************************************************/ | |
35 | ||
36 | #include "pm_help.h" | |
37 | #include "pmapi.h" | |
38 | #include <stdio.h> | |
39 | #include <stdlib.h> | |
40 | #include <string.h> | |
41 | #define STRICT | |
42 | #define WIN32_LEAN_AND_MEAN | |
43 | #include <windows.h> | |
44 | ||
45 | /*------------------------- Global Variables ------------------------------*/ | |
46 | ||
47 | #define DLL_NAME "nga_w32.dll" | |
48 | ||
49 | extern HANDLE _PM_hDevice; | |
50 | static HMODULE hModDLL = NULL; | |
51 | static ibool useRing0Driver = false; | |
52 | static ibool haveRDTSC; | |
53 | static GA_largeInteger countFreq; | |
54 | ||
55 | /*-------------------------- Implementation -------------------------------*/ | |
56 | ||
57 | /**************************************************************************** | |
58 | REMARKS: | |
59 | Loads the shared "nga_w32.dll" library from disk and connects to it. This | |
60 | library is *always* located in the same directory as the Nucleus | |
61 | graphics.bpd file. | |
62 | ****************************************************************************/ | |
63 | static ibool LoadSharedDLL(void) | |
64 | { | |
65 | char filename[PM_MAX_PATH]; | |
66 | char bpdpath[PM_MAX_PATH]; | |
67 | ||
68 | /* Check if we have already loaded the DLL */ | |
69 | if (hModDLL) | |
8bde7f77 | 70 | return true; |
c7de829c WD |
71 | PM_init(); |
72 | ||
73 | /* Open the DLL file */ | |
74 | if (!PM_findBPD(DLL_NAME,bpdpath)) | |
8bde7f77 | 75 | return false; |
c7de829c WD |
76 | strcpy(filename,bpdpath); |
77 | strcat(filename,DLL_NAME); | |
78 | if ((hModDLL = LoadLibrary(filename)) == NULL) | |
8bde7f77 | 79 | return false; |
c7de829c WD |
80 | return true; |
81 | } | |
82 | ||
83 | /**************************************************************************** | |
84 | PARAMETERS: | |
85 | path - Local path to the Nucleus driver files. | |
86 | ||
87 | REMARKS: | |
88 | This function is used by the application program to override the location | |
89 | of the Nucleus driver files that are loaded. Normally the loader code | |
90 | will look in the system Nucleus directories first, then in the 'drivers' | |
91 | directory relative to the current working directory, and finally relative | |
92 | to the MGL_ROOT environment variable. | |
93 | ||
94 | Note that for Win32 we also call into the loaded PMHELP device driver | |
95 | as necessary to change the local Nucleus path for system wide Nucleus | |
96 | drivers. | |
97 | ****************************************************************************/ | |
98 | void NAPI GA_setLocalPath( | |
99 | const char *path) | |
100 | { | |
101 | DWORD inBuf[1]; | |
102 | DWORD outBuf[1],outCnt; | |
103 | ||
104 | PM_setLocalBPDPath(path); | |
105 | if (_PM_hDevice != INVALID_HANDLE_VALUE) { | |
8bde7f77 WD |
106 | inBuf[0] = (DWORD)path; |
107 | DeviceIoControl(_PM_hDevice, PMHELP_GASETLOCALPATH32, | |
108 | inBuf, sizeof(inBuf), outBuf, sizeof(outBuf), &outCnt, NULL); | |
109 | } | |
c7de829c WD |
110 | } |
111 | ||
112 | /**************************************************************************** | |
113 | RETURNS: | |
114 | Pointer to the system wide PM library imports, or the internal version if none | |
115 | ||
116 | REMARKS: | |
117 | In order to support deploying new Nucleus drivers that may require updated | |
118 | PM library functions, we check here to see if there is a system wide version | |
119 | of the PM functions available. If so we return those functions for use with | |
120 | the system wide Nucleus drivers, otherwise the compiled in version of the PM | |
121 | library is used with the application local version of Nucleus. | |
122 | ****************************************************************************/ | |
123 | PM_imports * NAPI GA_getSystemPMImports(void) | |
124 | { | |
125 | PM_imports * pmImp; | |
126 | PM_imports * (NAPIP _GA_getSystemPMImports)(void); | |
127 | ||
128 | if (LoadSharedDLL()) { | |
8bde7f77 WD |
129 | /* Note that Visual C++ build DLL's with only a single underscore in front |
130 | * of the exported name while Watcom C provides two of them. We check for | |
131 | * both to allow working with either compiled DLL. | |
132 | */ | |
133 | if ((_GA_getSystemPMImports = (void*)GetProcAddress(hModDLL,"_GA_getSystemPMImports")) != NULL) { | |
134 | if ((_GA_getSystemPMImports = (void*)GetProcAddress(hModDLL,"__GA_getSystemPMImports")) != NULL) { | |
135 | pmImp = _GA_getSystemPMImports(); | |
136 | memcpy(&_PM_imports,pmImp,MIN(_PM_imports.dwSize,pmImp->dwSize)); | |
137 | return pmImp; | |
138 | } | |
139 | } | |
140 | } | |
c7de829c WD |
141 | return &_PM_imports; |
142 | } | |
143 | ||
144 | /**************************************************************************** | |
145 | PARAMETERS: | |
146 | gaExp - Place to store the exported functions | |
147 | shared - True if connecting to the shared, global Nucleus driver | |
148 | ||
149 | REMARKS: | |
150 | For Win32 if we are connecting to the shared, global Nucleus driver (loaded | |
151 | at ring 0) then we need to load a special nga_w32.dll library which contains | |
152 | thunks to call down into the Ring 0 device driver as necessary. If we are | |
153 | connecting to the application local Nucleus drivers (ie: Nucleus on DirectDraw | |
154 | emulation layer) then we do nothing here. | |
155 | ****************************************************************************/ | |
156 | ibool NAPI GA_getSharedExports( | |
157 | GA_exports *gaExp, | |
158 | ibool shared) | |
159 | { | |
160 | GA_exports * exp; | |
161 | GA_exports * (NAPIP _GA_getSystemGAExports)(void); | |
162 | ||
163 | useRing0Driver = false; | |
164 | if (shared) { | |
8bde7f77 WD |
165 | if (!LoadSharedDLL()) |
166 | PM_fatalError("Unable to load " DLL_NAME "!"); | |
167 | if ((_GA_getSystemGAExports = (void*)GetProcAddress(hModDLL,"_GA_getSystemGAExports")) == NULL) | |
168 | if ((_GA_getSystemGAExports = (void*)GetProcAddress(hModDLL,"__GA_getSystemGAExports")) == NULL) | |
169 | PM_fatalError("Unable to load " DLL_NAME "!"); | |
170 | exp = _GA_getSystemGAExports(); | |
171 | memcpy(gaExp,exp,MIN(gaExp->dwSize,exp->dwSize)); | |
172 | useRing0Driver = true; | |
173 | return true; | |
174 | } | |
c7de829c WD |
175 | return false; |
176 | } | |
177 | ||
178 | #ifndef TEST_HARNESS | |
179 | /**************************************************************************** | |
180 | REMARKS: | |
181 | Nothing special for this OS | |
182 | ****************************************************************************/ | |
183 | ibool NAPI GA_queryFunctions( | |
184 | GA_devCtx *dc, | |
185 | N_uint32 id, | |
186 | void _FAR_ *funcs) | |
187 | { | |
188 | static ibool (NAPIP _GA_queryFunctions)(GA_devCtx *dc,N_uint32 id,void _FAR_ *funcs) = NULL; | |
189 | ||
190 | if (useRing0Driver) { | |
8bde7f77 WD |
191 | /* Call the version in nga_w32.dll if it is loaded */ |
192 | if (!_GA_queryFunctions) { | |
193 | if ((_GA_queryFunctions = (void*)GetProcAddress(hModDLL,"_GA_queryFunctions")) == NULL) | |
194 | if ((_GA_queryFunctions = (void*)GetProcAddress(hModDLL,"__GA_queryFunctions")) == NULL) | |
195 | PM_fatalError("Unable to get exports from " DLL_NAME "!"); | |
196 | } | |
197 | return _GA_queryFunctions(dc,id,funcs); | |
198 | } | |
c7de829c WD |
199 | return __GA_exports.GA_queryFunctions(dc,id,funcs); |
200 | } | |
201 | ||
202 | /**************************************************************************** | |
203 | REMARKS: | |
204 | Nothing special for this OS | |
205 | ****************************************************************************/ | |
206 | ibool NAPI REF2D_queryFunctions( | |
207 | REF2D_driver *ref2d, | |
208 | N_uint32 id, | |
209 | void _FAR_ *funcs) | |
210 | { | |
211 | static ibool (NAPIP _REF2D_queryFunctions)(REF2D_driver *ref2d,N_uint32 id,void _FAR_ *funcs) = NULL; | |
212 | ||
213 | if (useRing0Driver) { | |
8bde7f77 WD |
214 | /* Call the version in nga_w32.dll if it is loaded */ |
215 | if (!_REF2D_queryFunctions) { | |
216 | if ((_REF2D_queryFunctions = (void*)GetProcAddress(hModDLL,"_REF2D_queryFunctions")) == NULL) | |
217 | if ((_REF2D_queryFunctions = (void*)GetProcAddress(hModDLL,"__REF2D_queryFunctions")) == NULL) | |
218 | PM_fatalError("Unable to get exports from " DLL_NAME "!"); | |
219 | } | |
220 | return _REF2D_queryFunctions(ref2d,id,funcs); | |
221 | } | |
c7de829c WD |
222 | return __GA_exports.REF2D_queryFunctions(ref2d,id,funcs); |
223 | } | |
224 | #endif | |
225 | ||
226 | /**************************************************************************** | |
227 | REMARKS: | |
228 | This function initialises the high precision timing functions for the | |
229 | Nucleus loader library. | |
230 | ****************************************************************************/ | |
231 | ibool NAPI GA_TimerInit(void) | |
232 | { | |
233 | if (_GA_haveCPUID() && (_GA_getCPUIDFeatures() & CPU_HaveRDTSC) != 0) { | |
8bde7f77 WD |
234 | haveRDTSC = true; |
235 | return true; | |
236 | } | |
c7de829c | 237 | else if (QueryPerformanceFrequency((LARGE_INTEGER*)&countFreq)) { |
8bde7f77 WD |
238 | haveRDTSC = false; |
239 | return true; | |
240 | } | |
c7de829c WD |
241 | return false; |
242 | } | |
243 | ||
244 | /**************************************************************************** | |
245 | REMARKS: | |
246 | This function reads the high resolution timer. | |
247 | ****************************************************************************/ | |
248 | void NAPI GA_TimerRead( | |
249 | GA_largeInteger *value) | |
250 | { | |
251 | if (haveRDTSC) | |
8bde7f77 | 252 | _GA_readTimeStamp(value); |
c7de829c | 253 | else |
8bde7f77 | 254 | QueryPerformanceCounter((LARGE_INTEGER*)value); |
c7de829c | 255 | } |