completely finished the documentation of the EBUF module (!)
[neuro.git] / src / video / graphics.c
blob1623b0abee6661856f0b722e0edf96992208b6b2
2 /*
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
22 /* graphics.c
23 * Module : Graphic_
25 * main Graphics source file and main interface
26 * for this module.
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 ---*/
37 #include "video.h"
39 /*--- Main Module Header ---*/
40 #include <graphics.h>
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 ---*/
86 static void
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;
99 u32 total = 0;
101 if (safe_draw_operation == 0)
102 return 0;
104 if (!elem)
105 return 0;
108 if (!elem->current)
109 return 0;
111 if (!elem->current->surface_ptr)
112 return 0;
114 total = Neuro_GiveEBufCount(Graphics_GetQueueBuffer()) + 1;
116 while(total-- > 0)
118 tmp = Neuro_GiveEBuf(Graphics_GetQueueBuffer(), total);
120 if (tmp == elem)
121 return 1;
124 return 0;
128 Graphics_GetSafeDrawOp()
130 return safe_draw_operation;
133 void
134 Graphics_SetSafeDrawOp(u8 safe)
136 if (safe > 1)
137 safe = 1;
139 safe_draw_operation = safe;
142 /* might become obsolete */
143 void
144 Neuro_SetFrameSkip(u32 frameskip)
146 frameSkip = frameskip;
149 /* might become obsolete */
150 void
151 Neuro_SetFpsLimit(u32 fpsLimit)
153 fps_limit = fpsLimit;
156 /* we need to move that to the interface function */
157 void
158 Neuro_GiveScreenSize(u32 *width, u32 *height)
160 Lib_GetScreenSize(width, height);
163 void
164 Neuro_RedrawScreen()
166 draw_this_cycle = 1;
169 void
170 Graphics_ResetScreenDraw()
172 draw_this_cycle = 0;
175 void
176 Graphics_SetDrawnLastCycle()
178 drawn_last_cycle = 1;
181 /* clean the whole screen */
182 void
183 Neuro_RefreshScreen()
185 Lib_FillRect(sclScreen, NULL, 0);
187 Graphics_PainterReset();
189 safe_draw_operation = 0;
192 void
193 Neuro_GiveFPS(t_tick *output)
195 *output = lFps;
198 /* use this function to set the background
199 * --will soon become obsolete--
201 void
202 Neuro_AddBackground(v_object *isurface)
204 /* obsoleted */
207 void
208 Neuro_AddDirectDrawing(Rectan *isrc, Rectan *idst, v_object *isurface)
210 Lib_BlitObject(isurface, isrc, sclScreen, idst);
212 /*Lib_BlitObject(sclScreen2, NULL, screen, NULL);
213 updScreen(0);
214 Lib_Flip(screen);*/
217 void *
218 Neuro_GetScreenBuffer()
220 return (void*)sclScreen;
223 /*--- Poll ---*/
225 void
226 Graphics_Poll()
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)
235 cleanPixels();
236 clean_pixel_in_this_cycle = 0;
241 if (ltime + 1 <= time(NULL))
243 lFps = fps;
244 fps = 0;
245 ltime = time(NULL);
247 else
249 /* lFps = 0; */
250 fps++;
253 if (fps_limit > 0 /*&& fps_limit <= fps*/)
255 /* in this case, we toggle a variable so nothing will be drawn
256 * this cycle
258 fps_dotincr += fps_limit;
260 if (fps_dotincr >= 100)
262 fps++;
264 if (fps_limit <= 100)
265 fps_dotincr -= 100;
266 else
267 fps_dotincr -= 100 * (int)(fps_limit / 100);
269 else
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;
289 else
291 dont_draw_this_cycle = 1;
292 frameSkip_tmp--;
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
314 * positive.
316 if (draw_this_cycle == 0)
318 INSTRUCTION_ENGINE *tmp;
320 tmp = Graphics_GetFirstElem();
322 if (tmp)
324 if (tmp->current->type == TDRAW_VOLATILE
325 || tmp->current->type == TDRAW_SDESTROY)
326 draw_this_cycle = 1;
331 if (draw_this_cycle)
332 Graphics_CoreDrawAll();
334 else
335 dont_draw_this_cycle = 0;
338 /* update the full screen */
339 if (draw_this_cycle && !dont_draw_this_cycle)
341 if (screen_buffer)
342 Lib_BlitObject(sclScreen, NULL, screen, NULL);
344 if (second_screen_buffer == 0)
345 updScreen(0);
347 draw_this_cycle = 0;
350 if (second_screen_buffer)
352 Lib_BlitObject(sclScreen2, NULL, screen, NULL);
353 updScreen(0);
357 /*--- Constructor Destructor ---*/
359 Graphics_Init()
361 int _err_ = 0;
362 u32 screenwidth, screenheight;
364 ltime = time(NULL);
366 Lib_GetScreenSize(&screenwidth, &screenheight);
368 if (screen_buffer)
370 _err_ = Lib_VideoInit(&screen, &sclScreen);
372 if (_err_ == 1)
374 Error_Print("Lib_VideoInit failed");
375 return 1;
378 else
380 _err_ = Lib_VideoInit(&screen, NULL);
382 if (_err_ == 1)
384 Error_Print("Lib_VideoInit failed");
385 return 1;
389 sclScreen = screen;
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");
400 return 1;
403 Lib_SetColorKey(sclScreen2, 0);
405 else
407 sclScreen2 = sclScreen;
412 Graphics_PainterInit();
414 return _err_;
417 void
418 Graphics_Clean()
421 Graphics_PainterClean();
424 if (use_memory_pool)
425 Pool_Clean();
428 if (screen)
430 Lib_FreeVobject(screen);
431 screen = NULL;
433 if (sclScreen && screen_buffer)
435 Lib_FreeVobject(sclScreen);
436 sclScreen = NULL;
438 if (sclScreen2 && second_screen_buffer)
440 Lib_FreeVobject(sclScreen2);
441 sclScreen2 = NULL;
444 Lib_VideoExit();