3 * libneuro, a light weight abstraction of high or lower libraries
4 * and toolkit for applications.
5 * Copyright (C) 2005-2006 Nicholas Niro, Robert Lemay
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 * main Graphics source file and main interface
29 /*--- Extern Headers Including ---*/
30 #include <time.h> /* to calculate the frames per second (fps) */
32 /*--- Local Headers Including ---*/
33 #include <extlib.h> /* we need to init the video and clean it... also use the blitter */
34 #include <ebuf.h> /* no longer needed */
36 /*--- local module main header ---*/
39 /*--- Main Module Header ---*/
42 /*--- Global Variables ---*/
44 /*--- Static Variables ---*/
46 static v_object
*screen
; /* the screen surface */
47 static v_object
*sclScreen
; /* attempt to do a double buffered screen (for the static type) */
48 static v_object
*sclScreen2
; /* another screen buffer used for the dynamic type */
51 static u32 fps
; /* used increment every cycles */
52 static u32 lFps
; /* used to give to other function the current's cycle fps count. */
53 static u32 ltime
; /* used for the fps count, it is used to know when 1 second passed. */
54 static u32 fps_limit
; /* used to limit the fps to this count. */
55 static u8 fps_dotincr
; /* used to after dot increment for the fps limiter algorithm */
56 /*static u8 fps_incr; *//* used to increment for the fps limiter algorithm */
57 static u32 frameSkip
= 0; /* holds the number of frames we have to skip. */
58 static u32 frameSkip_tmp
= 0; /* the count of frames skipped already. */
60 /* 1 is that we have drawn the last cycle and 0 is no */
61 static u8 drawn_last_cycle
;
63 /* 1 is that we don't draw anything in this cycle */
64 static u8 dont_draw_this_cycle
;
66 /* 1 is that we got new draw instruction this cycle so we have to draw. */
67 static u8 draw_this_cycle
;
69 /* 1 is that the Draw operations are safe,
70 * else they should not be considered safe
71 * and should be ignored
73 static u8 safe_draw_operation
= 1;
75 /* last frame we redrawn the pixels? */
76 /* static u8 lastPdraw; */
79 /*--- Static Prototypes ---*/
81 /* update only a part of the screen */
82 static void updScreen(Rectan
*rect
);
84 /*--- Static Functions ---*/
87 updScreen(Rectan
*rect
)
89 Lib_UpdateRect(screen
, rect
);
92 /*--- Global Functions ---*/
94 /* move that to coredraw.c */
96 Graphics_DrawIsPresent(v_elem
*elem
)
98 INSTRUCTION_ENGINE
*tmp
= NULL
;
101 if (safe_draw_operation
== 0)
111 if (!elem
->current
->surface_ptr
)
114 total
= Neuro_GiveEBufCount(Graphics_GetQueueBuffer()) + 1;
118 tmp
= Neuro_GiveEBuf(Graphics_GetQueueBuffer(), total
);
128 Graphics_GetSafeDrawOp()
130 return safe_draw_operation
;
134 Graphics_SetSafeDrawOp(u8 safe
)
139 safe_draw_operation
= safe
;
142 /* might become obsolete */
144 Neuro_SetFrameSkip(u32 frameskip
)
146 frameSkip
= frameskip
;
149 /* might become obsolete */
151 Neuro_SetFpsLimit(u32 fpsLimit
)
153 fps_limit
= fpsLimit
;
156 /* we need to move that to the interface function */
158 Neuro_GiveScreenSize(u32
*width
, u32
*height
)
160 Lib_GetScreenSize(width
, height
);
170 Graphics_ResetScreenDraw()
176 Graphics_SetDrawnLastCycle()
178 drawn_last_cycle
= 1;
181 /* clean the whole screen */
183 Neuro_RefreshScreen()
185 Lib_FillRect(sclScreen
, NULL
, 0);
187 Graphics_PainterReset();
189 safe_draw_operation
= 0;
193 Neuro_GiveFPS(t_tick
*output
)
198 /* use this function to set the background
199 * --will soon become obsolete--
202 Neuro_AddBackground(v_object
*isurface
)
208 Neuro_AddDirectDrawing(Rectan
*isrc
, Rectan
*idst
, v_object
*isurface
)
210 Lib_BlitObject(isurface
, isrc
, sclScreen
, idst
);
212 /*Lib_BlitObject(sclScreen2, NULL, screen, NULL);
218 Neuro_GetScreenBuffer()
220 return (void*)sclScreen
;
228 if (debug_instruction_buffer
|| dynamic_debug
)
229 Debug_Val(0, "cycle\n");
231 /* we will call a function in the module pixels in a near future */
233 if (clean_pixel_in_this_cycle)
236 clean_pixel_in_this_cycle = 0;
241 if (ltime
+ 1 <= time(NULL
))
253 if (fps_limit
> 0 /*&& fps_limit <= fps*/)
255 /* in this case, we toggle a variable so nothing will be drawn
258 fps_dotincr
+= fps_limit
;
260 if (fps_dotincr
>= 100)
264 if (fps_limit
<= 100)
267 fps_dotincr
-= 100 * (int)(fps_limit
/ 100);
270 dont_draw_this_cycle
= 1;
273 if (debug_instruction_buffer
)
275 Debug_Val(0, "--BEGIN debug print\n");
276 Graphics_DebugPrintQueue();
277 Debug_Val(0, "--END debug print\n");
280 /* construct the instruction buffer */
282 /* flush the instruction completely in the order
283 * presented and clean the raw engine buffer
285 if (frameSkip_tmp
<= 0)
287 frameSkip_tmp
= frameSkip
;
291 dont_draw_this_cycle
= 1;
296 if (!dont_draw_this_cycle
)
298 if (drawn_last_cycle
)
300 Graphics_CoreCleanDoneDynamics();
301 drawn_last_cycle
= 0;
304 if (debug_instruction_buffer
)
306 Debug_Val(0, "*BEGIN debug print\n");
307 Graphics_DebugPrintQueue();
308 Debug_Val(0, "*END debug print\n");
311 /* we check to see if the first element
312 * is a volatile type, if it is we will
313 * make the draw_this_cycle flag
316 if (draw_this_cycle
== 0)
318 INSTRUCTION_ENGINE
*tmp
;
320 tmp
= Graphics_GetFirstElem();
324 if (tmp
->current
->type
== TDRAW_VOLATILE
325 || tmp
->current
->type
== TDRAW_SDESTROY
)
332 Graphics_CoreDrawAll();
335 dont_draw_this_cycle
= 0;
338 /* update the full screen */
339 if (draw_this_cycle
&& !dont_draw_this_cycle
)
342 Lib_BlitObject(sclScreen
, NULL
, screen
, NULL
);
344 if (second_screen_buffer
== 0)
350 if (second_screen_buffer
)
352 Lib_BlitObject(sclScreen2
, NULL
, screen
, NULL
);
357 /*--- Constructor Destructor ---*/
362 u32 screenwidth
, screenheight
;
366 Lib_GetScreenSize(&screenwidth
, &screenheight
);
370 _err_
= Lib_VideoInit(&screen
, &sclScreen
);
374 Error_Print("Lib_VideoInit failed");
380 _err_
= Lib_VideoInit(&screen
, NULL
);
384 Error_Print("Lib_VideoInit failed");
392 if (second_screen_buffer
)
394 sclScreen2
= Lib_CreateVObject(0, screenwidth
, screenheight
,
395 Lib_GetDefaultDepth(), 0, 0, 0, 0);
397 if (sclScreen2
== NULL
)
399 Error_Print("Couldn't create a v object : sclScreen2");
403 Lib_SetColorKey(sclScreen2
, 0);
407 sclScreen2
= sclScreen
;
412 Graphics_PainterInit();
421 Graphics_PainterClean();
430 Lib_FreeVobject(screen
);
433 if (sclScreen
&& screen_buffer
)
435 Lib_FreeVobject(sclScreen
);
438 if (sclScreen2
&& second_screen_buffer
)
440 Lib_FreeVobject(sclScreen2
);