From 20896add5bfca00e28448437e5908b250f6be564 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Mon, 29 Jul 2024 16:54:19 +0300 Subject: [PATCH] drivers/dave2d: Add D/AVE 2D GPU driver. --- src/Makefile | 1 + src/drivers/dave2d/LICENSE | 44 + src/drivers/dave2d/Makefile | 60 + .../files/code/dave_64bitoperation-c.html | 58 + .../dave2d/docs/files/code/dave_blit-c.html | 66 + .../docs/files/code/dave_context-c.html | 136 + .../dave2d/docs/files/code/dave_dlist-c.html | 44 + .../dave2d/docs/files/code/dave_driver-c.html | 90 + .../docs/files/code/dave_perfcount-c.html | 46 + .../docs/files/code/dave_rbuffer-c.html | 92 + .../dave2d/docs/files/code/dave_render-c.html | 82 + .../docs/files/code/dave_texture-c.html | 78 + .../docs/files/code/dave_utility-c.html | 53 + .../docs/files/code/dave_viewport-c.html | 50 + .../docs/files/doc/images/blit_mapping.png | Bin 0 -> 13111 bytes .../dave2d/docs/files/doc/images/pattern.png | Bin 0 -> 1148 bytes .../dave2d/docs/files/doc/images/pwe.gif | Bin 0 -> 31960 bytes .../dave2d/docs/files/doc/images/trifan.gif | Bin 0 -> 582 bytes .../dave2d/docs/files/doc/images/trilist.gif | Bin 0 -> 568 bytes .../dave2d/docs/files/doc/images/tristrip.gif | Bin 0 -> 591 bytes .../dave2d/docs/files/doc/images/wedge.png | Bin 0 -> 8950 bytes .../docs/files/doc/images/wedgeconcave.png | Bin 0 -> 9967 bytes .../docs/files/doc/limitations-txt.html | 46 + .../dave2d/docs/files/doc/overview-txt.html | 80 + .../dave2d/docs/files/inc/dave_driver-h.html | 60 + .../docs/files/inc/dave_errorcodes-h.html | 38 + .../dave2d/docs/files/inc/dave_math-h.html | 68 + src/drivers/dave2d/docs/index.html | 1 + src/drivers/dave2d/docs/index/Functions.html | 53 + src/drivers/dave2d/docs/index/Functions2.html | 61 + src/drivers/dave2d/docs/index/Functions3.html | 33 + src/drivers/dave2d/docs/index/Functions4.html | 37 + src/drivers/dave2d/docs/index/General.html | 53 + src/drivers/dave2d/docs/index/General2.html | 61 + src/drivers/dave2d/docs/index/General3.html | 33 + src/drivers/dave2d/docs/index/General4.html | 45 + src/drivers/dave2d/docs/index/Types.html | 33 + src/drivers/dave2d/docs/javascript/main.js | 841 +++++++ .../dave2d/docs/javascript/prettify.js | 1526 ++++++++++++ .../dave2d/docs/javascript/searchdata.js | 92 + .../dave2d/docs/search/FunctionsA.html | 20 + .../dave2d/docs/search/FunctionsB.html | 20 + .../dave2d/docs/search/FunctionsC.html | 20 + .../dave2d/docs/search/FunctionsD.html | 20 + .../dave2d/docs/search/FunctionsE.html | 20 + .../dave2d/docs/search/FunctionsF.html | 20 + .../dave2d/docs/search/FunctionsG.html | 20 + .../dave2d/docs/search/FunctionsI.html | 20 + .../dave2d/docs/search/FunctionsL.html | 20 + .../dave2d/docs/search/FunctionsM.html | 20 + .../dave2d/docs/search/FunctionsN.html | 20 + .../dave2d/docs/search/FunctionsO.html | 20 + .../dave2d/docs/search/FunctionsP.html | 20 + .../dave2d/docs/search/FunctionsR.html | 20 + .../dave2d/docs/search/FunctionsS.html | 20 + .../dave2d/docs/search/FunctionsU.html | 20 + .../dave2d/docs/search/FunctionsW.html | 20 + src/drivers/dave2d/docs/search/GeneralA.html | 20 + src/drivers/dave2d/docs/search/GeneralB.html | 20 + src/drivers/dave2d/docs/search/GeneralC.html | 20 + src/drivers/dave2d/docs/search/GeneralD.html | 20 + src/drivers/dave2d/docs/search/GeneralE.html | 20 + src/drivers/dave2d/docs/search/GeneralF.html | 20 + src/drivers/dave2d/docs/search/GeneralG.html | 20 + src/drivers/dave2d/docs/search/GeneralI.html | 20 + src/drivers/dave2d/docs/search/GeneralL.html | 20 + src/drivers/dave2d/docs/search/GeneralM.html | 20 + src/drivers/dave2d/docs/search/GeneralN.html | 20 + src/drivers/dave2d/docs/search/GeneralO.html | 20 + src/drivers/dave2d/docs/search/GeneralP.html | 20 + src/drivers/dave2d/docs/search/GeneralR.html | 20 + src/drivers/dave2d/docs/search/GeneralS.html | 20 + src/drivers/dave2d/docs/search/GeneralT.html | 20 + src/drivers/dave2d/docs/search/GeneralU.html | 20 + src/drivers/dave2d/docs/search/GeneralV.html | 20 + src/drivers/dave2d/docs/search/GeneralW.html | 20 + src/drivers/dave2d/docs/search/NoResults.html | 15 + src/drivers/dave2d/docs/search/TypesD.html | 20 + src/drivers/dave2d/docs/styles/main.css | 829 +++++++ src/drivers/dave2d/include/dave_base.h | 1362 ++++++++++ src/drivers/dave2d/include/dave_box.h | 35 + src/drivers/dave2d/include/dave_circle.h | 31 + src/drivers/dave2d/include/dave_context.h | 160 ++ src/drivers/dave2d/include/dave_curve.h | 27 + .../dave2d/include/dave_d0_mm_dynamic.h | 21 + .../dave2d/include/dave_d0_mm_fixed_range.h | 36 + .../dave_d0_mm_fixed_range_fixed_blkcnt.h | 50 + src/drivers/dave2d/include/dave_d0lib.h | 298 +++ src/drivers/dave2d/include/dave_dlist.h | 258 ++ src/drivers/dave2d/include/dave_driver.h | 696 ++++++ src/drivers/dave2d/include/dave_edge.h | 72 + src/drivers/dave2d/include/dave_errorcodes.h | 72 + src/drivers/dave2d/include/dave_gradient.h | 47 + src/drivers/dave2d/include/dave_hardware.h | 35 + src/drivers/dave2d/include/dave_intern.h | 335 +++ src/drivers/dave2d/include/dave_line.h | 54 + src/drivers/dave2d/include/dave_math.h | 111 + src/drivers/dave2d/include/dave_memory.h | 28 + src/drivers/dave2d/include/dave_pattern.h | 21 + src/drivers/dave2d/include/dave_polyline.h | 33 + src/drivers/dave2d/include/dave_quad.h | 26 + src/drivers/dave2d/include/dave_rbuffer.h | 52 + src/drivers/dave2d/include/dave_registermap.h | 248 ++ src/drivers/dave2d/include/dave_render.h | 35 + src/drivers/dave2d/include/dave_texture.h | 35 + src/drivers/dave2d/include/dave_triangle.h | 29 + src/drivers/dave2d/include/dave_triarray.h | 22 + src/drivers/dave2d/include/dave_types.h | 33 + src/drivers/dave2d/include/dave_utility.h | 30 + src/drivers/dave2d/include/dave_videomodes.h | 59 + src/drivers/dave2d/include/dave_viewport.h | 21 + src/drivers/dave2d/include/dave_wedge.h | 25 + src/drivers/dave2d/src/dave_64bitoperation.c | 482 ++++ src/drivers/dave2d/src/dave_blit.c | 623 +++++ src/drivers/dave2d/src/dave_box.c | 413 ++++ src/drivers/dave2d/src/dave_circle.c | 291 +++ src/drivers/dave2d/src/dave_context.c | 2193 +++++++++++++++++ src/drivers/dave2d/src/dave_curve.c | 324 +++ src/drivers/dave2d/src/dave_d0_mm_dynamic.c | 103 + .../dave2d/src/dave_d0_mm_fixed_range.c | 353 +++ .../src/dave_d0_mm_fixed_range_fixed_blkcnt.c | 235 ++ src/drivers/dave2d/src/dave_d0lib.c | 391 +++ src/drivers/dave2d/src/dave_dlist.c | 1416 +++++++++++ src/drivers/dave2d/src/dave_driver.c | 1337 ++++++++++ src/drivers/dave2d/src/dave_edge.c | 660 +++++ src/drivers/dave2d/src/dave_errorcodes.c | 38 + src/drivers/dave2d/src/dave_gradient.c | 234 ++ src/drivers/dave2d/src/dave_hardware.c | 180 ++ src/drivers/dave2d/src/dave_line.c | 1455 +++++++++++ src/drivers/dave2d/src/dave_math.c | 79 + src/drivers/dave2d/src/dave_memory.c | 150 ++ src/drivers/dave2d/src/dave_pattern.c | 104 + src/drivers/dave2d/src/dave_perfcount.c | 181 ++ src/drivers/dave2d/src/dave_polyline.c | 583 +++++ src/drivers/dave2d/src/dave_quad.c | 534 ++++ src/drivers/dave2d/src/dave_rbuffer.c | 1344 ++++++++++ src/drivers/dave2d/src/dave_render.c | 1213 +++++++++ src/drivers/dave2d/src/dave_texture.c | 1428 +++++++++++ src/drivers/dave2d/src/dave_triangle.c | 437 ++++ src/drivers/dave2d/src/dave_utility.c | 470 ++++ src/drivers/dave2d/src/dave_viewport.c | 372 +++ src/drivers/dave2d/src/dave_wedge.c | 362 +++ 142 files changed, 28027 insertions(+) create mode 100644 src/drivers/dave2d/LICENSE create mode 100644 src/drivers/dave2d/Makefile create mode 100644 src/drivers/dave2d/docs/files/code/dave_64bitoperation-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_blit-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_context-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_dlist-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_driver-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_perfcount-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_rbuffer-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_render-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_texture-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_utility-c.html create mode 100644 src/drivers/dave2d/docs/files/code/dave_viewport-c.html create mode 100644 src/drivers/dave2d/docs/files/doc/images/blit_mapping.png create mode 100644 src/drivers/dave2d/docs/files/doc/images/pattern.png create mode 100644 src/drivers/dave2d/docs/files/doc/images/pwe.gif create mode 100644 src/drivers/dave2d/docs/files/doc/images/trifan.gif create mode 100644 src/drivers/dave2d/docs/files/doc/images/trilist.gif create mode 100644 src/drivers/dave2d/docs/files/doc/images/tristrip.gif create mode 100644 src/drivers/dave2d/docs/files/doc/images/wedge.png create mode 100644 src/drivers/dave2d/docs/files/doc/images/wedgeconcave.png create mode 100644 src/drivers/dave2d/docs/files/doc/limitations-txt.html create mode 100644 src/drivers/dave2d/docs/files/doc/overview-txt.html create mode 100644 src/drivers/dave2d/docs/files/inc/dave_driver-h.html create mode 100644 src/drivers/dave2d/docs/files/inc/dave_errorcodes-h.html create mode 100644 src/drivers/dave2d/docs/files/inc/dave_math-h.html create mode 100644 src/drivers/dave2d/docs/index.html create mode 100644 src/drivers/dave2d/docs/index/Functions.html create mode 100644 src/drivers/dave2d/docs/index/Functions2.html create mode 100644 src/drivers/dave2d/docs/index/Functions3.html create mode 100644 src/drivers/dave2d/docs/index/Functions4.html create mode 100644 src/drivers/dave2d/docs/index/General.html create mode 100644 src/drivers/dave2d/docs/index/General2.html create mode 100644 src/drivers/dave2d/docs/index/General3.html create mode 100644 src/drivers/dave2d/docs/index/General4.html create mode 100644 src/drivers/dave2d/docs/index/Types.html create mode 100644 src/drivers/dave2d/docs/javascript/main.js create mode 100644 src/drivers/dave2d/docs/javascript/prettify.js create mode 100644 src/drivers/dave2d/docs/javascript/searchdata.js create mode 100644 src/drivers/dave2d/docs/search/FunctionsA.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsB.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsC.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsD.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsE.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsF.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsG.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsI.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsL.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsM.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsN.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsO.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsP.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsR.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsS.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsU.html create mode 100644 src/drivers/dave2d/docs/search/FunctionsW.html create mode 100644 src/drivers/dave2d/docs/search/GeneralA.html create mode 100644 src/drivers/dave2d/docs/search/GeneralB.html create mode 100644 src/drivers/dave2d/docs/search/GeneralC.html create mode 100644 src/drivers/dave2d/docs/search/GeneralD.html create mode 100644 src/drivers/dave2d/docs/search/GeneralE.html create mode 100644 src/drivers/dave2d/docs/search/GeneralF.html create mode 100644 src/drivers/dave2d/docs/search/GeneralG.html create mode 100644 src/drivers/dave2d/docs/search/GeneralI.html create mode 100644 src/drivers/dave2d/docs/search/GeneralL.html create mode 100644 src/drivers/dave2d/docs/search/GeneralM.html create mode 100644 src/drivers/dave2d/docs/search/GeneralN.html create mode 100644 src/drivers/dave2d/docs/search/GeneralO.html create mode 100644 src/drivers/dave2d/docs/search/GeneralP.html create mode 100644 src/drivers/dave2d/docs/search/GeneralR.html create mode 100644 src/drivers/dave2d/docs/search/GeneralS.html create mode 100644 src/drivers/dave2d/docs/search/GeneralT.html create mode 100644 src/drivers/dave2d/docs/search/GeneralU.html create mode 100644 src/drivers/dave2d/docs/search/GeneralV.html create mode 100644 src/drivers/dave2d/docs/search/GeneralW.html create mode 100644 src/drivers/dave2d/docs/search/NoResults.html create mode 100644 src/drivers/dave2d/docs/search/TypesD.html create mode 100644 src/drivers/dave2d/docs/styles/main.css create mode 100644 src/drivers/dave2d/include/dave_base.h create mode 100644 src/drivers/dave2d/include/dave_box.h create mode 100644 src/drivers/dave2d/include/dave_circle.h create mode 100644 src/drivers/dave2d/include/dave_context.h create mode 100644 src/drivers/dave2d/include/dave_curve.h create mode 100644 src/drivers/dave2d/include/dave_d0_mm_dynamic.h create mode 100644 src/drivers/dave2d/include/dave_d0_mm_fixed_range.h create mode 100644 src/drivers/dave2d/include/dave_d0_mm_fixed_range_fixed_blkcnt.h create mode 100644 src/drivers/dave2d/include/dave_d0lib.h create mode 100644 src/drivers/dave2d/include/dave_dlist.h create mode 100644 src/drivers/dave2d/include/dave_driver.h create mode 100644 src/drivers/dave2d/include/dave_edge.h create mode 100644 src/drivers/dave2d/include/dave_errorcodes.h create mode 100644 src/drivers/dave2d/include/dave_gradient.h create mode 100644 src/drivers/dave2d/include/dave_hardware.h create mode 100644 src/drivers/dave2d/include/dave_intern.h create mode 100644 src/drivers/dave2d/include/dave_line.h create mode 100644 src/drivers/dave2d/include/dave_math.h create mode 100644 src/drivers/dave2d/include/dave_memory.h create mode 100644 src/drivers/dave2d/include/dave_pattern.h create mode 100644 src/drivers/dave2d/include/dave_polyline.h create mode 100644 src/drivers/dave2d/include/dave_quad.h create mode 100644 src/drivers/dave2d/include/dave_rbuffer.h create mode 100644 src/drivers/dave2d/include/dave_registermap.h create mode 100644 src/drivers/dave2d/include/dave_render.h create mode 100644 src/drivers/dave2d/include/dave_texture.h create mode 100644 src/drivers/dave2d/include/dave_triangle.h create mode 100644 src/drivers/dave2d/include/dave_triarray.h create mode 100644 src/drivers/dave2d/include/dave_types.h create mode 100644 src/drivers/dave2d/include/dave_utility.h create mode 100644 src/drivers/dave2d/include/dave_videomodes.h create mode 100644 src/drivers/dave2d/include/dave_viewport.h create mode 100644 src/drivers/dave2d/include/dave_wedge.h create mode 100644 src/drivers/dave2d/src/dave_64bitoperation.c create mode 100644 src/drivers/dave2d/src/dave_blit.c create mode 100644 src/drivers/dave2d/src/dave_box.c create mode 100644 src/drivers/dave2d/src/dave_circle.c create mode 100644 src/drivers/dave2d/src/dave_context.c create mode 100644 src/drivers/dave2d/src/dave_curve.c create mode 100644 src/drivers/dave2d/src/dave_d0_mm_dynamic.c create mode 100644 src/drivers/dave2d/src/dave_d0_mm_fixed_range.c create mode 100644 src/drivers/dave2d/src/dave_d0_mm_fixed_range_fixed_blkcnt.c create mode 100644 src/drivers/dave2d/src/dave_d0lib.c create mode 100644 src/drivers/dave2d/src/dave_dlist.c create mode 100644 src/drivers/dave2d/src/dave_driver.c create mode 100644 src/drivers/dave2d/src/dave_edge.c create mode 100644 src/drivers/dave2d/src/dave_errorcodes.c create mode 100644 src/drivers/dave2d/src/dave_gradient.c create mode 100644 src/drivers/dave2d/src/dave_hardware.c create mode 100644 src/drivers/dave2d/src/dave_line.c create mode 100644 src/drivers/dave2d/src/dave_math.c create mode 100644 src/drivers/dave2d/src/dave_memory.c create mode 100644 src/drivers/dave2d/src/dave_pattern.c create mode 100644 src/drivers/dave2d/src/dave_perfcount.c create mode 100644 src/drivers/dave2d/src/dave_polyline.c create mode 100644 src/drivers/dave2d/src/dave_quad.c create mode 100644 src/drivers/dave2d/src/dave_rbuffer.c create mode 100644 src/drivers/dave2d/src/dave_render.c create mode 100644 src/drivers/dave2d/src/dave_texture.c create mode 100644 src/drivers/dave2d/src/dave_triangle.c create mode 100644 src/drivers/dave2d/src/dave_utility.c create mode 100644 src/drivers/dave2d/src/dave_viewport.c create mode 100644 src/drivers/dave2d/src/dave_wedge.c diff --git a/src/Makefile b/src/Makefile index 0476555d3..e89781350 100755 --- a/src/Makefile +++ b/src/Makefile @@ -62,6 +62,7 @@ MLX90641_DIR=drivers/mlx90641 VL53L5CX_DIR=drivers/vl53l5cx PIXART_DIR=drivers/pixart DISPLAY_DIR=drivers/display +DAVE2D_DIR=drivers/dave2d LIBPDM_DIR=lib/libpdm TENSORFLOW_DIR=lib/tflm CYW4343_FW_DIR=drivers/cyw4343/firmware/ diff --git a/src/drivers/dave2d/LICENSE b/src/drivers/dave2d/LICENSE new file mode 100644 index 000000000..544bf138e --- /dev/null +++ b/src/drivers/dave2d/LICENSE @@ -0,0 +1,44 @@ +## Renesas Open License v1.0 + +Copyright (c) 2020 - 2024, Renesas Electronics Corporation and/or its affiliates + + +By installing, copying, downloading, accessing, or otherwise using this software +or any part thereof and the related documentation from Renesas Electronics Corporation +and/or its affiliates ("Renesas"), You, either individually or on behalf of an entity +employing or engaging You, agree to be bound by this Software License Agreement. If you +do not agree or no longer agree, you are not permitted to use this software or related +documentation. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form, except as embedded into a Renesas + integrated circuit in a product or a software update for + such product, must reproduce the above copyright notice, this list of + conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + +3. Neither the name of Renesas nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Renesas integrated circuit, or other such integrated circuit permitted by Renesas in writing. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY RENESAS "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL RENESAS OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/drivers/dave2d/Makefile b/src/drivers/dave2d/Makefile new file mode 100644 index 000000000..09905b36d --- /dev/null +++ b/src/drivers/dave2d/Makefile @@ -0,0 +1,60 @@ +# This file is part of the OpenMV project. +# +# Copyright (c) 2024 Ibrahim Abdelkader +# Copyright (c) 2024 Kwabena W. Agyeman +# +# This work is licensed under the MIT license, see the file LICENSE for details. +# +# D/AVE 2D Makefile +SRC_C += $(addprefix src/, \ + dave_d0lib.c \ + dave_d0_mm_dynamic.c \ + dave_d0_mm_fixed_range.c \ + dave_d0_mm_fixed_range_fixed_blkcnt.c \ + dave_64bitoperation.c \ + dave_blit.c \ + dave_box.c \ + dave_circle.c \ + dave_context.c \ + dave_curve.c \ + dave_dlist.c \ + dave_driver.c \ + dave_edge.c \ + dave_errorcodes.c \ + dave_gradient.c \ + dave_hardware.c \ + dave_line.c \ + dave_math.c \ + dave_memory.c \ + dave_pattern.c \ + dave_perfcount.c \ + dave_polyline.c \ + dave_quad.c \ + dave_rbuffer.c \ + dave_render.c \ + dave_texture.c \ + dave_triangle.c \ + dave_utility.c \ + dave_viewport.c \ + dave_wedge.c \ +) + +OBJS = $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ_DIRS = $(sort $(dir $(OBJS))) + +all: | $(OBJ_DIRS) $(OBJS) +$(OBJ_DIRS): + $(MKDIR) -p $@ + +$(BUILD)/%.o : %.c + $(ECHO) "CC $<" + $(CC) $(CFLAGS) -c -o $@ $< + +$(BUILD)/%.o : %.s + $(ECHO) "AS $<" + $(AS) $(AFLAGS) $< -o $@ + +$(BUILD)/src/dave_d0lib.o: override CFLAGS += -Wno-unused-value +$(BUILD)/src/dave_d0_mm_fixed_range.o: override CFLAGS += -Wno-unused-value + +-include $(OBJS:%.o=%.d) diff --git a/src/drivers/dave2d/docs/files/code/dave_64bitoperation-c.html b/src/drivers/dave2d/docs/files/code/dave_64bitoperation-c.html new file mode 100644 index 000000000..a703e3478 --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_64bitoperation-c.html @@ -0,0 +1,58 @@ + + +functions for 64bit operations + + + + + + + + + +

functions for 64bit operations

This module contains all the necessary function for 64bit operation in case the chosen compiler does not support long long.  Per default this module is linked.  This module is excluded only when the compiler supports long long

Summary
functions for 64bit operationsThis module contains all the necessary function for 64bit operation in case the chosen compiler does not support long long.
Functions
d2_cast32to64Cast an 32bit integer to 64bit variable
d2_cast64to32Cast an 64bit variable to a32bit variable
d2_add64Addition of 2 64bit value
d2_sub64Substraction of 2 64bit value
d2_mul3232to64multiply two 32-bit variables and return a 64bit value
d2_mul3264multiply two a 32bit varibales with a 64bit one and return a 64bit result
d2_div6432division of 64bit value by a 32bit.
d2_shiftleft64Shift left a variable of type d2_int64
d2_shiftright64Shift right a variable of type d2_int64
+ +

Functions

+ +

d2_cast32to64

void d2_cast32to64(d2_s32 par,
d2_int64 *res)

Cast an 32bit integer to 64bit variable

Parameters

par32bit integer to be casted

Return

d2_int64a 64bit value
+ +

d2_cast64to32

d2_s32 d2_cast64to32(const d2_int64 *par)

Cast an 64bit variable to a32bit variable

Parameters

par64bit variable of type d2_int64

Return

inta 32bit value
+ +

d2_add64

void d2_add64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)

Addition of 2 64bit value

Parameters

a64bit variable of type d2_int64
bpointer to a 64bit variable of type d2_int64
respointer to a 64bit variable of type d2_int64.  The result will be stored in that variable.

Return

none

+ +

d2_sub64

void d2_sub64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)

Substraction of 2 64bit value

Parameters

a64bit variable of type d2_int64
bpointer to a 64bit variable of type d2_int64
respointer to a 64bit variable of type d2_int64.  The result will be stored in that variable.

Return

none

+ +

d2_mul3232to64

multiply two 32-bit variables and return a 64bit value

Parameters

aint
bint
respointer to a variable of type d2_int64 The result will be stored in that variable.

Return

none

+ +

d2_mul3264

void d2_mul3264(d2_s32 a,
const d2_int64 *b,
d2_int64 *res)

multiply two a 32bit varibales with a 64bit one and return a 64bit result

Parameters

aint
bpointer to a 64bit variable of type d2_int64
respointer to a 64bit variable of type d2_int64.  The result will be stored in that variable.

Return

None

+ +

d2_div6432

void d2_div6432(const d2_int64 *dividend,
d2_s32 divisor,
d2_int64 *res)

division of 64bit value by a 32bit.  The return result is a 64bit value.

Parameters

dividendpointer to a 64bit variable of type d2_int64
divisor32bit variable of type int
respointer to a 64bit variable of type d2_int64 The result will be stored in this variable

Return

None

+ +

d2_shiftleft64

void d2_shiftleft64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)

Shift left a variable of type d2_int64

Parameters

varpointer to a 64bit variable of type d2_int64
indexinteger, number of bit to shift
respointer to a 64bit variable of type d2_int64 The result will be stored in this variable

Return

None

+ +

d2_shiftright64

void d2_shiftright64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)

Shift right a variable of type d2_int64

Parameters

varpointer to a 64bit variable of type d2_int64
indexinteger, number of bit to shift
respointer to a 64bit variable of type d2_int64 The result will be stored in this variable

Return

None

+ +
+ + + + + + + + + + +
void d2_cast32to64(d2_s32 par,
d2_int64 *res)
Cast an 32bit integer to 64bit variable
d2_s32 d2_cast64to32(const d2_int64 *par)
Cast an 64bit variable to a32bit variable
void d2_add64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)
Addition of 2 64bit value
void d2_sub64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)
Substraction of 2 64bit value
void d2_mul3264(d2_s32 a,
const d2_int64 *b,
d2_int64 *res)
multiply two a 32bit varibales with a 64bit one and return a 64bit result
void d2_div6432(const d2_int64 *dividend,
d2_s32 divisor,
d2_int64 *res)
division of 64bit value by a 32bit.
void d2_shiftleft64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)
Shift left a variable of type d2_int64
void d2_shiftright64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)
Shift right a variable of type d2_int64
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_blit-c.html b/src/drivers/dave2d/docs/files/code/dave_blit-c.html new file mode 100644 index 000000000..2a5d11841 --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_blit-c.html @@ -0,0 +1,66 @@ + + +Blit Functions + + + + + + + + + +

Blit Functions

BLock Image Transfer operations

Blit’s are special Rendering Functions to copy one rectangle part of the video memory into another part of the video memory.  The operation could be performed using texturemapping and boxrendering as well, but the blit interface avoids setting and restoring all necessary context states.

Texel-to-pixel mapping

Conceptually textures are seen the same way as a raster display: Each texel is defined at the exact center of a grid cell.  The driver maps the left border of the left-most texel to the left border of the left-most destination pixel and the right border of the right-most texel to the right border of the right-most destination pixel.

Example

Find below an example of resizing a source texture with filtering enabled.

  • A source image (3x1) is stretched to a destination rectangle (5x1).
  • A source image (5x1) is downsized to a destination rectangle (3x1).

Please not that the texel-to-pixel mapping implementation has changed for the magnification case since D2 Driver version 3.10.

Summary
Blit FunctionsBLock Image Transfer operations
BLIT Attributes Writes
d2_setblitsrcSpecify the source for blit operation.
BLIT Rendering Functions
d2_blitcopyCopy rectangle part of the source into destination.
+ +

BLIT Attributes Writes

+ +

d2_setblitsrc

d2_s32 d2_setblitsrc(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)

Specify the source for blit operation.

parameters

handledevice pointer (see: d2_opendevice)
ptraddress of the top left texel (coordinate 0,0)
pitchnumber of pixels (not bytes) per scanline
widthwidth of bitmap in pixels (equal or less than pitch)
heightheight of bitmap in pixels
formatpixel encoding type (bitmap format)

bitmap formats

d2_mode_alpha8monochrome 8bit per pixel
d2_mode_alpha4monochrome 4bit per pixel
d2_mode_alpha2monochrome 2bit per pixel
d2_mode_alpha1monochrome 1bit per pixel
d2_mode_rgb565colored 16bit per pixel (alpha is blue)
d2_mode_argb8888colored 32bit per pixel
d2_mode_rgba8888colored 32bit per pixel
d2_mode_rgb888(same as d2_mode_argb8888, in case of RLE textures 24bit pixel are decoded to 32bit)
d2_mode_argb4444colored 16bit per pixel
d2_mode_rgba4444colored 16bit per pixel
d2_mode_rgb444(same as d2_mode_argb4444)
d2_mode_argb1555colored 16bit per pixel
d2_mode_rgba5551colored 16bit per pixel
d2_mode_rgb555(same as d2_mode_argb1555)
d2_mode_ai44colored, palletized 8bit per pixel, (4 bit alpha, 4 bit indexed RGB: see d2_settexclut)
d2_mode_i8colored, palletized 8bit per pixel (palette is used if d2_mode_clut is also set)
d2_mode_i4colored, palletized 4bit per pixel (palette is used if d2_mode_clut is also set)
d2_mode_i2colored, palletized 2bit per pixel (palette is used if d2_mode_clut is also set)
d2_mode_i1colored, palletized 1bit per pixel (palette is used if d2_mode_clut is also set)

additional flags (can be combined with all above formats) :

d2_mode_rleEnables the RLE unit (available if the feature bit D2FB_RLEUNIT is set (see d2_getrevisionhw)).
d2_mode_clutEnables the color look up table (for d2_mode_i8 through d2_mode_i1) (see d2_settexclut).

Modes d2_mode_rgb888, d2_mode_rgb444 and d2_mode_rgb555 can be used as well.  Alpha information has to be ignored by not selecting the flag d2_bf_usealpha when calling d2_blitcopy.

If the CLUT is not enabled with an indexed color format (d2_mode_i8 to d2_mode_i1), the index is written directly to the framebuffer.  The index can be combined with the offset, see d2_settexclut_offset.

In case of d2_mode_alpha4 to d2_mode_alpha1 bits are MSB aligned and replicated to the lower bits of the 8 bit format of the internal A, R, G and B channels.

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

note

width can be max 2048 pixel, height can be max 1024 pixel.

Please notice that a cache flush using ‘d1_cacheblockflush’ might be necessary if memory contents were changed before!  To avoid problems you can use the d1 driver memory management functions ‘d1_copytovidmem’ or ‘d1_copyfromvidmem’, which implicitly do a cache flush.

+ +

BLIT Rendering Functions

+ +

d2_blitcopy

d2_s32 d2_blitcopy(d2_device *handle,
d2_s32 srcwidth,
d2_s32 srcheight,
d2_blitpos srcx,
d2_blitpos srcy,
d2_width dstwidth,
d2_width dstheight,
d2_point dstx,
d2_point dsty,
d2_u32 flags)

Copy rectangle part of the source into destination.

The source is set prior to the blit using d2_setblitsrc and the destination will be part of the framebuffer (see: d2_framebuffer) just as with any normal rendering function.

parameters

handledevice pointer (see: d2_opendevice)
srcwidth, srcheightsize of source rectangle in pixels (integer)
srcx,srcyposition in source bitmap (integer)
dstwidth, dstheightsize of destination rectangle in pixels (fixedpoint)
dstx,dstyposition in destination bitmap (fixedpoint)
flagsany combination of blit flag bits (see below)

blit flag bits

d2_bf_filteruapply linear filter on U axis (x-direction)
d2_bf_filtervapply linear filter in V axis (y-direction)
d2_bf_filterapply bilinear filter (both axis)
d2_bf_wrapuwrap bitmap on U axis (x-direction)
d2_bf_wrapvwrap bitmap on V axis (y-direction)
d2_bf_wrapwrap bitmap on U and V axis (x/y-direction)
d2_bf_mirrorumirror bitmap in U axis (x-direction)
d2_bf_mirrorvmirror bitmap in V axis (y-direction)
d2_bf_colorizebitmap colors are multiplied by color register index 0 (see: d2_setcolor)
d2_bf_colorize2bitmap colors are interpolated between color register index 0 and 1 (see: d2_setcolor)
d2_bf_usealphaalpha value from bitmap is used
d2_bf_invertalphaalpha value from bitmap is inverted before use (requires usealpha)
d2_bf_no_blitctxbackupfor this blit don’t backup context data for better performance; previous texture modes get lost and must be set again
blitsrc.src:+-------------------------------------+
+            |           blitsrc.width             |
+            |<----------blitsrc.pitch------------>|
+            |                                     |
+            |    srcx/y:+-----------------+  ^
+            |           |                 |  |
+            |           |<---srcwidth---->|  |
+            |           |                 |  | srcheight
+            |           |                 |  |
+            |           +-------\\--------+  v
+            |                    \\
+                                  \\
+    Display:  +--------------------\\----------------------+
+              |                     \\                     |
+              |         dstx/y:+-----\\-------------+  ^
+              |                |                    |  |
+              |                |<------dstwidth---->|  |
+              |                |                    |  | dstheight
+              |                |                    |  |
+              |                |                    |  |
+              |                +--------------------+  v

d2_setblitsrc sets parameters for the texture buffer.  d2_blitcopy sets parameters for an area of the texture buffer and an area of the framebuffer where the texture area will be mapped to.  Both areas don’t need to be the same size.

note

Wrapping will work with source bitmap dimensions that are integer powers of two only (2,4,8,16,32,..)!

texture pitch can be >= 2048 if (srcheight-1) * pitch < 2048*1024 and if srcheight is multiple of dstheight

d2_bf_filterv cannot be used if the pitch of the texture is >= 2048

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +
+ + + + + + + + + + +
d2_s32 d2_setblitsrc(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for blit operation.
d2_s32 d2_blitcopy(d2_device *handle,
d2_s32 srcwidth,
d2_s32 srcheight,
d2_blitpos srcx,
d2_blitpos srcy,
d2_width dstwidth,
d2_width dstheight,
d2_point dstx,
d2_point dsty,
d2_u32 flags)
Copy rectangle part of the source into destination.
There is a rendering function for each supported geometric shape.
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
d2_s32 d2_settexclut(d2_device *handle,
d2_color *clut)
Set texture colour palette pointer.
d2_u32 d2_getrevisionhw(const d2_device *handle)
Query hw revisionID.
d2_s32 d2_settexclut_offset(d2_device *handle,
d2_u32 offset)
Set index offset for indexed texture formats.
List of all dave driver errorcodes.
d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)
Specify the rendering target.
d2_s32 d2_setcolor(d2_device *handle,
d2_s32 index,
d2_color color)
Set color registers.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_context-c.html b/src/drivers/dave2d/docs/files/code/dave_context-c.html new file mode 100644 index 000000000..82e6b8652 --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_context-c.html @@ -0,0 +1,136 @@ + + +Context Functions + + + + + + + + + +

Context Functions

Modify material settings

Rendering attributes (like color, pattern, blendmodes) are stored inside a context.  A context is a collection of material attributes and must not be mistaken with a device handle.  A device handle (see: Device management) is the root of all process dependant data and is passed as first parameter to every function.  This construct allows the driver functions to be reentrant in case of a multiple drawing engine units.

A device handle contains information about displaylists, framebuffers,etc...  Everything that the drawing engine will require.  It also includes pointers to contexts.

Each device has at all times pointers to three relevant context’s :

selected contextThis one is changed (written to) by the set commands shown below (see: d2_selectcontext)
solid contextUsed as a source (read from) when rendering interior regions (see: d2_solidcontext)
outline contextUsed as a source (read from) when rendering outlines or shadows (see: d2_outlinecontext)

All three (selected, solid and outline) can point to the same context.  Every driver function that starts with get or set will work on the currently selected context (with the obvious exception of geterror and getversion).

There is always a default context that can not be freed by the application and is used for everything per default.

Summary
Context FunctionsModify material settings
Context Management
d2_newcontextCreate new context (used to store render settings).
d2_freecontextRelease Context.
d2_getcontextGet a pointer to an currently active context.
d2_selectcontextMake a rendering context active (all following property set operations will use it)
d2_solidcontextDefine the solid rendering context.
d2_outlinecontextDefine the outline rendering context.
Context Attribute Writes
d2_setfillmodeSelect fillmode (solid,patter,texture,..)
d2_setcolorSet color registers.
d2_setalphaset constant alpha value
d2_setalphaexset constant alpha value
d2_setalphamodeChoose alpha source.
d2_setalphagradientDefine an alpha gradient.
d2_setblendmodeChoose blendmode for RGB.
d2_setalphablendmodeChoose blendmode for alpha channel.
d2_setalphablendmodeexChoose blendmode for alpha channel.
d2_setantialiasingGlobally disable or enable antialiasing.
d2_setblurSet global blurring factor.
d2_setlinecapSpecify lineend style.
d2_setlinejoinSpecify polyline connection style.
d2_setmiterlimitClipping distance for miter polyline connections.
d2_setpatternSpecify pattern bitmask.
d2_setpatternalphaSpecify pattern transparency.
d2_setpatternparamDefine mapping of pattern to geometry.
d2_setlinepatternSpecify parameters for aligned patterns.
d2_setpatternmodeDefine pattern addressing details.
d2_setpatternsizeDefine pattern size.
d2_setclipgradientDefine an alpha gradient for clipping.
d2_setcircleextendIncrease bbox of circles.
Context Attribute Queries
d2_getfillmodeQuery fillmode from selected context.
d2_getcolorQuery a color from selected context.
d2_getalphaQuery constant alpha from selected context.
d2_getalphaexQuery constant alpha from selected context.
d2_getalphamodeQuery alpha source from selected context.
d2_getblendmodesrcQuery source blend factor from selected context.
d2_getblendmodedstQuery destination blend factor from selected context.
d2_getalphablendmodesrcQuery source blend factor for alpha channel blending from selected context.
d2_getalphablendmodedstQuery destination blend factor for alpha channel blending from selected context.
d2_getalphablendmodeflagsQuery alpha blend flags from selected context.
d2_getantialiasingQuery antialiasing setting from selected context.
d2_getblurQuery blurring factor from selected context.
d2_getlinecapQuery lineend style from selected context.
d2_getlinejoinQuery polyline connection style from selected context.
d2_getpatternQuery pattern bitmask from selected context.
d2_getpatternmodeQuery pattern addressing details.
d2_getpatternsizeQuery pattern bitmask size.
d2_getpatternalphaQuery pattern transparency from selected context.
+ +

Context Management

+ +

d2_newcontext

d2_context * d2_newcontext(d2_device *handle)

Create new context (used to store render settings).

Note that every context is bound to the device it is created for and can not be used in another process or selected into any other device.  Every new context is reset to a default state, it does not reflect the currently selected context.

parameters

handledevice pointer (see: d2_opendevice)

returns

context pointer or NULL in case of an error

+ +

d2_freecontext

d2_s32 d2_freecontext(d2_device *handle,
d2_context *ctx)

Release Context.

Free the memory associated with a context.  If the context is still selected or an active source for rendering it is deselected (by selecting the default context instead) before destruction.

All contexts assigned to a device are freed automatically when the device is closed.

parameters

handledevice pointer (see: d2_opendevice)
ctxcontext pointer

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_getcontext

d2_context * d2_getcontext(
   d2_device *handle,
   d2_s32 mode
) /* PRQA S 3673 */ /* $Misra: #NOT_CONST_IN_DEBUG_BUILD $*/

Get a pointer to an currently active context.

parameters

handledevice pointer (see: d2_opendevice)
modegetcontext mode determines what context should be returned

getcontext modes

d2_context_defaultreturn the default context
d2_context_selectedreturn the currently selected context (see: d2_selectcontext)
d2_context_solidreturn current solid context (see: d2_solidcontext)
d2_context_outlinereturn current outline context (see: d2_outlinecontext)

returns

context pointer or NULL in case of an error

+ +

d2_selectcontext

d2_s32 d2_selectcontext(d2_device *handle,
d2_context *ctx)

Make a rendering context active (all following property set operations will use it)

Selecting a context has no direct effect on how geometry is rendered (reading is done from solid and outline contexts) and is a very fast operation.

parameters

handledevice pointer (see: d2_opendevice)
ctxcontext pointer

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_solidcontext, d2_outlinecontext, d2_getcontext

+ +

d2_solidcontext

d2_s32 d2_solidcontext(d2_device *handle,
d2_context *ctx)

Define the solid rendering context.

parameters

handledevice pointer (see: d2_opendevice)
ctxcontext pointer

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_selectcontext, d2_outlinecontext, d2_getcontext

+ +

d2_outlinecontext

d2_s32 d2_outlinecontext(d2_device *handle,
d2_context *ctx)

Define the outline rendering context.

parameters

handledevice pointer (see: d2_opendevice)
ctxcontext pointer

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_solidcontext, d2_selectcontext, d2_getcontext

+ +

Context Attribute Writes

+ +

d2_setfillmode

d2_s32 d2_setfillmode(d2_device *handle,
d2_u32 mode)

Select fillmode (solid,patter,texture,..)

parameters

handledevice pointer (see: d2_opendevice)
modefillmode

fill modes

d2_fm_colorsingle color (default)
d2_fm_twocolorblending between color1 and color2 instead of color1 and background
d2_fm_patternfill with pattern
d2_fm_texturefill with texture

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setcolor

d2_s32 d2_setcolor(d2_device *handle,
d2_s32 index,
d2_color color)

Set color registers.

Set one of the two color registers, color1 and color2.  Second register (index 1) is used for pattern rendering and during d2_fm_twocolor fillmode only.

parameters

handledevice pointer (see: d2_opendevice)
indexcolor register index (0 or 1)
color24bit rgb color value

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setalpha

d2_s32 d2_setalpha(d2_device *handle,
d2_alpha alpha)

set constant alpha value

parameters

handledevice pointer (see: d2_opendevice)
alphaalpha value (0 is totally transparent, 255 is fully opaque)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setalphaex

d2_s32 d2_setalphaex(d2_device *handle,
d2_s32 index,
d2_alpha alpha)

set constant alpha value

parameters

handledevice pointer (see: d2_opendevice)
indexalpha register index (0 or 1)
alphaalpha value (0 is totally transparent, 255 is fully opaque)

if index is 0 this function does the same as d2_setalpha. if index is 1 alpha is set for color register 2 (see: d2_setalphablendmodeex).

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setalphamode

d2_s32 d2_setalphamode(d2_device *handle,
d2_u32 mode)

Choose alpha source.

Defines how alpha (transparency) is defined.  As a constant value, a gradient or a mixture to both.  Gradients are defined using d2_setalphagradient.

Note that per pixel alpha (e.g. texture alpha channel) information is not disabled by setting the alphamode to opaque.  To disable texture alpha look at d2_settextureoperation.

parameters

handledevice pointer (see: d2_opendevice)
modealpha mode, several values can be or’ed together

alpha modes

d2_am_opaqueno transparency (equal to constant alpha of 0xff)
d2_am_constantconstant transparency (see: d2_setalpha)
d2_am_gradient1alpha gradient1 is active
d2_am_gradient2alpha gradient2 is active

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setalphagradient

d2_s32 d2_setalphagradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_point dx,
d2_point dy)

Define an alpha gradient.

Instead or in addition to a constant alpha (transparency) value the hardware can also apply one or more alpha gradients to the rendered geometry.  Gradients have to be enabled using d2_setalphamode in order to become visible.

parameters

handledevice pointer (see: d2_opendevice)
indexalpha gradient index (0 or 1)
x,ystartpoint of gradient (point of alpha 0) (fixedpoint)
dx,dydirection and length of gradient (distance to point of alpha 255)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setblendmode

d2_s32 d2_setblendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)

Choose blendmode for RGB.

Blendmode defines how the RGB channels of new pixels (source) are combined with already existing data in the framebuffer (destination).  Blend modes for alpha channel are set by d2_setalphablendmode.

The most common blending (and also the default) is a direct linear blend :

d2_bm_alpha , d2_bm_one_minus_alpha

Additive blending is also pretty common :

d2_bm_alpha , d2_bm_one

Note that antialiasing is not possible without blending (because partly covered pixels are represented by transparency).  Therefore antialiasing is impossible with blendmodes that ignore alpha entirely.

If d2_mode_alpha8 is used, alpha is treated as color.

parameters

handledevice pointer (see: d2_opendevice)
srcfactorsource blend factor (see available blend factors)
dstfactordestination blend factor (see available blend factors)

blend factors

d2_bm_zeroconstant 0
d2_bm_oneconstant 1
d2_bm_alphacurrent alpha
d2_bm_one_minus_alphainverted alpha

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setalphablendmode

d2_s32 d2_setalphablendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)

Choose blendmode for alpha channel.

Blendmode defines how new alpha values (source) are combined with already existing data in the framebuffer (destination).

  • The most common blending for alpha channel (and also the default) is write src alpha :
d2_bm_one, d2_bm_zero
  • Another possible mode is alpha blending:
d2_bm_one, d2_bm_one_minus_alpha
  • It is also possible to keep dst alpha :
d2_bm_zero, d2_bm_one

parameters

handledevice pointer (see: d2_opendevice)
srcfactorsource blend factor (see available blend factors)
dstfactordestination blend factor (see available blend factors)

blend factors

d2_bm_zeroconstant 0
d2_bm_oneconstant 1
d2_bm_alphacurrent alpha
d2_bm_one_minus_alphainverted alpha

note

If the framebuffer format is set to d2_mode_alpha8 (d2_framebuffer) then alpha blend mode should be set to write src alpha.  For d2_mode_alpha8 the blend modes set by d2_setblendmode do apply.

note

the blend flags of the selected context is set to d2_blendf_default (see: d2_setalphablendmodeex)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setalphablendmodeex

d2_s32 d2_setalphablendmodeex(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor,
d2_u32 blendflags)

Choose blendmode for alpha channel.

Blendmode defines how new alpha values (source) are combined with already existing data in the framebuffer (destination).

  • The most common blending for alpha channel (and also the default) is write src alpha :
d2_bm_one, d2_bm_zero
  • Another possible mode is alpha blending:
d2_bm_one, d2_bm_one_minus_alpha
  • It is also possible to keep dst alpha :
d2_bm_zero, d2_bm_one

parameters

handledevice pointer (see: d2_opendevice)
srcfactorsource blend factor (see available blend factors)
dstfactordestination blend factor (see available blend factors)
blendflagsblend flags (see available blend flags)

blend factors

d2_bm_zeroconstant 0
d2_bm_oneconstant 1
d2_bm_alphacurrent alpha
d2_bm_one_minus_alphainverted alpha

blend flags

d2_blendf_blenddstuse framebuffer alpha as dst alpha (is d2_blendf_default)
d2_blendf_blendcolor2use color2 alpha as dst alpha as input for the blending formula (see: d2_setalphaex)

note

If the framebuffer format is set to d2_mode_alpha8 (d2_framebuffer) the alpha blend mode should be set to write src alpha: For d2_mode_alpha8 the blend modes set by d2_setblendmode do apply.

On older D/AVE 2D hardware revisions without alpha channel blending (see: d2_getrevisionhw, D2FB_ALPHACHANNELBLENDING) only the following two blend combinations can be used for the alpha channel:

  • (1/0): 1 * src + 0 * dst -> write source alpha
  • (0/1): 0 * src + 1 * dst -> write framebuffer alpha or color2 alpha (depending on blendflags)

These modes also require that the same source blend factor is configured for RGB and A.

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setantialiasing

d2_s32 d2_setantialiasing(d2_device *handle,
d2_s32 enable)

Globally disable or enable antialiasing.

When antialiasing is enabled all geometry is blended with the background according to its coverage value.

parameters

handledevice pointer (see: d2_opendevice)
enableboolean value (set 1 to enable antialiasing)

If antaliasing is disabled blurring will also be disabled (see: d2_setblur).

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setblur

d2_s32 d2_setblur(d2_device *handle,
d2_width blur)

Set global blurring factor.

The blurring factor is a fixed point (4 bit fraction) number of pixels during which the edge opacity changes from 0 (no coverage) to 1 (fully covered).  The intended use is a finetuning of the antialiasing.  The default is a value of 1.0 equals a single pixel wide region around each primitive for antialiasing.

A lower value is not useful (and not supported).  A higher value will produce results similar to an additional lowpass filter (hence the name).  Extending the AA region above 2 or 3 pixels is not recommended and should be used for special effects only.

Note that blurring will not work when antialiasing is disabled (see: d2_setantialiasing).  If blurring factor is > 1 then antialiasing will be enabled (see: d2_setantialiasing).

In order to disable blurring set a value of 1 (fixed point)

parameters

handledevice pointer (see: d2_opendevice)
blurfixed point

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setlinecap

d2_s32 d2_setlinecap(d2_device *handle,
d2_u32 mode)

Specify lineend style.

Linecaps are applied when rendering lines using d2_renderline or d2_renderline2

parameters

handledevice pointer (see: d2_opendevice)
modelinecap mode

linecap modes

d2_lc_buttlines end directly at endpoints
d2_lc_roundlines end with halfcircles
d2_lc_squareline ends are extended by the half linewidth

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setlinejoin

d2_s32 d2_setlinejoin(d2_device *handle,
d2_u32 mode)

Specify polyline connection style.

Linejoins are applied when rendering polylines using d2_renderpolyline

parameters

handledevice pointer (see: d2_opendevice)
modelinejoin mode

linejoin modes

d2_lj_noneno connection is applied
d2_lj_miterlines meet in a sharp angle (see also d2_setmiterlimit)
d2_lj_roundline are connected by circle segments
d2_lj_bevellines meet in a flat angle

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setmiterlimit

d2_s32 d2_setmiterlimit(d2_device *handle,
d2_width miter)

Clipping distance for miter polyline connections.

When using sharp linejoin’s (d2_lj_miter) with d2_renderpolyline the sharp edge has to be clipped at some point.  Otherwise it would extend to infinity when the two segments meet at 180�.

parameters

handledevice pointer (see: d2_opendevice)
mitermaximum pixel distance the join can extend beyond bevel edge

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setpattern

d2_s32 d2_setpattern(d2_device *handle,
d2_pattern pattern)

Specify pattern bitmask.

When patterns are used to fill a primitive an index into the bitmask is generated for each pixel (see: d2_setpatternparam for mapping details).  The pattern wraps around after N bits (N can be set using d2_setpatternsize).

Depending on the bit color1 or color2 and patternalpha1 or patternalpha2 are used.  Fractional indices are interpolated between those two values.

parameters

handledevice pointer (see: d2_opendevice)
patternN bit pattern mask

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

example

The following figure shows a rendered line filled with an 8 bit pattern.  Color1 is blue and color2 is green, the bitstring is 0101 1001.  For the upper line filtering is off, the lower line is rendered with filtering enabled (flag: d2_pm_filter).

+ +

d2_setpatternalpha

d2_s32 d2_setpatternalpha(d2_device *handle,
d2_s32 index,
d2_alpha alpha)

Specify pattern transparency.

Pattern alpha is mixed with global alpha (gradient or constant).  Pattern alpha index 0 is used where 0bits occur in the pattern bitmask.

parameters

handledevice pointer (see: d2_opendevice)
indexregister index (0 or 1 as patterns are always twocolor)
alphaalphavalue (0 is totally transparent, 255 is fully opaque)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_setcolor, d2_setpattern

+ +

d2_setpatternparam

d2_s32 d2_setpatternparam(d2_device *handle,
d2_point x,
d2_point y,
d2_width dx,
d2_width dy)

Define mapping of pattern to geometry.

Pattern mapping is defined by specifying a line segment (startpoint and vector to endpoint) along which the pattern is mapped.  The startpoint maps to bit0 of the pattern bitmask (see: <set_pattern>).  With the bitmask extending along the direction vector.

Note that the pattern is repeated infinitely along the defined line.

Free pattern directions apply to line based geometry only when pattern mode (see: d2_setpatternmode) is not set to auto align.

parameters

handledevice pointer (see: d2_opendevice)
x, ypattern startpoint (fixedpoint)
dx, dypattern direction and size (fixedpoint)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_setpatternsize, d2_setpattern, d2_setpatternmode

+ +

d2_setlinepattern

d2_s32 d2_setlinepattern(d2_device *handle,
d2_width scale,
d2_s32 offset)

Specify parameters for aligned patterns.

When rendering line based geometry it is very often required to align the pattern perpendicular to the line direction.  For single elements it can be done using d2_setpatternparam but this is not efficient and sometimes (e.g. with polylines) not even possible.

When enabled by setting the patternmode to contain d2_pm_autoalign this function can be used to describe the pattern relative to any line geometry by scale and offset.

The offset can be incremented automatically after rendering an element if d2_pm_advance is set using d2_setpatternmode.  Calling d2_setlinepattern resets the internally managed offset to the specified value.

parameters

handledevice pointer (see: d2_opendevice)
scalenumber of screenpixels one pattern bit is mapped onto
offsetpattern offset in pixels (fixedpoint format equal to d2_point)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_setpatternmode, d2_setpatternparam

+ +

d2_setpatternmode

d2_s32 d2_setpatternmode(d2_device *handle,
d2_u32 mode)

Define pattern addressing details.

Filtering (interpolation) of pattern data can be disabled by passing 0 as patternmode.

Patterns can be aligned to run perpendicular to rendered lines automatically when d2_pm_autoalign mode is enabled (works only when rendering line based geometry).  In this case calling d2_setpatternparam is unnecessary but additional data has to be passed using <d2_linepattern>.

parameters

handledevice pointer (see: d2_opendevice)
modeany combination of pattern mode bits (see below)

pattern mode bits

d2_pm_filteruse linear interpolation between colors (default)
d2_pm_autoalignmap pattern to line direction (see: d2_setlinepattern)
d2_pm_advanceincrease offset automatically (see: d2_setlinepattern)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_setpatternsize

d2_s32 d2_setpatternsize(d2_device *handle,
d2_s32 size)

Define pattern size.

Patterns are defined as a bitvector.  This function can be used to define the number of valid bits.  The size may not exceed the maximum size supported by the hardware (currently 8).  The default size is set to 4 in every new context for compatibility reasons.

Size changes affect only the following calls to d2_setpatternparam and d2_setpattern

Note that for correct wraparound the size must divide the hardware maximum without remainder.

parameters

handledevice pointer (see: d2_opendevice)
sizenumber of valid bits used for pattern mask

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

please note

when using small pattern size (<8) all leading unused bits in the pattern mask (see: d2_setpattern) must be zero!

+ +

d2_setclipgradient

d2_s32 d2_setclipgradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_s32 nx,
d2_s32 ny,
d2_u32 flags)

Define an alpha gradient for clipping.

Instead or in addition to a constant alpha (transparency) value the hardware can also apply one or more alpha gradients to the rendered geometry.

d2_setalphagradient offers an interface suitable to specify smooth alpha gradients, but does not provide enough accuracy for steep gradients, which effectively clip objects along a straight edge, e.g. let the alpha value drop from 255 to 0 within the distance of a single pixel.  For this reason d2_setclipgradient offers the necessary accuracy by using 16.16 fixed point instead of d2_point (12.4 fixed point) for the definition of the gradient.  Also the interpretation of nx,ny is different compared to dx,dy of d2_setalphagradient as follows: nx,ny specify a normal vector of the clipping edge, pointing towards the non-clipped side.  When this vector is normalized to a length of 1.0 (i.e.  0x00010000), the gradient alpha value changes from 0 to 255 within the distance of a single pixel.  When it is longer, the gradient is even steeper respectively smoother, when it is shorter.  The gradient alpha value is always clamped to 0 respectively 255 when it leaves this range.

note

Additionally index 2 or 3 can also be used in some cases.  These indices are shared with the alpha gradients (and will overwrite these settings) and have to be enabled using d2_setalphamode in order to become visible.  Please also note that the total number of available gradients (alpha or clip) is restricted by the D/AVE 2D hardware and varies on the primitive types and render modes!

parameters

handledevice pointer (see: d2_opendevice)
indexalpha gradient index (0 or 1, additionally 2 or 3)
x,ystartpoint of gradient (point of alpha 0) (fixedpoint)
nx,nynormal vector of the clipping edge, pointing towards the non-clipped side (16.16 fixedpoint)
flagsreserved

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_setalphagradient

+ +

d2_setcircleextend

d2_s32 d2_setcircleextend(d2_device *handle,
d2_width offset)

Increase bbox of circles.

Due to limited precision for circle parameters large circles with enabled blurring can become inaccurate.  To avoid clipping at the bbox of the circle the bbox can be extended by offset.

parameters

handledevice pointer (see: d2_opendevice)
offsetnumber by which bbox of circles will be extended (fixedpoint)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

Context Attribute Queries

+ +

d2_getfillmode

d2_u8 d2_getfillmode(d2_device *handle)

Query fillmode from selected context.

see: d2_setfillmode for a list of fill modes

parameters

handledevice pointer (see: d2_opendevice)

returns

Select fillmode (d2_fm_color,d2_fm_pattern,..). undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setfillmode

+ +

d2_getcolor

d2_color d2_getcolor(d2_device *handle,
d2_s32 index)

Query a color from selected context.

parameters

handledevice pointer (see: d2_opendevice)
indexcolor register index (0 or 1)

returns

content of specified color register. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setcolor

+ +

d2_getalpha

d2_alpha d2_getalpha(d2_device *handle)

Query constant alpha from selected context.

parameters

handledevice pointer (see: d2_opendevice)

returns

content of constant alpha register. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setalpha

+ +

d2_getalphaex

d2_alpha d2_getalphaex(d2_device *handle,
d2_s32 index)

Query constant alpha from selected context.

parameters

handledevice pointer (see: d2_opendevice)
indexalpha register index (0 or 1)

returns

content of constant alpha register. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setalphaex

+ +

d2_getalphamode

d2_u8 d2_getalphamode(d2_device *handle)

Query alpha source from selected context.

see: d2_setalphamode for a list of alpha mode bits

parameters

handledevice pointer (see: d2_opendevice)

returns

alpha source bitmask. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setalphamode

+ +

d2_getblendmodesrc

d2_u32 d2_getblendmodesrc(d2_device *handle)

Query source blend factor from selected context.

see: d2_setblendmode for a list of blendmodes

parameters

handledevice pointer (see: d2_opendevice)

returns

source blend factor. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_getblendmodedst, d2_setblendmode

+ +

d2_getblendmodedst

d2_u32 d2_getblendmodedst(d2_device *handle)

Query destination blend factor from selected context.

see: d2_setblendmode for a list of blendmodes

parameters

handledevice pointer (see: d2_opendevice)

returns

destination blend factor. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_getblendmodesrc, d2_setblendmode

+ +

d2_getalphablendmodesrc

d2_u32 d2_getalphablendmodesrc(d2_device *handle)

Query source blend factor for alpha channel blending from selected context.

see: d2_setalphablendmode for a list of blendmodes

parameters

handledevice pointer (see: d2_opendevice)

returns

alpha source blend factor. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_getalphablendmodedst, d2_setalphablendmode

+ +

d2_getalphablendmodedst

d2_u32 d2_getalphablendmodedst(d2_device *handle)

Query destination blend factor for alpha channel blending from selected context.

see: d2_setalphablendmode for a list of blendmodes

parameters

handledevice pointer (see: d2_opendevice)

returns

alpha destination blend factor. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_getblendmodesrc, d2_setalphablendmode

+ +

d2_getalphablendmodeflags

d2_u8 d2_getalphablendmodeflags(d2_device *handle)

Query alpha blend flags from selected context.

see: d2_setalphablendmodeex for a list of blend flags

parameters

handledevice pointer (see: d2_opendevice)

returns

alpha blend flags.  Undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setalphablendmodeex

+ +

d2_getantialiasing

d2_s32 d2_getantialiasing(d2_device *handle)

Query antialiasing setting from selected context.

parameters

handledevice pointer (see: d2_opendevice)

returns

Boolean (0 or 1) antialiasing setting. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setantialiasing

+ +

d2_getblur

d2_width d2_getblur(d2_device *handle)

Query blurring factor from selected context.

parameters

handledevice pointer (see: d2_opendevice)

returns

global blurring factor (fixedpoint). undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setblur

+ +

d2_getlinecap

d2_u8 d2_getlinecap(d2_device *handle)

Query lineend style from selected context.

see: d2_setlinecap for a list of all line cap modes

parameters

handledevice pointer (see: d2_opendevice)

returns

Linecap mode. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setlinecap

+ +

d2_getlinejoin

d2_u8 d2_getlinejoin(d2_device *handle)

Query polyline connection style from selected context.

see: d2_setlinejoin for a list of all line join modes

parameters

handledevice pointer (see: d2_opendevice)

returns

Linejoin mode. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setlinejoin

+ +

d2_getpattern

d2_pattern d2_getpattern(d2_device *handle)

Query pattern bitmask from selected context.

parameters

handledevice pointer (see: d2_opendevice)

returns

Pattern bitmask. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setpattern

+ +

d2_getpatternmode

d2_u32 d2_getpatternmode(d2_device *handle)

Query pattern addressing details.

parameters

handledevice pointer (see: d2_opendevice)

returns

Pattern address mode. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setpatternmode

+ +

d2_getpatternsize

d2_s32 d2_getpatternsize(d2_device *handle)

Query pattern bitmask size.

parameters

handledevice pointer (see: d2_opendevice)

returns

Pattern bitmask size. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setpatternsize

+ +

d2_getpatternalpha

d2_alpha d2_getpatternalpha(d2_device *handle,
d2_s32 index)

Query pattern transparency from selected context.

parameters

handledevice pointer (see: d2_opendevice)
indexregister index (0 or 1 as patterns are always twocolor)

returns

Pattern alpha. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_setpatternalpha

+ +
+ + + + + + + + + + +
d2_context * d2_newcontext(d2_device *handle)
Create new context (used to store render settings).
d2_s32 d2_freecontext(d2_device *handle,
d2_context *ctx)
Release Context.
d2_context * d2_getcontext(
   d2_device *handle,
   d2_s32 mode
) /* PRQA S 3673 */ /* $Misra: #NOT_CONST_IN_DEBUG_BUILD $*/
Get a pointer to an currently active context.
d2_s32 d2_selectcontext(d2_device *handle,
d2_context *ctx)
Make a rendering context active (all following property set operations will use it)
d2_s32 d2_solidcontext(d2_device *handle,
d2_context *ctx)
Define the solid rendering context.
d2_s32 d2_outlinecontext(d2_device *handle,
d2_context *ctx)
Define the outline rendering context.
d2_s32 d2_setfillmode(d2_device *handle,
d2_u32 mode)
Select fillmode (solid,patter,texture,..)
d2_s32 d2_setcolor(d2_device *handle,
d2_s32 index,
d2_color color)
Set color registers.
d2_s32 d2_setalpha(d2_device *handle,
d2_alpha alpha)
set constant alpha value
d2_s32 d2_setalphaex(d2_device *handle,
d2_s32 index,
d2_alpha alpha)
set constant alpha value
d2_s32 d2_setalphamode(d2_device *handle,
d2_u32 mode)
Choose alpha source.
d2_s32 d2_setalphagradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_point dx,
d2_point dy)
Define an alpha gradient.
d2_s32 d2_setblendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)
Choose blendmode for RGB.
d2_s32 d2_setalphablendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)
Choose blendmode for alpha channel.
d2_s32 d2_setalphablendmodeex(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor,
d2_u32 blendflags)
Choose blendmode for alpha channel.
d2_s32 d2_setantialiasing(d2_device *handle,
d2_s32 enable)
Globally disable or enable antialiasing.
d2_s32 d2_setblur(d2_device *handle,
d2_width blur)
Set global blurring factor.
d2_s32 d2_setlinecap(d2_device *handle,
d2_u32 mode)
Specify lineend style.
d2_s32 d2_setlinejoin(d2_device *handle,
d2_u32 mode)
Specify polyline connection style.
d2_s32 d2_setmiterlimit(d2_device *handle,
d2_width miter)
Clipping distance for miter polyline connections.
d2_s32 d2_setpattern(d2_device *handle,
d2_pattern pattern)
Specify pattern bitmask.
d2_s32 d2_setpatternalpha(d2_device *handle,
d2_s32 index,
d2_alpha alpha)
Specify pattern transparency.
d2_s32 d2_setpatternparam(d2_device *handle,
d2_point x,
d2_point y,
d2_width dx,
d2_width dy)
Define mapping of pattern to geometry.
d2_s32 d2_setlinepattern(d2_device *handle,
d2_width scale,
d2_s32 offset)
Specify parameters for aligned patterns.
d2_s32 d2_setpatternmode(d2_device *handle,
d2_u32 mode)
Define pattern addressing details.
d2_s32 d2_setpatternsize(d2_device *handle,
d2_s32 size)
Define pattern size.
d2_s32 d2_setclipgradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_s32 nx,
d2_s32 ny,
d2_u32 flags)
Define an alpha gradient for clipping.
d2_s32 d2_setcircleextend(d2_device *handle,
d2_width offset)
Increase bbox of circles.
d2_u8 d2_getfillmode(d2_device *handle)
Query fillmode from selected context.
d2_color d2_getcolor(d2_device *handle,
d2_s32 index)
Query a color from selected context.
d2_alpha d2_getalpha(d2_device *handle)
Query constant alpha from selected context.
d2_alpha d2_getalphaex(d2_device *handle,
d2_s32 index)
Query constant alpha from selected context.
d2_u8 d2_getalphamode(d2_device *handle)
Query alpha source from selected context.
d2_u32 d2_getblendmodesrc(d2_device *handle)
Query source blend factor from selected context.
d2_u32 d2_getblendmodedst(d2_device *handle)
Query destination blend factor from selected context.
d2_u32 d2_getalphablendmodesrc(d2_device *handle)
Query source blend factor for alpha channel blending from selected context.
d2_u32 d2_getalphablendmodedst(d2_device *handle)
Query destination blend factor for alpha channel blending from selected context.
d2_u8 d2_getalphablendmodeflags(d2_device *handle)
Query alpha blend flags from selected context.
d2_s32 d2_getantialiasing(d2_device *handle)
Query antialiasing setting from selected context.
d2_width d2_getblur(d2_device *handle)
Query blurring factor from selected context.
d2_u8 d2_getlinecap(d2_device *handle)
Query lineend style from selected context.
d2_u8 d2_getlinejoin(d2_device *handle)
Query polyline connection style from selected context.
d2_pattern d2_getpattern(d2_device *handle)
Query pattern bitmask from selected context.
d2_u32 d2_getpatternmode(d2_device *handle)
Query pattern addressing details.
d2_s32 d2_getpatternsize(d2_device *handle)
Query pattern bitmask size.
d2_alpha d2_getpatternalpha(d2_device *handle,
d2_s32 index)
Query pattern transparency from selected context.
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
List of all dave driver errorcodes.
d2_s32 d2_settextureoperation(d2_device *handle,
d2_u8 amode,
d2_u8 rmode,
d2_u8 gmode,
d2_u8 bmode)
Choose texture operation for each channel.
d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)
Specify the rendering target.
d2_u32 d2_getrevisionhw(const d2_device *handle)
Query hw revisionID.
d2_s32 d2_renderline(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w,
d2_u32 flags)
Render a wide line.
d2_s32 d2_renderline2(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w1,
d2_width w2,
d2_u32 flags)
Render a wide line with 2 different widths.
d2_s32 d2_renderpolyline(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_width w,
d2_u32 flags)
Render a polyline
short (fixedpoint)
d2_s32 d2_geterror(const d2_device *handle)
Query device error information.
const d2_char * d2_geterrorstring(const d2_device *handle)
Query detailed device error information.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_dlist-c.html b/src/drivers/dave2d/docs/files/code/dave_dlist-c.html new file mode 100644 index 000000000..b98038942 --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_dlist-c.html @@ -0,0 +1,44 @@ + + +Dlist Functions + + + + + + + + + +

Dlist Functions

Summary
Dlist Functions
Functions
d2_executedlistExecute an already prepared display list.
d2_adddlistAdd an already prepared display list to the current render buffer.
+ +

Functions

+ +

d2_executedlist

d2_s32 d2_executedlist(d2_device *handle,
const void *address,
d2_u32 flags)

Execute an already prepared display list.  A display list (Dlist) can be created e.g. by d2_dumprenderbuffer.

Basically the address will be sent to D/AVE and will be executed immediately.  So the dlist address must be accessible by the GPU and it is in the application’s responsibility to prepare the Dlist correctly.

d2_executedlist must not be called while D/AVE is busy rendering (see: Render Buffers).

Note

This has no influence on the render buffer mechanism.  The driver will manage cooperation of render buffers and Dlists.

Note

In case d2_opendevice was called with d2_df_no_dlist address must be accessible by the CPU.

parameters

handledevice pointer (see: d2_opendevice)
addressAddress of the Dlist (must be accessible by the GPU)
flagsreserved (set to 0)

returns

errorcode (D2_OK if successful) see Errorcodes for details

+ +

d2_adddlist

d2_s32 d2_adddlist(d2_device *handle,
void *address,
d2_s32 size,
d2_u32 flags)

Add an already prepared display list to the current render buffer.  A display list (Dlist) can be created e.g. by d2_dumprenderbuffer.

Depending on the flags, the Dlist will be added to the current render buffer by copying its content or by adding ‘call’ operations to the current render buffer.

If a ‘postprocess’ rendermode is active the layers are merged before the Dlist is added (see: d2_selectrendermode).

Note

If d2_al_no_copy is selected, the GPU must be able to select the specified address, in case if d2_al_copy the CPU must be able to access the Dlist.

Note

For the mode d2_al_no_copy the low level driver must support the handling of lists of Dlist start addresses (see: d2_level1interface and low level device <D1 Display list handling at ../../../driver_l1/files/doc/d1_dlistindirect-txt.html>).

If this handling is not supported then no Dlists can be added in this mode.

parameters

handledevice pointer (see: d2_opendevice)
addressAddress of the Dlist (in case of d2_al_no_copy must be accessible by the GPU in case of d2_al_no_copy must be accessible by CPU)
sizesize of Dlist
flagsd2_al_copy, d2_al_no_copy

returns

errorcode (D2_OK if successful) see Errorcodes for details

flags

d2_al_defaultdefault behavior d2_al_copy.
d2_al_copycontent will be copied.
d2_al_no_copycall to the Dlist will be added.

see also

d2_dumprenderbuffer, d2_getrenderbuffersize, d2_relocateframe

+ +
+ + + + + + + + + + +
d2_s32 d2_executedlist(d2_device *handle,
const void *address,
d2_u32 flags)
Execute an already prepared display list.
d2_s32 d2_adddlist(d2_device *handle,
void *address,
d2_s32 size,
d2_u32 flags)
Add an already prepared display list to the current render buffer.
d2_s32 d2_dumprenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
void **rdata,
d2_s32 *rsize)
Copy the content of a renderbuffer into user memory.
Renderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
List of all dave driver errorcodes.
d2_s32 d2_selectrendermode(d2_device *handle,
d2_u32 mode)
Select a rendering mode.
d1_device * d2_level1interface(const d2_device *handle)
Get the lowlevel device handle currently used by the d2_device.
d2_u32 d2_getrenderbuffersize(d2_device *handle,
d2_renderbuffer *rb)
Query the number of allocated display list entries.
extern d2_s32 d2_relocateframe(d2_device *handle,
const void *ptr)
Change framebuffer for render commands already issued.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_driver-c.html b/src/drivers/dave2d/docs/files/code/dave_driver-c.html new file mode 100644 index 000000000..007f12d8f --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_driver-c.html @@ -0,0 +1,90 @@ + + +Basic Functions + + + + + + + + + +

Basic Functions

Driver device management and hardware initialization / shutdown.

Summary
Basic FunctionsDriver device management and hardware initialization / shutdown.
Static functions
Device management
d2_getversionstringQuery versionID string (device independent)
d2_getversionQuery versionID (device independent)
d2_opendeviceCreate a new device handle.
d2_closedeviceDestroy a device handle.
d2_geterrorQuery device error information.
d2_geterrorstringQuery detailed device error information.
d2_inithwInitialize hardware for working with specified device.
d2_deinithwUnlink hardware currently bound by specified device.
d2_level1interfaceGet the lowlevel device handle currently used by the d2_device.
d2_getrevisionhwQuery hw revisionID.
d2_getrevisionstringhwQuery hw revisionID string.
d2_lowlocalmemmodeEnable and configure the ‘low localmem’ mode.
Rendering Mode
d2_selectrendermodeSelect a rendering mode.
d2_getrendermodeGet the rendering mode.
d2_layermergeJoin outline and solid parts of currently selected renderbuffer.
d2_outlinewidthDefine the width of geometry outlines.
d2_shadowoffsetDefine the offset of geometry shadows.
Utility Functions
d2_flushframeWait for current rendering to end.
d2_setdlistblocksizeSet blocksize for default displaylists.
d2_getdlistblocksizeGet blocksize of default displaylist.
d2_getdlistblockcountGet number of blocks of default displaylist (writelist).
d2_commandspendingCheck if there are pending commands in the current displaylist.
+ +

Static functions

+ +

Device management

+ +

d2_getversionstring

const d2_char * d2_getversionstring(void)

Query versionID string (device independent)

returns

human readable driver version as a string.

see also

d2_getversion

+ +

d2_getversion

d2_s32 d2_getversion(void)

Query versionID (device independent)

returns

driver revision as a single 32bit integer

bits 31..24branch number
bits 23..16major version number
bits 15..0minor version number

see also

d2_getversionstring

+ +

d2_opendevice

d2_device * d2_opendevice(d2_u32 flags)

Create a new device handle.

A device is the basic software object.  It contains references to objects that the drawing engine requires, (e.g.: displaylists).  All 2D drawing functions require such a device pointer as first parameter.

A device on its own is useless, unless bound to a physical hardware (i.e.: Drawing Engine).  The binding is done by the function d2_inithw.  A hardware instance can only be mapped to one device object.  It is not possible to share a single device pointer between different processes.

Creating a device will never fail (sufficient memory assumed) but binding it to a hardware (see: d2_inithw) can fail.

parameters

flagsa bitfield containing flags

flags

d2_df_no_dlistdon’t use a display list (slower single command mode)
d2_df_no_irqdon’t use an interrupt (slower polling used instead)
d2_df_no_fbcachedisable framebuffer cache (attention: see note below)
d2_df_no_texcachedisable texture cache (attention: see note below)
d2_df_no_dwcleardisable double word clearing in d2_clear
d2_df_no_registercachingdon’t use register caching
d2_df_no_blitctxbackupdon’t backup context data at blit for better performance; previous texture modes get lost and must be set again

note

Flags ‘d2_df_no_fbcache’ and ‘d2_df_no_texcache’ should only be used for debugging purposes.  Especially when multithreading is used, these flags must not be set different for devices which are bound to the same hardware instance through d2_inithw.

returns

device pointer or NULL if not enough memory was available

+ +

d2_closedevice

d2_s32 d2_closedevice(d2_device *handle)

Destroy a device handle.

All contexts associated with the device are destroyed as well.

parameters

handledevice pointer (see: d2_opendevice)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_geterror

d2_s32 d2_geterror(const d2_device *handle)

Query device error information.

See list of all Errorcodes for more details.

parameters

handledevice pointer (see: d2_opendevice)

returns

integer error code (0 is no error)

+ +

d2_geterrorstring

const d2_char * d2_geterrorstring(const d2_device *handle)

Query detailed device error information.

See list of all Errorcodes for more details.

parameters

handledevice pointer (see: d2_opendevice)

returns

string with human readable error description, or 0 if an error occurs

+ +

d2_inithw

d2_s32 d2_inithw(d2_device *handle,
d2_u32 flags)

Initialize hardware for working with specified device.  After creation a device is ‘bound’ to a hardware instance by calling inithw for this device.  A single device cannot work with multiple hardware units.

parameters

handledevice pointer (see: d2_opendevice)
flagshardware instance id (use 0 for default)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_deinithw

d2_s32 d2_deinithw(d2_device *handle)

Unlink hardware currently bound by specified device.  Hardware must be deinitialized before it can be reinitalized for another device.

parameters

handledevice pointer (see: d2_opendevice)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_level1interface

d1_device * d2_level1interface(const d2_device *handle)

Get the lowlevel device handle currently used by the d2_device.  This is necessary e.g. for allocating framebuffers using the lowlevel (d1_) interface.

parameters

handledevice pointer (see: d2_opendevice)

returns

handle for lowlevel device, or NULL if an error occurs

+ +

d2_getrevisionhw

d2_u32 d2_getrevisionhw(const d2_device *handle)

Query hw revisionID.  This information is available after calling d2_inithw.

parameters

handledevice pointer (see: d2_opendevice)

returns

HW Revision ID

HW Revision ID structure

Bit[7..0]revision number
Bit[11..8]branch number
Bit[15..12]D/AVE Type
Bit[20..16]Features

D/AVE Type

0D/AVE2DT-S
1D/AVE2DT-L

Feature bits

Bit[16]D2FB_SWDAVE (Software D/AVE)
Bit[17]D2FB_DLR (DisplayListReader available)
Bit[18]D2FB_FBCACHE (Framebuffer Cache available)
Bit[19]D2FB_TXCACHE (Texture Cache available)
Bit[20]D2FB_PERFCOUNT (Two performance counters available)
Bit[21]D2FB_TEXCLUT (Color Lookup Table for ai44 format)
Bit[22]D2FB_FBPREFETCH (frame buffer cache prefetch available)
Bit[23]D2FB_RLEUNIT (RLE unit available)
Bit[24]D2FB_TEXCLUT256 (256 entry CLUT available)
Bit[25]D2FB_COLORKEY (color keying available)
Bit[26]D2FB_HILIMITERPRECISION (limiter high precision mode available)
Bit[27]D2FB_ALPHACHANNELBLENDING (alpha channel blending available)

see also

d2_getrevisionstringhw

+ +

d2_getrevisionstringhw

const d2_char * d2_getrevisionstringhw(const d2_device *handle)

Query hw revisionID string.  This information is available after calling d2_inithw.

parameters

handledevice pointer (see: d2_opendevice)

returns

human readable hw revision string, or 0 if an error occurs (e.g.  “D/AVE 2DT-S, Revision 1.05, Features: DLR FBCACHE”).

see also

d2_getrevisionhw

+ +

d2_lowlocalmemmode

d2_s32 d2_lowlocalmemmode(d2_device *handle,
d2_u32 dlistblockfactor,
d2_u32 dlistblocks)

Enable and configure the ‘low localmem’ mode.

On systems with low local CPU memory, the display lists can not be completely assembled in the local memory.  A special mode is used in this case, which assembles small display list blocks in the local memory and copies them to the video memory, where they are concatenated to larger blocks.  In order to use this mode it is necessary to call d2_lowlocalmemmode directly after d2_opendevice and before d2_inithw.

Querying the number of effectively used display list blocks can be done using d2_getdlistblockcount, which gives the number of display list blocks used so far (in units of the local display list block size).  The application developer must take care that the maximum display list size configured using d2_lowlocalmemmode is sufficient.

parameters

handledevice pointer (see: d2_opendevice)
dlistblockfactorsize of a dlist block in vidmem is this factor * local size (configurable using d2_setdlistblocksize)
dlistblocksmaximum number of dlist blocks in vidmem

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_setdlistblocksize

+ +

Rendering Mode

+ +

d2_selectrendermode

d2_s32 d2_selectrendermode(d2_device *handle,
d2_u32 mode)

Select a rendering mode.  Dave can automatically generate and render geometry outlines and shadows.  A different rendering context is used for interior (solid context) and addons (outline context) so that both parts can have entirely different materials.

Note that primitives which are issued while rendermode ‘postprocess’ is active are buffered and put into the commandlist after all normal commands.  Combined rendermodes like ‘solid_outlined’ and ‘solid_shadow’ internally use postprocessing to sort solid and outline parts.

parameters

handledevice pointer (see: d2_opendevice)
moderendering mode

available rendering modes

d2_rm_solidDirect rendering of primitives (default mode)
d2_rm_outlineOnly outlines are rendered
d2_rm_solid_outlinedInterior and outlines are rendered
d2_rm_shadowOnly shadows are rendered
d2_rm_solid_shadowInterior and shadows are rendered
d2_rm_postprocessDirect rendering of primitives as a postprocess

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_outlinewidth, d2_shadowoffset

+ +

d2_getrendermode

d2_u32 d2_getrendermode(const d2_device *handle)

Get the rendering mode.  This function can be used to get the rendering mode used for a specified d2_device.

parameters

handledevice pointer (see: d2_opendevice)

available rendering modes

d2_rm_solidDirect rendering of primitives (default mode)
d2_rm_outlineOnly outlines are rendered
d2_rm_solid_outlinedInterior and outlines are rendered
d2_rm_shadowOnly shadows are rendered
d2_rm_solid_shadowInterior and shadows are rendered
d2_rm_postprocessDirect rendering of primitives as a postprocess

returns

integer specifying the rendering mode, or 0 if an error occurs

+ +

d2_layermerge

d2_s32 d2_layermerge(d2_device *handle)

Join outline and solid parts of currently selected renderbuffer.  When using rendermode d2_rm_postprocess (see: d2_selectrendermode) the postprocess buffer can be flushed using a call to d2_layermerge.

parameters

handledevice pointer (see: d2_opendevice)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_selectrendermode

+ +

d2_outlinewidth

d2_s32 d2_outlinewidth(d2_device *handle,
d2_width width)

Define the width of geometry outlines.  Used only when using outline or solid_outlined rendering modes.

parameters

handledevice pointer (see: d2_opendevice)
widthoutline width in pixels (fixedpoint)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_selectrendermode, d2_shadowoffset

+ +

d2_shadowoffset

d2_s32 d2_shadowoffset(d2_device *handle,
d2_point x,
d2_point y)

Define the offset of geometry shadows.  Used only when using shadow or solid_shadow rendering modes.

parameters

handledevice pointer (see: d2_opendevice)
xx axis offset in pixels (fixedpoint)
yy axis offset in pixels (fixedpoint)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_selectrendermode, d2_outlinewidth

+ +

Utility Functions

+ +

d2_flushframe

d2_s32 d2_flushframe(d2_device *handle)

Wait for current rendering to end.

Function will not return until the hardware has finished executing all currently active rendering operations.  Note that no rendering operations are started until a renderbuffer is executed.  (See Render Buffers)

parameters

handledevice pointer (see: d2_opendevice)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_setdlistblocksize

d2_s32 d2_setdlistblocksize(d2_device *handle,
d2_u32 size)

Set blocksize for default displaylists.

Sets the number of displaylist entries per block (aka page).  The value given is effectively used for internal calls to d2_newrenderbuffer as both ‘initialsize’ and ‘stepsize’.  For hints on how to optimize this size see documentation of d2_newrenderbuffer.

The default blocksize is: 204

parameters

handledevice pointer (see: d2_opendevice)
sizenumber of displaylist entries per block (minimum is 3)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

note

The minimum number of displaylist entries per block is 3.  This limitation is required to terminate a list correctly, there must be enough space to insert a dlist jump and a special termination entry.

see also

d2_getdlistblocksize, d2_newrenderbuffer

+ +

d2_getdlistblocksize

d2_u32 d2_getdlistblocksize(const d2_device *handle)

Get blocksize of default displaylist.

Function will return the number of displaylist entries per block

parameters

handledevice pointer (see: d2_opendevice)

returns

number of displaylist entries per block, or 0 if an error occurs

see also

d2_setdlistblocksize, d2_newrenderbuffer

+ +

d2_getdlistblockcount

d2_u32 d2_getdlistblockcount(d2_device *handle)

Get number of blocks of default displaylist (writelist).

Function will return the number of used blocks for current displaylist

parameters

handledevice pointer (see: d2_opendevice)

returns

number of used blocks

see also

d2_setdlistblocksize, d2_newrenderbuffer

+ +

d2_commandspending

d2_s32 d2_commandspending(d2_device *handle)

Check if there are pending commands in the current displaylist.

parameters

handledevice pointer (see: d2_opendevice)

returns

boolean value: true when there are commands pending, also 0 if an error occurs

see also

d2_getdlistblockcount

+ +
+ + + + + + + + + + +
const d2_char * d2_getversionstring(void)
Query versionID string (device independent)
d2_s32 d2_getversion(void)
Query versionID (device independent)
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
d2_s32 d2_closedevice(d2_device *handle)
Destroy a device handle.
d2_s32 d2_geterror(const d2_device *handle)
Query device error information.
const d2_char * d2_geterrorstring(const d2_device *handle)
Query detailed device error information.
d2_s32 d2_inithw(d2_device *handle,
d2_u32 flags)
Initialize hardware for working with specified device.
d2_s32 d2_deinithw(d2_device *handle)
Unlink hardware currently bound by specified device.
d1_device * d2_level1interface(const d2_device *handle)
Get the lowlevel device handle currently used by the d2_device.
d2_u32 d2_getrevisionhw(const d2_device *handle)
Query hw revisionID.
const d2_char * d2_getrevisionstringhw(const d2_device *handle)
Query hw revisionID string.
d2_s32 d2_lowlocalmemmode(d2_device *handle,
d2_u32 dlistblockfactor,
d2_u32 dlistblocks)
Enable and configure the ‘low localmem’ mode.
d2_s32 d2_selectrendermode(d2_device *handle,
d2_u32 mode)
Select a rendering mode.
d2_u32 d2_getrendermode(const d2_device *handle)
Get the rendering mode.
d2_s32 d2_layermerge(d2_device *handle)
Join outline and solid parts of currently selected renderbuffer.
d2_s32 d2_outlinewidth(d2_device *handle,
d2_width width)
Define the width of geometry outlines.
d2_s32 d2_shadowoffset(d2_device *handle,
d2_point x,
d2_point y)
Define the offset of geometry shadows.
d2_s32 d2_flushframe(d2_device *handle)
Wait for current rendering to end.
d2_s32 d2_setdlistblocksize(d2_device *handle,
d2_u32 size)
Set blocksize for default displaylists.
d2_u32 d2_getdlistblocksize(const d2_device *handle)
Get blocksize of default displaylist.
d2_u32 d2_getdlistblockcount(d2_device *handle)
Get number of blocks of default displaylist (writelist).
d2_s32 d2_commandspending(d2_device *handle)
Check if there are pending commands in the current displaylist.
List of all dave driver errorcodes.
Renderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.
d2_renderbuffer * d2_newrenderbuffer(d2_device *handle,
d2_u32 initialsize,
d2_u32 stepsize)
Create a new renderbuffer.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_perfcount-c.html b/src/drivers/dave2d/docs/files/code/dave_perfcount-c.html new file mode 100644 index 000000000..b1d579e7a --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_perfcount-c.html @@ -0,0 +1,46 @@ + + +Profiling + + + + + + + + + +

Profiling

Performance measurement counter functions

Check D2FB_PERFCOUNT bit of d2_getrevisionhw to see if performance counters are available.

Summary
ProfilingPerformance measurement counter functions
Performance counting
d2_setperfcounteventSet the event to be counted by performance counter.
d2_setperfcountvalueSet the current performance counter value.
d2_getperfcountvalueGet the current performance counter value.
+ +

Performance counting

+ +

d2_setperfcountevent

d2_s32 d2_setperfcountevent(d2_device *handle,
d2_u32 counter,
d2_u32 event)

Set the event to be counted by performance counter.

Does not work while D/AVE is active!  When calling this while D/AVE is active executing a display list, rendering errors or even hangups can occur.

parameters

handledevice pointer (see: d2_opendevice)
counter0 or 1: which of both available performance counters to use
eventwhich events the selected performance counter has to count

events

d2_pc_disabledisable performance counter
d2_pc_davecyclesDAVE active cycles
d2_pc_fbreadsframebuffer read access
d2_pc_fbwritesframebuffer write access
d2_pc_texreadstexture read access
d2_pc_invpixelsinvisible pixels (enumerated but selected with alpha 0%)
d2_pc_invpixels_missinvisible pixels while internal fifo is empty (lost cycles)
d2_pc_dlrcyclesdisplaylist reader active cycles
d2_pc_fbreadhitsframebuffer read hits
d2_pc_fbreadmissesframebuffer read misses
d2_pc_fbwritehitsframebuffer write hits
d2_pc_fbwritemissesframebuffer write misses
d2_pc_texreadhitstexture read hits
d2_pc_texreadmissestexture read misses
d2_pc_clkcyclesevery clock cycle (for use as timer)
d2_pc_dlrburstreadsdisplaylist reader burst reads
d2_pc_dlrwordsreaddisplaylist reader words read
d2_pc_rlerewindstexture rle decoder rewinds
d2_pc_texburstreadstexture cache burst reads
d2_pc_texwordsreadtexture cache words read
d2_pc_fbburstreadsframebuffer cache burst reads
d2_pc_fbwordsreadframebuffer cache words read
d2_pc_fbburstwritesframebuffer cache burst writes
d2_pc_fbwordswrittenframebuffer cache words written

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_setperfcountvalue

d2_s32 d2_setperfcountvalue(d2_device *handle,
d2_u32 counter,
d2_slong value)

Set the current performance counter value.

Does not work while D/AVE is active!  When calling this while D/AVE is active executing a display list, rendering errors or even hangups can occur.

parameters

handledevice pointer (see: d2_opendevice)
counter0 or 1: which of both available performance counters to use
valuevalue to be set: 0 for reset

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_getperfcountvalue

d2_slong d2_getperfcountvalue(d2_device *handle,
d2_u32 counter)

Get the current performance counter value.

parameters

handledevice pointer (see: d2_opendevice)
counter0 or 1: which of both available performance counters to use

returns

current counter register value

+ +
+ + + + + + + + + + +
d2_s32 d2_setperfcountevent(d2_device *handle,
d2_u32 counter,
d2_u32 event)
Set the event to be counted by performance counter.
d2_s32 d2_setperfcountvalue(d2_device *handle,
d2_u32 counter,
d2_slong value)
Set the current performance counter value.
d2_slong d2_getperfcountvalue(d2_device *handle,
d2_u32 counter)
Get the current performance counter value.
d2_u32 d2_getrevisionhw(const d2_device *handle)
Query hw revisionID.
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
List of all dave driver errorcodes.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_rbuffer-c.html b/src/drivers/dave2d/docs/files/code/dave_rbuffer-c.html new file mode 100644 index 000000000..698262c2d --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_rbuffer-c.html @@ -0,0 +1,92 @@ + + +Render Buffers + + + + + + + + + +

Render Buffers

Renderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.

Issuing rendering commands to the D/AVE driver does not directly trigger a hardware activity but adds a set of commands to the currently selected Renderbuffer (see: d2_selectrenderbuffer).

This buffer can be executed directly by the hardware.  For best performance and maximum parallelism there should always be one renderbuffer executing while another one is being filled (double-buffered render buffers).

The application can manage this on its own by using d2_selectrenderbuffer and d2_executerenderbuffer or make use of the utility functions and internal buffers (see: d2_startframe and d2_endframe).

startframe / endframe

The recommended method using double-buffered render buffers is to use d2_startframe and d2_endframe.  These functions use two internal render buffers in turn.  The internal render buffers can be accessed by d2_getrenderbuffer.

d2_startframe(handle); // --> start HW rendering of the previous frame (buffer a), switch to buffer b for all following render commands
+
+// ... now issue new render commands to buffer b while HW is rendering the previous frame from render buffer a ...
+
+d2_endframe(handle); // --> close render buffer b which has just captured all render commands, wait for HW to finish rendering of buffer a
+
+// may now propagate the rendered frame (from buffer a) to the display controller

selectrenderbuffer / executerenderbuffer / flushframe

Render buffers can also be managed by the application.  Use d2_newrenderbuffer to allocate a new render buffer.  To issue render commands a render buffer must be selected by d2_selectrenderbuffer.  A render buffer can then be executed by d2_executerenderbuffer.  Before d2_executerenderbuffer can be called again the application has to wait for Dave to be finished by d2_flushframe.

d2_selectrenderbuffer(handle, buffer);
+
+// issue render commands
+
+d2_executerenderbuffer(handle, buffer);
+d2_flushframe(handle);
+// propagate the rendered frame to the display controller

Using a single render buffer

Please note that when using just a single render buffer (no double-buffering) the allocated buffer can not be freed as long as it is selected because the buffer will be linked for internal usage.  This means that another call of d2_selectrenderbuffer must be issued with a second buffer to de-select the previous buffer to avoid memory leaks.

buffer = d2_newrenderbuffer(handle, 25, 25);
+d2_selectrenderbuffer(handle, buffer);
+d2_executerenderbuffer(handle, buffer, d2_ef_default);
+d2_flushframe(handle);
+...
+// select a different buffer before freeing
+d2_selectrenderbuffer(handle, newbuffer);
+d2_freerenderbuffer(handle, buffer);

If no second render buffer is available and only a single render buffer should be used the following two commands have to be called before creating any render buffer.  This will prevent internal buffer linkage!

// close internal render buffer 0
+d2_executerenderbuffer(locD2DHandle,d2_getrenderbuffer(locD2DHandle, 0), 0);
+// close internal render buffer 1
+d2_executerenderbuffer(locD2DHandle,d2_getrenderbuffer(locD2DHandle, 1), 0);
+...
+buffer = d2_newrenderbuffer(handle, 25, 25);
+d2_selectrenderbuffer(handle, buffer);
+d2_executerenderbuffer(handle, buffer, d2_ef_default);
+d2_flushframe(handle);
+d2_freerenderbuffer(handle, buffer); // free a selected buffer

However, it is recommended to use at least two render buffers, e.g.  d2_startframe and d2_endframe.

executedlist

Instead of d2_executerenderbuffer a given Dlist can be executed directly by d2_executedlist.

Summary
Render BuffersRenderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.
Renderbuffer Management
d2_newrenderbufferCreate a new renderbuffer.
d2_freerenderbufferDestroy and free a renderbuffer.
d2_selectrenderbufferChoose a renderbuffer for writing.
d2_executerenderbufferRender the content of a renderbuffer.
d2_getrenderbufferReturn internal renderbuffers.
Utility Functions
d2_startframeMark the begin of a scene.
d2_endframeMark the end of a scene.
d2_relocateframeChange framebuffer for render commands already issued.
d2_dumprenderbufferCopy the content of a renderbuffer into user memory.
d2_getrenderbuffersizeQuery the number of allocated display list entries.
d2_freedumpedbufferfree a chunk of memory returned from d2_dumprenderbuffer.
+ +

Renderbuffer Management

+ +

d2_newrenderbuffer

d2_renderbuffer * d2_newrenderbuffer(d2_device *handle,
d2_u32 initialsize,
d2_u32 stepsize)

Create a new renderbuffer.

Renderbuffers are filled by the driver but read (executed) directly by the Dave hardware.  Buffers grow on demand but only shrink slowly: If a page was not used for 60 calls of d2_executerenderbuffer, the page is freed one at a time: The next page will not be freed before 60 further calls have elapsed.

A single displaylist entry requires 20bytes of memory, choosing large page sizes is potential waste of memory while too many small pages can degrade the performance of both reading and writing to the buffer.

By using d2_getrenderbuffersize, it is possible to query the number of used entries for a given application.  This can be used to optimize the page size.

The number of used pages of the renderbuffer currently used as writebuffer can be queried using d2_getdlistblockcount.

parameters

handledevice pointer (see: d2_opendevice)
initialsizenumber of displaylist entries in the first page (minimum is 3)
stepsizenumber of displaylist entries in following pages (minimum is 3)

returns

pointer to internal renderbuffer (or NULL if failed)

see also

d2_getrenderbuffer, d2_setdlistblocksize, d2_freerenderbuffer

+ +

d2_freerenderbuffer

d2_s32 d2_freerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)

Destroy and free a renderbuffer.

You can only free buffers that were created by d2_newrenderbuffer and are not currently executed.  To make sure execution has finished the application can call d2_flushframe.

note

Please note that when using just a single render buffer (no double buffering) the allocated buffer can not be freed as long as it is selected (see above for more details).

parameters

handledevice pointer (see: d2_opendevice)
bufferrenderbuffer address

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_selectrenderbuffer

d2_s32 d2_selectrenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)

Choose a renderbuffer for writing.  Selecting a buffer that is currently executed will cause rendering failures.

The previously selected renderbuffer is flushed.  All subsequent Rendering Functions write to the specified renderbuffer.  The buffer is finalized when d2_executerenderbuffer is called.  The render buffer is reset for writing a new list after selection.

For the usage of render buffers see Render Buffers.

If buffer is 0 then the internal renderbuffer for writing will be selected, thus d2_startframe/d2_endframe can be continued to use (see also d2_getrenderbuffer).

parameters

handledevice pointer (see: d2_opendevice)
bufferrenderbuffer address or 0

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_executerenderbuffer

d2_s32 d2_executerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
d2_u32 flags)

Render the content of a renderbuffer.

For the usage of render buffers see Render Buffers.

Before rendering is started, the renderbuffer is prepared for execution.  This involves flushing of scratch buffers, possibly merge of layers in certain render modes (see d2_selectrendermode) and potentially copying the display list to a dedicated video memory or at least flushing of the CPU data caches.  The buffer passed to d2_executerenderbuffer can be used for execution again by calling d2_executerenderbuffer again with the same buffer as argument.  But before new render commands can be written to the buffer it must be selected by d2_selectrenderbuffer.

Note that before calling d2_executerenderbuffer, it must be made sure that no render buffer is currently executed on the hardware.  This can be done by either waiting for the respective interrupt or by calling d2_flushframe.

Note that even when d2_flushframe is issued to wait for the rendering of the buffer to finish the buffer still has to be reselected (using d2_selectrenderbuffer) in order to use it again for rendering.

Note that calling this function from inside an interrupt service routine is not recommended, as the execution time can not be foreseen.  If it is called from inside the D/AVE ‘display list finished’ ISR anyway, it needs to be made sure that clearing the IRQ happens before the call to d2_executerenderbuffer!  Register writes to the D/AVE core are not allowed while a display list is being executed.

Note that if d2_ef_execute_once is used a new render buffer must be selected by d2_selectrenderbuffer even if it is the same render buffer.

parameters

handledevice pointer (see: d2_opendevice)
bufferrenderbuffer address
flags(not used)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_getrenderbuffer

d2_renderbuffer * d2_getrenderbuffer(d2_device *handle,
d2_s32 index)

Return internal renderbuffers.

Two renderbuffers are allocated automatically for every device.  These cannot be freed manually (destruction is automatic) but can be used for rendering.

Note that if internal buffers are used the utility functions d2_startframe and d2_endframe might not work as expected anymore.  These functions use both internal buffers for ‘double buffering’ and rely on using d2_selectrenderbuffer exclusively.

parameters

handledevice pointer (see: d2_opendevice)
indexrenderbuffer index (only 0 and 1 are valid indices)

returns

pointer to internal renderbuffer (or NULL if failed)

+ +

Utility Functions

+ +

d2_startframe

d2_s32 d2_startframe(d2_device *handle)

Mark the begin of a scene.

Use this function (together with d2_endframe) to let the driver handle render buffer execution and flipping automatically.

When startframe is called the render buffer that was filled during the last frame (between previous d2_startframe/d2_endframe) is executed on the HW.  New render commands that are sent after this ‘startframe’ are put into the other render buffer.

For the usage of render buffers see Render Buffers.

parameters

handledevice pointer (see: d2_opendevice)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_endframe

d2_s32 d2_endframe(d2_device *handle)

Mark the end of a scene.

Use this function (together with d2_startframe) to let the driver handle render buffer execution and flipping automatically.

Endframe makes sure the previous frame (the one started on the HW by the last call of d2_startframe) has been rendered completely.  A wait for the HW is done if necessary.  The render buffer just filled with render commands (since the last d2_startframe) is logically closed.

For the usage of render buffers see Render Buffers.

parameters

handledevice pointer (see: d2_opendevice)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_relocateframe

extern d2_s32 d2_relocateframe(d2_device *handle,
const void *ptr)

Change framebuffer for render commands already issued.

This function can be used to change the target framebuffer of all d2 render commands that have been issued since the last d2_startframe.

It does only work if framebuffer format and size stay the same and only a single framebuffer has been set used d2_framebuffer since the frame has been started.  The current framebuffer is not changed, this would require a call to d2_framebuffer afterwards.

parameters

handledevice pointer (see: d2_opendevice)
ptrnew address of the top left pixel (coordinate 0,0)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

note

Intention of this function is to support an immediate flush to a hidden framebuffer when the frame currently assembled was initially prepared for the currently displayed framebuffer.  Use d2_layermerge to take care about outline and solid parts.

This function can only be used when double word clearing is disabled (see: d2_opendevice) and ‘low localmem’ mode is not enabled (see: d2_lowlocalmemmode)!

note

If d2_adddlist (d2_al_no_copy) commands have been used these added dlists are not changed.

+ +

d2_dumprenderbuffer

d2_s32 d2_dumprenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
void **rdata,
d2_s32 *rsize)

Copy the content of a renderbuffer into user memory.

The entire renderbuffer is stored as one flat dave displaylist in memory.  Writes to the displaylist control register (display list jumps) are removed and replaced by the code following at the new address - this way the dumped list can be relocated in memory.

Note that the application has to free the memory allocated for a dumped list using d2_freedumpedbuffer.

This function can only be used when double word clearing is disabled (see: d2_opendevice) and ‘low localmem’ mode is not enabled (see: d2_lowlocalmemmode).

note

Use d2_layermerge to take care about outline and solid parts.

note

d2_dumprenderbuffer does not work correctly if d2_adddlist (d2_al_no_copy) commands have been used.  Use d2_adddlist (d2_al_copy) instead if you want to get dlists with the desired content.

parameters

handledevice pointer (see: d2_opendevice)
bufferrenderbuffer address
rdatapointer to memory (filled by function)
rsizesize of memory in bytes (filled by function)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_getrenderbuffersize

d2_u32 d2_getrenderbuffersize(d2_device *handle,
d2_renderbuffer *rb)

Query the number of allocated display list entries.  Each display list entry is based on one address word and 4 data words (20 bytes).  This function can be used to profile an application and optimize the page sizes set via d2_setdlistblocksize or d2_newrenderbuffer.  It is recommended to call this function only directly before d2_executerenderbuffer, when all required commands are inside the render buffer.

This function can only be used when ‘low localmem’ mode is not enabled (see: d2_lowlocalmemmode).

note

If d2_adddlist (d2_al_no_copy) commands have been used these added dlists are not counted.

parameters

handledevice pointer (see: d2_opendevice)
rbpointer to renderbuffer

returns

the number of allocated display list entries, or 0 if an error occurs

+ +

d2_freedumpedbuffer

d2_s32 d2_freedumpedbuffer(d2_device *handle,
void *data)

free a chunk of memory returned from d2_dumprenderbuffer.

Dumped renderbuffers must be released using this function.  Passing a NULL pointer for ‘data’ is accepted and does nothing.

parameters

handledevice pointer (see: d2_opendevice)
datapointer to memory (created by d2_dumprenderbuffer)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +
+ + + + + + + + + + +
d2_renderbuffer * d2_newrenderbuffer(d2_device *handle,
d2_u32 initialsize,
d2_u32 stepsize)
Create a new renderbuffer.
d2_s32 d2_freerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)
Destroy and free a renderbuffer.
d2_s32 d2_selectrenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)
Choose a renderbuffer for writing.
d2_s32 d2_executerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
d2_u32 flags)
Render the content of a renderbuffer.
d2_renderbuffer * d2_getrenderbuffer(d2_device *handle,
d2_s32 index)
Return internal renderbuffers.
d2_s32 d2_startframe(d2_device *handle)
Mark the begin of a scene.
d2_s32 d2_endframe(d2_device *handle)
Mark the end of a scene.
extern d2_s32 d2_relocateframe(d2_device *handle,
const void *ptr)
Change framebuffer for render commands already issued.
d2_s32 d2_dumprenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
void **rdata,
d2_s32 *rsize)
Copy the content of a renderbuffer into user memory.
d2_u32 d2_getrenderbuffersize(d2_device *handle,
d2_renderbuffer *rb)
Query the number of allocated display list entries.
d2_s32 d2_freedumpedbuffer(d2_device *handle,
void *data)
free a chunk of memory returned from d2_dumprenderbuffer.
d2_s32 d2_flushframe(d2_device *handle)
Wait for current rendering to end.
d2_s32 d2_executedlist(d2_device *handle,
const void *address,
d2_u32 flags)
Execute an already prepared display list.
d2_u32 d2_getdlistblockcount(d2_device *handle)
Get number of blocks of default displaylist (writelist).
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
d2_s32 d2_setdlistblocksize(d2_device *handle,
d2_u32 size)
Set blocksize for default displaylists.
List of all dave driver errorcodes.
There is a rendering function for each supported geometric shape.
Renderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.
d2_s32 d2_selectrendermode(d2_device *handle,
d2_u32 mode)
Select a rendering mode.
d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)
Specify the rendering target.
d2_s32 d2_layermerge(d2_device *handle)
Join outline and solid parts of currently selected renderbuffer.
d2_s32 d2_lowlocalmemmode(d2_device *handle,
d2_u32 dlistblockfactor,
d2_u32 dlistblocks)
Enable and configure the ‘low localmem’ mode.
d2_s32 d2_adddlist(d2_device *handle,
void *address,
d2_s32 size,
d2_u32 flags)
Add an already prepared display list to the current render buffer.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_render-c.html b/src/drivers/dave2d/docs/files/code/dave_render-c.html new file mode 100644 index 000000000..ad09d627c --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_render-c.html @@ -0,0 +1,82 @@ + + +Rendering Functions + + + + + + + + + +

Rendering Functions

There is a rendering function for each supported geometric shape.

Rendering functions are the only functions that cause entries into the Render Buffers.  Material and mode changes translate into hardware register access only when something is actually rendered.

Summary
Rendering FunctionsThere is a rendering function for each supported geometric shape.
Direct Rendering
d2_clearRender fill the entire framebuffer with a single color.
d2_renderboxRender a rectangle.
d2_renderlineRender a wide line.
d2_renderline2Render a wide line with 2 different widths.
d2_rendertriRender a triangle.
d2_renderquadRender a quadrangle.
d2_rendercircleRender a circle or circle ring.
d2_renderwedgeRender a circle arc or circle ring arc.
Buffer Rendering
d2_renderpolylineRender a polyline
d2_renderpolyline2Render a polyline with multiple width
d2_rendertrilistRender a polygon from a triangle list.
d2_rendertristripRender a polygon from a triangle strip.
d2_rendertrifanRender a polygon from a triangle fan
d2_renderpolygonRender a convex polygon
+ +

Direct Rendering

+ +

d2_clear

d2_s32 d2_clear(d2_device *handle,
d2_color color)

Render fill the entire framebuffer with a single color.

The current cliprect is used to determine framebuffer dimensions.  Clearing is the only function that bypasses the current solid context and renders plain color - regardless of blendmodes, fillmodes and other attributes.

Because clearing does bypass the context material settings it is the only function that includes both alpha and color in the 32bit ‘color’ argument.  The most significant byte is used to fill the framebuffer alpha channel if one is present.

To clear using all context attributes simply use d2_renderbox.

parameters

handledevice pointer (see: d2_opendevice)
colorfill color and alpha

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_renderbox

d2_s32 d2_renderbox(d2_device *handle,
d2_point x1,
d2_point y1,
d2_width w,
d2_width h)

Render a rectangle.

Nothing is rendered if width or height are 0.  Subpixel positions and fractional sizes are supported.

parameters

handledevice pointer (see: d2_opendevice)
x1,y1top left corner (fixedpoint)
wwidth of rectangle in pixels (fixedpoint)
hheight of rectangle in pixels (fixedpoint)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_renderline

d2_s32 d2_renderline(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w,
d2_u32 flags)

Render a wide line.

Subpixel positions and fractional widths are supported.

To modify the lineend styles use d2_setlinecap, but note that only included endpoints will get a cap.  So if d2_lf_exclude_end is specified and linecap is set to round - the endpoint will not get rounded.

parameters

handledevice pointer (see: d2_opendevice)
x1,y1startpoint (fixedpoint)
x2,y2endpoint (fixedpoint)
wwidth of line in pixels (fixedpoint)
flagsadditional lineend flags

lineend flags

d2_le_exclude_startstartpoint is not part of the line
d2_le_exclude_endendpoint is not part of the line
d2_le_exclude_nonestart and endpoint are part of the line
d2_le_exclude_bothstart and endpoint are not part of the line

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_renderline2, d2_setlinecap

+ +

d2_renderline2

d2_s32 d2_renderline2(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w1,
d2_width w2,
d2_u32 flags)

Render a wide line with 2 different widths.

Line can have two different width at start and endpoint, forming a trapezoid.  If both widths are equal it is faster to use d2_renderline instead.  Subpixel positions and fractional widths are supported.

To modify the lineend styles use d2_setlinecap, but note that only included endpoints will get a cap.  So if d2_lf_exclude_end is specified and linecap is set to round - the endpoint will not get rounded.

parameters

handledevice pointer (see: d2_opendevice)
x1,y1startpoint (fixedpoint)
x2,y2endpoint (fixedpoint)
w1width of line in pixels at startpoint (fixedpoint)
w2width of line in pixels at endpoint (fixedpoint)
flagsadditional lineend flags

lineend flags

d2_le_exclude_startstartpoint is not part of the line
d2_le_exclude_endendpoint is not part of the line
d2_le_exclude_nonestart and endpoint are part of the line
d2_le_exclude_bothstart and endpoint are not part of the line

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_renderline, d2_setlinecap

+ +

d2_rendertri

d2_s32 d2_rendertri(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_u32 flags)

Render a triangle.

Triangles must be specified with clockwise orientation.  Subpixel positions are supported.  In order to get correct antialiasing and outlines shared edges must be specified using edge flags.

parameters

handledevice pointer (see: d2_opendevice)
x1,y1first point (fixedpoint)
x2,y2second point (fixedpoint)
x3,y3third point (fixedpoint)
flagstriangle edge flags

triangle edge flags

d2_edge0_sharededge from (x1,y1) - (x2,y2) is shared
d2_edge1_sharededge from (x2,y2) - (x3,y3) is shared
d2_edge2_sharededge from (x3,y3) - (x1,y1) is shared

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_renderquad

d2_s32 d2_renderquad(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_point x4,
d2_point y4,
d2_u32 flags)

Render a quadrangle.

A quadrangle is a convex four-sided polygon (quadrilateral is the precise mathematical term).  Quadrangles must be specified with clockwise orientation.  Subpixel positions are supported.  In order to get correct antialiasing and outlines shared edges must be specified using edge flags.

parameters

handledevice pointer (see: d2_opendevice)
x1,y1first point (fixedpoint)
x2,y2second point (fixedpoint)
x3,y3third point (fixedpoint)
x4,y4fourth point (fixedpoint)
flagsquadrangle edge flags

triangle edge flags

d2_edge0_sharededge from (x1,y1) - (x2,y2) is shared
d2_edge1_sharededge from (x2,y2) - (x3,y3) is shared
d2_edge2_sharededge from (x3,y3) - (x4,y4) is shared
d2_edge3_sharededge from (x4,y4) - (x1,y1) is shared

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_rendercircle

d2_s32 d2_rendercircle(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w)

Render a circle or circle ring.

Circles are directly rasterized and not reduced to linear parts by the hardware.  Subpixel positions, radii and widths are supported.  Nonantialiased circle rings with a fractional width below 1 pixel will have drop outs (missing pixels).

parameters

handledevice pointer (see: d2_opendevice)
x,ycenter (fixedpoint)
rradius (fixedpoint)
wwidth or 0 for a solid circle (fixedpoint)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_renderwedge

d2_s32 d2_renderwedge(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w,
d2_s32 nx1,
d2_s32 ny1,
d2_s32 nx2,
d2_s32 ny2,
d2_u32 flags)

Render a circle arc or circle ring arc.

Same as d2_rendercircle but clipped by two additional linear boundaries, resulting in an arc.  As default the two half planes form an intersected area for the clipping region.  For angles > 180 deg the flag d2_wf_concave must be used.  When the flag d2_wf_concave is set the two half planes form a united, concave area.  In order to get correct antialiasing and outlines shared edges must be specified using edge flags (only linear edges can be shared).

parameters

handledevice pointer (see: d2_opendevice)
x,ycenter (fixedpoint)
rradius (fixedpoint)
wwidth or 0 for a solid circle (fixedpoint)
nx1, ny1normal vector of first edge (16:16 fixedpoint)
nx2, ny2normal vector of second edge (16:16 fixedpoint)
flagsedge sharing and concave flags

circle wedge flags

d2_edge0_sharedfirst edge is shared
d2_edge1_sharedsecond edge is shared
d2_wf_concavedefines that the clipping region forms a united area for angles > 180 deg

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

note

d2_renderwedge internally calls d2_setclipgradient for drawing wedges and will overwrite the clip gradient settings!

remarks

The figure below shows four examples of different wedges and the corresponding normal vectors (n1, n2).  In order to get correct antialiasing all vectors must be normalized to a length of one.

example

...
+d2_setcolor(handle, 0, 0x0000ff);
+d2_renderwedge(handle, 100<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,   -46340, -46340,   0);
+d2_renderwedge(handle, 200<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    0<<16, -1<<16,   0);
+d2_renderwedge(handle, 300<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    46340, -46340,   0);
+d2_renderwedge(handle, 400<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    1<<16,  0<<16,   0);
+...

remarks

The figure below shows the same examples but with d2_wf_concave set.

example

...
+d2_setcolor(handle, 0, 0x0000ff);
+d2_renderwedge(handle, 100<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,   -46340, -46340,   d2_wf_concave);
+d2_renderwedge(handle, 200<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    0<<16, -1<<16,   d2_wf_concave);
+d2_renderwedge(handle, 300<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    46340, -46340,   d2_wf_concave);
+d2_renderwedge(handle, 400<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    1<<16,  0<<16,   d2_wf_concave);
+...
+ +

Buffer Rendering

+ +

d2_renderpolyline

d2_s32 d2_renderpolyline(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_width w,
d2_u32 flags)

Render a polyline

Line segments inside the polyline are connected as defined by d2_setlinejoin and endpoints of the polyline are using the current linecap style set by d2_setlinecap.  If the line is closed (d2_le_closed) it has no endpoints and therefore no linecaps.

parameters

handledevice pointer (see: d2_opendevice)
datapointer to an array of 2*’count’ d2_point values (‘count’ x,y pairs)
countnumber of vertices
wwidth of polyline
flagsadditional lineend flags

lineend flags

d2_le_exclude_startfirst point is not part of the polyline
d2_le_exclude_endlast point is not part of the polyline
d2_le_closedpolyline has no start or endpoint, last vertex is connected back to first

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_setlinecap, d2_setlinejoin

+ +

d2_renderpolyline2

d2_s32 d2_renderpolyline2(d2_device *handle,
const d2_point *data,
d2_u32 count,
const d2_width *w,
d2_u32 flags)

Render a polyline with multiple width

Similar to d2_renderpolyline but a width can be supplied for each vertex.  Line segments inside the polyline are connected by round line joins and endpoints of the polyline are using the current linecap style set by d2_setlinecap.  If the line is closed (d2_le_closed) it has no endpoints and therefore no linecaps.

parameters

handledevice pointer (see: d2_opendevice)
datapointer to an array of 2*’count’ d2_point values (‘count’ x,y pairs)
countnumber of vertices
wpointer width to an array of ‘count’ d2_width values (width for each vertex)
flagsadditional lineend flags

lineend flags

d2_le_exclude_startfirst point is not part of the polyline
d2_le_exclude_endlast point is not part of the polyline
d2_le_closedpolyline has no start or endpoint, last vertex is connected back to first

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_setlinecap, d2_setlinejoin, d2_renderpolyline

+ +

d2_rendertrilist

d2_s32 d2_rendertrilist(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)

Render a polygon from a triangle list.

Each triangle must be defined in clockwise order.  In order to get correct antialiasing and outlines, shared edges must be specified using edge flags (see: d2_rendertri for flag definition).  There is one flagbyte per triangle.  If no sharing is required (e.g. no antialiasing) you can pass NULL for the ‘flags’ pointer.

For each triangle 3 vertices are specified in the data array.

parameters

handledevice pointer (see: d2_opendevice)
datapointer to an array of 6*count d2_point values (3*count x,y pairs)
flagspointer to an array to count bytes containing edgesharing flags or NULL.  If NULL is passed it is assumed that no edges are shared.
countnumber of triangles

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_rendertri, d2_rendertrifan, d2_rendertristrip

+ +

d2_rendertristrip

d2_s32 d2_rendertristrip(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)

Render a polygon from a triangle strip.

When rendering connected structures using a set of triangles a triangle strip can be used instead of a triangle list (d2_rendertrilist).  The advantage is that for every triangle except the first one only one additional vertex has to be specified.  The other two vertices are reused from the previous triangle.  See diagram for explanation:

Triangles rendered from the order given above are :

  • 1,2,3
  • 2,4,3
  • 3,4,5
  • 4,6,5

Note that every second triangle is flipped automatically in order to keep them all in clockwise orientation.  Internal edges are automatically flagged as shared but you can still specify a flag for each triangle in order to define additional shared edges.  There is one flagbyte per triangle.  If no additional sharing information is required you can pass NULL for the ‘flags’ pointer.

The first triangle must be defined in clockwise order (others will then be clockwise as well).

parameters

handledevice pointer (see: d2_opendevice)
datapointer to an array of 2*count+4 d2_point values (count+2 x,y pairs)
flagspointer to an array to count bytes containing edgesharing flags or NULL
countnumber of triangles

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_rendertri, d2_rendertrifan, d2_rendertrilist

+ +

d2_rendertrifan

d2_s32 d2_rendertrifan(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)

Render a polygon from a triangle fan

When rendering connected structures where all triangles share a common vertex a triangle fan can be used instead of a triangle list (d2_rendertrilist).  The advantage is that for every triangle except the first one only one additional vertex has to be specified.  The other two vertices are reused from the previous triangle and the common base vertex.  See diagram for explanation:

Triangles rendered from the order given above are :

  • 1,2,3
  • 1,3,4
  • 1,4,5

Internal edges are automatically flagged as shared but you can still specify a flag for each triangle in order to define additional shared edges.  There is one flagbyte per triangle.  If no additional sharing information is required you can pass NULL for the ‘flags’ pointer.

The first triangle must be defined in clockwise order (others will then be clockwise as well).

parameters

handledevice pointer (see: d2_opendevice)
datapointer to an array of 2*count+4 d2_point values (count+2 x,y pairs)
flagspointer to an array to count bytes containing edgesharing flags or NULL
countnumber of triangles

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_rendertri, d2_rendertrilist, d2_rendertristrip

+ +

d2_renderpolygon

d2_s32 d2_renderpolygon(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_u32 flags)

Render a convex polygon

All vertices have to be in clockwise order.  If seperation into monoton subregions is required, internal edges will be flagged as ‘shared’ automatically.  Outer edges are always nonshared for now.

parameters

handledevice pointer (see: d2_opendevice)
datapointer to an array of d2_point values (count x,y pairs)
countnumber of points
flagsreserved (should be NULL)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +
+ + + + + + + + + + +
d2_s32 d2_clear(d2_device *handle,
d2_color color)
Render fill the entire framebuffer with a single color.
d2_s32 d2_renderbox(d2_device *handle,
d2_point x1,
d2_point y1,
d2_width w,
d2_width h)
Render a rectangle.
d2_s32 d2_renderline(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w,
d2_u32 flags)
Render a wide line.
d2_s32 d2_renderline2(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w1,
d2_width w2,
d2_u32 flags)
Render a wide line with 2 different widths.
d2_s32 d2_rendertri(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_u32 flags)
Render a triangle.
d2_s32 d2_renderquad(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_point x4,
d2_point y4,
d2_u32 flags)
Render a quadrangle.
d2_s32 d2_rendercircle(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w)
Render a circle or circle ring.
d2_s32 d2_renderwedge(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w,
d2_s32 nx1,
d2_s32 ny1,
d2_s32 nx2,
d2_s32 ny2,
d2_u32 flags)
Render a circle arc or circle ring arc.
d2_s32 d2_renderpolyline(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_width w,
d2_u32 flags)
Render a polyline
d2_s32 d2_renderpolyline2(d2_device *handle,
const d2_point *data,
d2_u32 count,
const d2_width *w,
d2_u32 flags)
Render a polyline with multiple width
d2_s32 d2_rendertrilist(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle list.
d2_s32 d2_rendertristrip(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle strip.
d2_s32 d2_rendertrifan(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle fan
d2_s32 d2_renderpolygon(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_u32 flags)
Render a convex polygon
Renderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
List of all dave driver errorcodes.
d2_s32 d2_setlinecap(d2_device *handle,
d2_u32 mode)
Specify lineend style.
d2_s32 d2_setclipgradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_s32 nx,
d2_s32 ny,
d2_u32 flags)
Define an alpha gradient for clipping.
d2_s32 d2_setlinejoin(d2_device *handle,
d2_u32 mode)
Specify polyline connection style.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_texture-c.html b/src/drivers/dave2d/docs/files/code/dave_texture-c.html new file mode 100644 index 000000000..5221395a9 --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_texture-c.html @@ -0,0 +1,78 @@ + + +Texture Functions + + + + + + + + + +

Texture Functions

Modify texture mapping settings

Texture attributes are part of the context (see: Context Functions) but a single context might contain multiple mapping attributes if multiple texture hardware units are present.

Summary
Texture FunctionsModify texture mapping settings
Texture Attribute Writes
d2_settextureSpecify the source for texture mapping.
d2_settexturemodeDefine texture addressing details.
d2_settextureoperationChoose texture operation for each channel.
d2_settexopparamSet texture operation parameter.
d2_settexturemappingDefine texture mapping.
d2_settexelcenterSet texel center offset.
d2_settexclutSet texture colour palette pointer.
d2_settexclut_partSet a part of the color lookup table.
d2_writetexclut_directWrite a part of the color lookup table directly to the render buffer.
d2_settexclut_offsetSet index offset for indexed texture formats.
d2_settexclut_formatSet color format of texture CLUT.
d2_setcolorkeySet the color for color keying.
Texture Attribute Queries
d2_gettextureoperationaQuery texture operation for alpha channel.
d2_gettextureoperationrQuery texture operation for red channel.
d2_gettextureoperationgQuery texture operation for green channel.
d2_gettextureoperationbQuery texture operation for blue channel.
d2_gettexopparam1Query texture operation parameter p1.
d2_gettexopparam2Query texture operation parameter p2.
+ +

Texture Attribute Writes

+ +

d2_settexture

d2_s32 d2_settexture(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)

Specify the source for texture mapping.

The specified texture is used only when d2_setfillmode is set to d2_fm_texture

parameters

handledevice pointer (see: d2_opendevice)
ptraddress of the top left texel (coordinate 0,0)
pitchnumber of texels (not bytes) per scanline
widthwidth of texture in texels (equal or less than pitch)
heightheight of texture in texels
formattexel encoding type (texture format)

texture formats

d2_mode_alpha8monochrome 8bit per pixel
d2_mode_alpha4monochrome 4bit per pixel
d2_mode_alpha2monochrome 2bit per pixel
d2_mode_alpha1monochrome 1bit per pixel
d2_mode_rgb565colored 16bit per pixel (alpha is blue)
d2_mode_argb8888colored 32bit per pixel
d2_mode_rgba8888colored 32bit per pixel
d2_mode_rgb888(same as d2_mode_argb8888)
d2_mode_argb4444colored 16bit per pixel
d2_mode_rgba4444colored 16bit per pixel
d2_mode_rgb444(same as d2_mode_argb4444)
d2_mode_argb1555colored 16bit per pixel
d2_mode_rgba5551colored 16bit per pixel
d2_mode_rgb555(same as d2_mode_argb1555)
d2_mode_ai44colored, palletized 8bit per pixel, (4 bit alpha, 4 bit indexed RGB: see d2_settexclut)
d2_mode_i8colored, palletized 8bit per pixel (palette is used if d2_mode_clut is also set)
d2_mode_i4colored, palletized 4bit per pixel (palette is used if d2_mode_clut is also set)
d2_mode_i2colored, palletized 2bit per pixel (palette is used if d2_mode_clut is also set)
d2_mode_i1colored, palletized 1bit per pixel (palette is used if d2_mode_clut is also set)

additional flags (can be combined with all above formats) :

d2_mode_clutEnables the color look up table (for d2_mode_i8 through d2_mode_i1) (see d2_settexclut).

Modes d2_mode_rgb888, d2_mode_rgb444 and d2_mode_rgb555 can be used as well.  In this case alpha information has to be ignored by setting a d2_settextureoperation of d2_to_one for alpha.

If the CLUT is not enabled with an indexed color format (d2_mode_i8 to d2_mode_i1), the index is written directly to the framebuffer.  The index can be combined with the offset, see d2_settexclut_offset.

In case of d2_mode_alpha4 to d2_mode_alpha1 bits are MSB aligned and replicated to the lower bits of the 8 bit format of the internal A, R, G and B channels.

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

note

Please notice that a cache flush using ‘d1_cacheblockflush’ might be necessary if memory contents were changed before!  To avoid problems you can use the d1 driver memory management functions ‘d1_copytovidmem’ or ‘d1_copyfromvidmem’, which implicitly do a cache flush.

+ +

d2_settexturemode

d2_s32 d2_settexturemode(d2_device *handle,
d2_u32 mode)

Define texture addressing details.

Texture wrapping will work with texture dimensions that are integer powers of two only (2,4,8,16,32,..).  Other sizes will wrap at the next higher power of two.

parameters

handledevice pointer (see: d2_opendevice)
modeany combination of texture mode bits (default is d2_tm_filter, see below)

texture mode bits

d2_tm_wrapuwrap texture on U axis (x-direction)
d2_tm_wrapvwrap texture on V axis (y-direction)
d2_tm_filteruapply linear filter on U axis (x-direction)
d2_tm_filtervapply linear filter in V axis (y-direction)
d2_tm_filterapply bilinear filter (both axis)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_settextureoperation

d2_s32 d2_settextureoperation(d2_device *handle,
d2_u8 amode,
d2_u8 rmode,
d2_u8 gmode,
d2_u8 bmode)

Choose texture operation for each channel.

Textures can be ‘colorized’ by a varity of operations.  A textureoperation can be defined for each channel (a,r,g,b) individually.  Depending on the chosen operation one or two additional parameters have to be set using d2_settexopparam.

The default setting is d2_to_one, d2_to_copy, d2_to_copy, d2_to_copy and will therfore ignore any alpha information in the texture.

parameters

handledevice pointer (see: d2_opendevice)
amodetexture operation for alpha channel
rmodetexture operation for red channel
gmodetexture operation for green channel
bmodetexture operation for blue channel

texture operations

d2_to_zeroreplace channel data with zero (no parameters)
d2_to_onereplace channel data with one (no parameters)
d2_to_replacereplace channel data with a constant (p1)
d2_to_copycopy channel data unchanged (no parameters)
d2_to_invertinvert channel data (no parameters)
d2_to_multiplymultiply channel data with a constant (p1)
d2_to_invmultiplymultiply inverted data with a constant (p1)
d2_to_blenduse channel data to blend between two constants (p1,p2)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_settexopparam

+ +

d2_settexopparam

d2_s32 d2_settexopparam(d2_device *handle,
d2_u32 index,
d2_u32 p1,
d2_u32 p2)

Set texture operation parameter.

Several texture operations require additional constants.  See d2_settextureoperation for a list and description of all operations and their constants.  The index parameter selects the color channels for which new parameters are to be set.

Both constant have to be in the range of 0 ..  255 unused constants (e.g. p2 in most operations) are ignored.  Note that several color channel indices can be or’ed together.

parameters

handledevice pointer (see: d2_opendevice)
indexcolor channel index / indices
p1parameter ‘p1’ (see: d2_settextureoperation)
p2parameter ‘p2’ (see: d2_settextureoperation)

color channel indices

d2_cc_alphaalpha channel
d2_cc_redred channel
d2_cc_greengreen channel
d2_cc_blueblue channel
d2_cc_rgball channels except alpha
d2_cc_allall channels

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_settextureoperation

+ +

d2_settexturemapping

d2_s32 d2_settexturemapping(d2_device *handle,
d2_point x,
d2_point y,
d2_s32 u0,
d2_s32 v0,
d2_s32 dxu,
d2_s32 dyu,
d2_s32 dxv,
d2_s32 dyv)

Define texture mapping.

This is the most basic function to setup the texture mapping frame of reference.  You can directly specify the texture increments in u and v direction for stepping on the x or y axis.

parameters

handledevice pointer (see: d2_opendevice)
x , yposition of the (u0,v0) texel on screen (fixedpoint)
u0, v0initial texture coordinates (valid at point x,y) (16:16 fixedpoint)
dxu, dxvtexture increment for a step in x direction (16:16 fixedpoint)
dyu, dyvtexture increment for a step in y direction (16:16 fixedpoint)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_settexelcenter

d2_s32 d2_settexelcenter(d2_device *handle,
d2_point x,
d2_point y)

Set texel center offset.

Default texel center is top left corner (0.0 , 0.0)

parameters

handledevice pointer (see: d2_opendevice)
x , ysubpixel position of the texel center (fixedpoint)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_settexclut

d2_s32 d2_settexclut(d2_device *handle,
d2_color *clut)

Set texture colour palette pointer.

For indexed texture formats (see: d2_settexture), a colour look-up table is used.  This function registers a pointer to a ARGB CLUT (32 bit values, format 0xAARRGGBB) with the current context.  The size of the CLUT must be 16 resp.  256 words (see note).

The pointer needs to be persistent, as the table is not immediately copied to the context.  It is read once before the next object using textures is rendered or if d2_settexclut_part is used.  If the CLUT is changed later on, d2_settexclut has to be called again to trigger a new upload.

parameters

handledevice pointer (see: d2_opendevice)
clutpersistent pointer to CLUT

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

note

size of CLUT:16 x 32bit if feature bit D2FB_TEXCLUT256 = 0 (see d2_getrevisionhw)
size of CLUT:256 x 32bit if feature bit D2FB_TEXCLUT256 = 1 (see d2_getrevisionhw)

the parameter clut can be NULL.  If the CLUT was cached then the allocated memory will be freed (see: d2_settexclut_part)

see also

d2_settexture, d2_settexclut_part

+ +

d2_settexclut_part

d2_s32 d2_settexclut_part(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)

Set a part of the color lookup table.

Only parts of the CLUT can be set or overridden.  The CLUT content will be cached in the current context.  If a pointer to a CLUT was given by d2_settexclut this CLUT contents is first copied to the context.  The contents of clut_part is then copied to the cached CLUT starting at start_index with a length of length.

The size of the CLUT is 256 resp.  16 (if feature bit D2FB_TEXCLUT256 = 1 resp.  = 0 (see d2_getrevisionhw))

parameters

handledevice pointer (see: d2_opendevice)
clut_partpointer to a segment for the CLUT
start_indexstart index of the CLUT where clut_part will be copied to (0..size-1)
lengthnumber of CLUT entries to be copied (1..size)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_settexclut

+ +

d2_writetexclut_direct

d2_s32 d2_writetexclut_direct(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)

Write a part of the color lookup table directly to the render buffer.

Only parts of the CLUT can be set.  The contents of clut_part is written directly to the render buffer starting at start_index with a length of length.

The size of the CLUT is 256 resp.  16 (if feature bit D2FB_TEXCLUT256 = 1 resp.  = 0 (see d2_getrevisionhw))

parameters

handledevice pointer (see: d2_opendevice)
clut_partpointer to a segment for the CLUT
start_indexstart index of the CLUT where clut_part will be written to (0..size-1)
lengthnumber of CLUT entries to write (1..size)

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

note

  • no data needs to be cached
  • clut_part does not need to be persistent
  • a context switch does not restore the contents of the CLUT

see also

d2_settexclut d2_settexclut_part

+ +

d2_settexclut_offset

d2_s32 d2_settexclut_offset(d2_device *handle,
d2_u32 offset)

Set index offset for indexed texture formats.

For the indexed texture formats d2_mode_i4, d2_mode_i2 and d2_mode_i1 (see: d2_settexture) an offset to the color index can be used.

The offset is an 8 bit resp.  4 bit value (if feature bit D2FB_TEXCLUT256 = 1 resp.  = 0 (see d2_getrevisionhw))

parameters

handledevice pointer (see: d2_opendevice)
offsetoffset to index (default = 0); will be or’ed with the index of the texel

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

see also

d2_settexclut d2_settexture

+ +

d2_settexclut_format

d2_s32 d2_settexclut_format(d2_device *handle,
d2_u32 format)

Set color format of texture CLUT.

The Color lookup table has 256 entries of 32 bit color values.  Each color value is coded as ARGB8888.  In case of RGB565 the CLUT 256x32bit is divided into a lower and an upper part for 256 16bit color entries.  One 32bit word contains two successive 16bit color entries.  The lower 16 bit contain the first color entry and the upper 16 bit contain the next color entry.  The upper part of the CLUT can be accessed by the texture unit by setting the texclut_offset to 0x80.  When loading the CLUT 32bit words are written to the RAM.  In this 16bit mode the driver has to take care to write the correct data.

If the feature bit D2FB_TEXCLUT256 = 0 the format applies to 16 entries of 32 bit (see d2_getrevisionhw).

parameters

handledevice pointer (see: d2_opendevice)
formatcolor format

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

color formats

d2_mode_argb8888colored 32bit per pixel (default)
d2_mode_rgb565colored 16bit per pixel (alpha is blue)

see also

d2_settexclut d2_settexture

+ +

d2_setcolorkey

d2_s32 d2_setcolorkey(d2_device *handle,
d2_s32 enable,
d2_color color_key)

Set the color for color keying.

Color keying compares every RGB value of a texture pixel with color_key.  If the values are equal then Alpha as well as R, G and B are set to 0 to mark the pixel transparent.

parameters

handledevice pointer (see: d2_opendevice)
enableenables color keying
color_keyRGB value of color key

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

note

colorkeying is available if the feature bit D2FB_COLORKEY is set (see d2_getrevisionhw)

see also

d2_settexture

+ +

Texture Attribute Queries

+ +

d2_gettextureoperationa

d2_u8 d2_gettextureoperationa(d2_device *handle)

Query texture operation for alpha channel.

See d2_settextureoperation for a list of texture operations

parameters

handledevice pointer (see: d2_opendevice)

returns

texture operation. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_gettextureoperationr, d2_gettextureoperationg, d2_gettextureoperationb

+ +

d2_gettextureoperationr

d2_u8 d2_gettextureoperationr(d2_device *handle)

Query texture operation for red channel.

See d2_settextureoperation for a list of texture operations

parameters

handledevice pointer (see: d2_opendevice)

returns

texture operation. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_gettextureoperationa, d2_gettextureoperationg, d2_gettextureoperationb

+ +

d2_gettextureoperationg

d2_u8 d2_gettextureoperationg(d2_device *handle)

Query texture operation for green channel.

See d2_settextureoperation for a list of texture operations

parameters

handledevice pointer (see: d2_opendevice)

returns

texture operation. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_gettextureoperationa, d2_gettextureoperationr, d2_gettextureoperationb

+ +

d2_gettextureoperationb

d2_u8 d2_gettextureoperationb(d2_device *handle)

Query texture operation for blue channel.

See d2_settextureoperation for a list of texture operations

parameters

handledevice pointer (see: d2_opendevice)

returns

texture operation. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_gettextureoperationa, d2_gettextureoperationr, d2_gettextureoperationg

+ +

d2_gettexopparam1

d2_alpha d2_gettexopparam1(d2_device *handle,
d2_u32 index)

Query texture operation parameter p1.

See d2_settexopparam and d2_settextureoperation for details

parameters

handledevice pointer (see: d2_opendevice)
indexcolor channel index

color channel indices

d2_cc_alphaalpha channel
d2_cc_redred channel
d2_cc_greengreen channel
d2_cc_blueblue channel

returns

texture operation parameter p1. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_settexopparam

+ +

d2_gettexopparam2

d2_alpha d2_gettexopparam2(d2_device *handle,
d2_u32 index)

Query texture operation parameter p2.

See d2_settexopparam and d2_settextureoperation for details

parameters

handledevice pointer (see: d2_opendevice)
indexcolor channel index

color channel indices

d2_cc_alphaalpha channel
d2_cc_redred channel
d2_cc_greengreen channel
d2_cc_blueblue channel

returns

texture operation parameter p2. undefined in case of an error (check with d2_geterror or d2_geterrorstring)

see also

d2_settexopparam

+ +
+ + + + + + + + + + +
d2_s32 d2_settexture(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for texture mapping.
d2_s32 d2_settexturemode(d2_device *handle,
d2_u32 mode)
Define texture addressing details.
d2_s32 d2_settextureoperation(d2_device *handle,
d2_u8 amode,
d2_u8 rmode,
d2_u8 gmode,
d2_u8 bmode)
Choose texture operation for each channel.
d2_s32 d2_settexopparam(d2_device *handle,
d2_u32 index,
d2_u32 p1,
d2_u32 p2)
Set texture operation parameter.
d2_s32 d2_settexturemapping(d2_device *handle,
d2_point x,
d2_point y,
d2_s32 u0,
d2_s32 v0,
d2_s32 dxu,
d2_s32 dyu,
d2_s32 dxv,
d2_s32 dyv)
Define texture mapping.
d2_s32 d2_settexelcenter(d2_device *handle,
d2_point x,
d2_point y)
Set texel center offset.
d2_s32 d2_settexclut(d2_device *handle,
d2_color *clut)
Set texture colour palette pointer.
d2_s32 d2_settexclut_part(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)
Set a part of the color lookup table.
d2_s32 d2_writetexclut_direct(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)
Write a part of the color lookup table directly to the render buffer.
d2_s32 d2_settexclut_offset(d2_device *handle,
d2_u32 offset)
Set index offset for indexed texture formats.
d2_s32 d2_settexclut_format(d2_device *handle,
d2_u32 format)
Set color format of texture CLUT.
d2_s32 d2_setcolorkey(d2_device *handle,
d2_s32 enable,
d2_color color_key)
Set the color for color keying.
d2_u8 d2_gettextureoperationa(d2_device *handle)
Query texture operation for alpha channel.
d2_u8 d2_gettextureoperationr(d2_device *handle)
Query texture operation for red channel.
d2_u8 d2_gettextureoperationg(d2_device *handle)
Query texture operation for green channel.
d2_u8 d2_gettextureoperationb(d2_device *handle)
Query texture operation for blue channel.
d2_alpha d2_gettexopparam1(d2_device *handle,
d2_u32 index)
Query texture operation parameter p1.
d2_alpha d2_gettexopparam2(d2_device *handle,
d2_u32 index)
Query texture operation parameter p2.
Modify material settings
d2_s32 d2_setfillmode(d2_device *handle,
d2_u32 mode)
Select fillmode (solid,patter,texture,..)
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
List of all dave driver errorcodes.
d2_u32 d2_getrevisionhw(const d2_device *handle)
Query hw revisionID.
d2_s32 d2_geterror(const d2_device *handle)
Query device error information.
const d2_char * d2_geterrorstring(const d2_device *handle)
Query detailed device error information.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_utility-c.html b/src/drivers/dave2d/docs/files/code/dave_utility-c.html new file mode 100644 index 000000000..ed82b85fa --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_utility-c.html @@ -0,0 +1,53 @@ + + +Utility Functions + + + + + + + + + +

Utility Functions

Triangle mapping and perspective warp operations

Summary
Utility FunctionsTriangle mapping and perspective warp operations
Functions
d2_utility_maptriangleThis function uses d2_settexturemapping to map a texture on a triangle.
d2_utility_perspectivewarpCopies an image in perspective manner to a destination rectangle.
d2_utility_fbblitcopyCopy a rectangular part inside the current framebuffer.
d2_rendercircle_no_hilimiterprecisionEnable or disable the high limiter precision feature of the latest D/AVE 2D renderer for drawing blurred circles with higher image quality.
+ +

Functions

+ +

d2_utility_maptriangle

d2_s32 d2_utility_maptriangle(d2_device *handle,
const d2_f32 *points,
const d2_f32 *uvs)

This function uses d2_settexturemapping to map a texture on a triangle.

parameters

handledevice pointer (see: d2_opendevice)
pointsptr to array of six floats containing the screen positions (x,y pairs)
uvsptr to array of six floats containing the texture coordinates (u,v pairs)

Please remember that this function has to access the current texture details (width, height and pitch) in order to calculate a correct mapping.  So the final texture must be active in the selected context at the time d2_utility_maptriangle is called. d2_utility_maptriangle is internally using d2_settexturemapping and is overwriting the current values.

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

see also

d2_settexturemapping

+ +

d2_utility_perspectivewarp

d2_s32 d2_utility_perspectivewarp(d2_device *handle,
d2_u16 srcwidth,
d2_u16 srcheight,
d2_s16 srcx,
d2_s16 srcy,
d2_s16 dstwidth,
d2_s16 dstheight,
d2_s16 dstx,
d2_s16 dsty,
d2_u16 wt)

Copies an image in perspective manner to a destination rectangle.

d2_utility_perspectivewarp is internally using d2_settexturemapping and is overwriting the current values.

parameters

handledevice pointer (see: d2_opendevice)
srcwidthwidth of source rectangle in pixels
srcheightheigth of source rectangle in pixels
srcxx position in source bitmap
srcyy position in source bitmap
dstwidthwidth of destination rectangle in pixels
dstheightheight of destination rectangle in pixels
dstxx position in destination bitmap
dstyy position in destination bitmap
wt1/z (z>1) value in 16 Bit fraction (z=2 -> wt=65536/2)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

example

Copy a 256x256 source texture into a 640x480 destination rectangle:

...
+d2_settexture( handle, texture, 256, 256, 256, d2_mode_rgb565 );
+d2_settexturemode( handle, 0 );
+d2_setfillmode( handle, d2_fm_texture );
+d2_utility_perspectivewarp(  handle, 256, 256, 0, 0, 640, 480, 0, 0, 65536/4 );
+...

limitations

This function is not meant for dynamic perspective animations.

see also

d2_settexturemapping

+ +

d2_utility_fbblitcopy

d2_s32 d2_utility_fbblitcopy(d2_device *handle,
d2_u16 width,
d2_u16 height,
d2_blitpos srcx,
d2_blitpos srcy,
d2_blitpos dstx,
d2_blitpos dsty,
d2_u32 flags)

Copy a rectangular part inside the current framebuffer.

This is a wrapper function around d2_blitcopy, which copies a rectangular region inside a single buffer.  Source and destination buffer are the current framebuffer, set via d2_framebuffer.  This function handles the different cases of potentially overlapping source and destination areas and makes sure no read-after-write problems arise.  Note that both source and destination rectangles need to lie fully inside the framebuffer for this function to work correctly.

parameters

handledevice pointer (see: d2_opendevice)
width, heightsize of source/destination rectangle in pixels (integer)
srcx, srcytop/left coordinate of source rectangle (integer)
dstx, dstytop/left coordinate of destination rectangle (integer)
flagsany combination of blit flag bits (see below), passed on to d2_blitcopy

flags parameter bits (only one bit allowed)

d2_bf_no_blitctxbackupfor this blit don’t backup context data for better performance; previous texture modes get lost and must be set again

returns

errorcode (D2_OK if successful) see list of Errorcodes for details

+ +

d2_rendercircle_no_hilimiterprecision

void d2_rendercircle_no_hilimiterprecision(d2_device *handle,
d2_u32 flag)

Enable or disable the high limiter precision feature of the latest D/AVE 2D renderer for drawing blurred circles with higher image quality.  Note: This function can be used to de-activate the feature for compatibility reasons (clear D2FB_HILIMITERPRECISION bit in HW revision)!

parameters

handledevice pointer (see: d2_opendevice)
flag0 will activate the high limiter precision if possible, 1 will deactivate the feature even on newer version of D/AVE 2D.
+ +
+ + + + + + + + + + +
d2_s32 d2_utility_maptriangle(d2_device *handle,
const d2_f32 *points,
const d2_f32 *uvs)
This function uses d2_settexturemapping to map a texture on a triangle.
d2_s32 d2_utility_perspectivewarp(d2_device *handle,
d2_u16 srcwidth,
d2_u16 srcheight,
d2_s16 srcx,
d2_s16 srcy,
d2_s16 dstwidth,
d2_s16 dstheight,
d2_s16 dstx,
d2_s16 dsty,
d2_u16 wt)
Copies an image in perspective manner to a destination rectangle.
d2_s32 d2_utility_fbblitcopy(d2_device *handle,
d2_u16 width,
d2_u16 height,
d2_blitpos srcx,
d2_blitpos srcy,
d2_blitpos dstx,
d2_blitpos dsty,
d2_u32 flags)
Copy a rectangular part inside the current framebuffer.
void d2_rendercircle_no_hilimiterprecision(d2_device *handle,
d2_u32 flag)
Enable or disable the high limiter precision feature of the latest D/AVE 2D renderer for drawing blurred circles with higher image quality.
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
List of all dave driver errorcodes.
d2_s32 d2_settexturemapping(d2_device *handle,
d2_point x,
d2_point y,
d2_s32 u0,
d2_s32 v0,
d2_s32 dxu,
d2_s32 dyu,
d2_s32 dxv,
d2_s32 dyv)
Define texture mapping.
d2_s32 d2_blitcopy(d2_device *handle,
d2_s32 srcwidth,
d2_s32 srcheight,
d2_blitpos srcx,
d2_blitpos srcy,
d2_width dstwidth,
d2_width dstheight,
d2_point dstx,
d2_point dsty,
d2_u32 flags)
Copy rectangle part of the source into destination.
d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)
Specify the rendering target.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/code/dave_viewport-c.html b/src/drivers/dave2d/docs/files/code/dave_viewport-c.html new file mode 100644 index 000000000..486a8139e --- /dev/null +++ b/src/drivers/dave2d/docs/files/code/dave_viewport-c.html @@ -0,0 +1,50 @@ + + +Viewport Functions + + + + + + + + + +

Viewport Functions

Framebuffer and view specific functions.

Summary
Viewport FunctionsFramebuffer and view specific functions.
Clipping
d2_cliprectSpecify the clipping rectangle.
d2_getcliprectGet the clipping rectangle.
Framebuffer management
d2_framebufferSpecify the rendering target.
d2_getframebufferGet information about the rendering target
+ +

Clipping

+ +

d2_cliprect

d2_s32 d2_cliprect(d2_device *handle,
d2_border xmin,
d2_border ymin,
d2_border xmax,
d2_border ymax)

Specify the clipping rectangle.

No pixels outside the clipping rectangle are touched (rendered or read).  The clipping borders are specified as integer positions (in contrast to rendering where subpixel positions are supported).

The driver checks whether the specified rectangle fits within the framebuffer memory (by checking the dimensions given with d2_framebuffer).  Cliprects will be automatically adjusted to fit inside the framebuffer region.

parameters

handledevice pointer (see: d2_opendevice)
xmininteger pixel position of left border (inclusive)
ymininteger pixel position of top border (inclusive)
xmaxinteger pixel position of right border (inclusive)
ymaxinteger pixel position of bottom border (inclusive)

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

d2_getcliprect

d2_s32 d2_getcliprect(d2_device *handle,
d2_border *xmin,
d2_border *ymin,
d2_border *xmax,
d2_border *ymax)

Get the clipping rectangle.

No pixels outside the clipping rectangle are touched (rendered or read).  The clipping borders are specified as integer positions (in contrast to rendering where subpixel positions are supported).

parameters

handledevice pointer (see: d2_opendevice)
xminpointer to an integer that receives pixel position of left border
yminpointer to an integer that receives pixel position of top border
xmaxpointer to an integer that receives pixel position of right border
ymaxpointer to an integer that receives pixel position of bottom border

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +

Framebuffer management

+ +

d2_framebuffer

d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)

Specify the rendering target.

Use this function to define the framebuffer’s memory area and layout.  All subsequent Rendering Functions will work on the given buffer.

Setting a new framebuffer will automatically adjust the cliprect to the maximum range [0 .. width-1] and [0 .. height-1]

parameters

handledevice pointer (see: d2_opendevice)
ptraddress of the top left pixel (coordinate 0,0)
pitchnumber of pixels (not bytes) per scanline
widthwidth of framebuffer in pixels (equal or less than pitch)
heightheight of framebuffer in pixels
formatpixel encoding type (framebuffer format)

framebuffer formats

d2_mode_alpha8monochrome 8bit per pixel
d2_mode_rgb565colored 16bit per pixel
d2_mode_argb8888colored 32bit per pixel
d2_mode_argb4444colored 16bit per pixel
d2_mode_rgba8888colored 32bit per pixel
d2_mode_rgba4444colored 16bit per pixel

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

note

this function has no effect on what memory area is currently visible

+ +

d2_getframebuffer

d2_s32 d2_getframebuffer(d2_device *handle,
void **ptr,
d2_s32 *pitch,
d2_u32 *width,
d2_u32 *height,
d2_s32 *format)

Get information about the rendering target

Use this function to get information about the framebuffer’s memory area and layout (framebuffer pointer, pitch, size and format).

parameters

handledevice pointer (see: d2_opendevice)
ptrpointer to receive address of the top left pixel (coordinate 0,0)
pitchpointer to receive number of pixels (not bytes) per scanline
widthpointer to receive width of framebuffer in pixels (equal or less than pitch)
heightpointer to receive height of framebuffer in pixels
formatpointer to receive pixel encoding type (framebuffer format)

framebuffer formats

d2_mode_alpha8monochrome 8bit per pixel
d2_mode_rgb565colored 16bit per pixel
d2_mode_argb8888colored 32bit per pixel
d2_mode_argb4444colored 16bit per pixel

returns

errorcode (D2_OK if successfull) see list of Errorcodes for details

+ +
+ + + + + + + + + + +
d2_s32 d2_cliprect(d2_device *handle,
d2_border xmin,
d2_border ymin,
d2_border xmax,
d2_border ymax)
Specify the clipping rectangle.
d2_s32 d2_getcliprect(d2_device *handle,
d2_border *xmin,
d2_border *ymin,
d2_border *xmax,
d2_border *ymax)
Get the clipping rectangle.
d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)
Specify the rendering target.
d2_s32 d2_getframebuffer(d2_device *handle,
void **ptr,
d2_s32 *pitch,
d2_u32 *width,
d2_u32 *height,
d2_s32 *format)
Get information about the rendering target
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
List of all dave driver errorcodes.
There is a rendering function for each supported geometric shape.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/doc/images/blit_mapping.png b/src/drivers/dave2d/docs/files/doc/images/blit_mapping.png new file mode 100644 index 0000000000000000000000000000000000000000..92adb90f0f8a5abb641cc99bc820df00c62e2681 GIT binary patch literal 13111 zcmbVzWmHtryZ6uv(%m5lQUX%a5)w)Y!zc{hDMOcpGz=gh-JmD~3?Lvw_s}Q}(hM!# zN_Y?6`(Nv>^?rEQx*ulGIs2Ta_N@KH@7WWrqoqnr$Uq1Jfr!=BlwX2CSOviK#2sv4 zgpo|20bf||FI5#m$YG`};0D+BspeAT2?B}at1Ca%_c7UhO9VHb z@|;gp8&05lauxG|$4@z$L-RV6?yKF4{%Y3 zn^RD;bhEL)dMT9hFbi(v-%m$aVA$4Wac{lT1MxthbF!BwoSngb42uI-Ik~3d*APqY z6ZcmCJn!%R`y}Uh!ZPl*d2heZ+wOawOXc}jAPh>Mk=6zqDhLP}34q{ZN&@*bIz)p8 zMCmhrmVTxVSirM8gJx6CP2Y9h>2&B^}9G&CZZKo=8sIi(5qSx z8zz;%dhf9}-{?J%D!>|W5aR#R%u~txi=Cs*ed2Wv$P`s*hnXh->(6Qba&e74Dw$hH#FPL>Y zz7mZR{M_LXqD<75_weNo)*HC8p4}LGCYgpkq&<&~tbv$#@)24x9mI_JMv)WtINUP3 z85avG>-F^1b*S{Sx#4-tSCBcAZ2gu3eU;v4e^XuY6Vz*Abb_d(QUqcgIWg4Ah}GH(|-dftCJ}aR!Ig3QU-M+rKy0;`VAMd>2Wc zjCYLA6|8idmR=P0Jdk1uBPTxqOXMhLjIU^aQ?Pb(`|`E!1xz)A0GDFR%fjg;;;E;= z{Rqt+b=qIB0UF93E}enW0T+k&vYNiX(c%)Oj0 z>Mgk~PG9_C3@7p(_Pp=PCoB_#=?MipH3lgB!9ZamN(Z;mSwc@*mpl;Pd|SwfjiB&B z!Hb{0A!QOq#GG)NB)4u!`3oMEa%Fgte*90?L&6xmiwI&TMJ9@G=INVN^zo`XitXW{ zb4fab_#z=xH&%F?8P0l4F_~(H4vaJjnxijt@6~>>yPw$+X%N{a=KPV@4Q7mPG0ASB$o-|JN! zD~bF&!xNLOjOmk~Yd7@2&*}8$eZ%|r!kXp}JHU)v<{?h-*seP&8E@lP+&mtzU`MlL zZTjFAxilzS&Yi(yVef0sH%-Qewsw4{7^180<|VwBkHJ%XiEzP;G#B|~eM&v=!$8dn zU&YSh;p|g?9SV;^cv$XWC2);{XeF=rK8cm<$@}6<&Eshlru*=nh^nIm z33|qk%XzOtGMPL}R8eKboH_T46bVE1*K{+b`xKfi#yiol58Pus3b@L>4i}Wx9no}= zfy5!O=rosm=#j@XHtppFOotF3&KW{uBCJ2ZtdT;et*RULDQ>UX$T4q>a7{v4v(wuIo)A@<}Ab&Jhu(DJu*u zMa})5^{# z-bo|jes&pmLa6u=C|H)7|BBlr6IGB>U{a9$5i73h+i-7_#`IJFWA-fUx!c&^V0Uh0C zD9~JX1$_Ny`T1%ucm+~NFc}vjgwdA#(N*eoHpe=#J6+9oyH(v!{i)kH*1Y%Nkv02P zbQ^+6=(SxlcCkcc+*!eE6qgiE>5MAnNKG%3igMd_)y916v#>42vyfDn{dTXKfA2da z{vA|WQTSH0IM<$itm%$mCs>csYixe zmS`05LdN0C%&1_hdA5FIN&@F66zlonTDbuq0&g5Ut_IXGDHj@D+K{mO>|0n+Ileg) zgYrWuvvib$Y-rTgte*O9d{7|z(JwXtex6t&N`m1DQDOQ=w0~*)thY=kY2kz;)b`kqb zGp^_xg&F;{y*0*8HRTZx4;zJx7p?gXS`fkG4Y(h?n=?h(DTaL zFF;hQ!?L0fbbb=110Az}cWU;gVmw1}zG$1+D#UffU+7h8uVdQNDS| zK1(H-`JpsoM`EHJSfnp_#R5M9kWzATav~xk;^JNhOYL(VuRa}pZoPu*2nftos9ddRBk=JbG&E*({P0?8!QZr)Ou_!ReJ;9jJ1nI+vNR;dhNV;Iq}X z-@jT9q({)0&$YEF*xGWlep9BKnxDU3&w3;B)-VRP*t7pknm|y{c5ZGoC*}`4U4sylgXi9Ezr)e_9WB>i;I;*}UvdjX? z%mVo^H;pzWJA)h!A`k{!Wh|6b?xKU}Q4~WbRfHjrEn#fe`^9mgy^e4qH80nl`Ns2u z<<6c2)(ywsOQEC}9o=dg&(sAHt&9ytHb4^Z9#@Sks(m%3{@%wjvTo292)2s|bgAY# zMqFQCtFfXoZ7ZO%BPYv|tl~d~lI)T^tE`5xa&gw?{L^+IpX@|{j0;!>=D-zD8`e$~ zqkDXgw6|N=S8FS67WInWBgwnyzS|-C_&-R;Ef=XKC{oDlB0u|E(QzMQ)1%cz2ZXc=U&CP(Ya;Mu zI|I18u%K|}dj+-^JSMKng?FRzMDUequz&Qc`I%{mLq+?9v_?H{$+#_CfKR^=$u5cI)rG#T3@oWXhw-# z-33MVa)dl%O0wgXg?JKc{D{c&$t8{t2pMg)#AEPTM-DH(0Eh9Gx* z2;mCt5{@stD?e|ic%fWa@&vH^_e>}Fu!h|xhKYFa0~{3W9(nh@{ul_#4j3^!@w3!# z=GeO*eE%C5$?Gm&?}3W}l*jDUJhb3u(NrcojFM<KPnd_WEK!hQaJhbb-#1$gKR5D5-=_}v+))1nr z{c227z(`DF09lURbIACoT5QPIO);nXx?;FaEB zir+6y&~5z~4jhe-Pxj~K%aeN6&Iua?bB!@1$2Kgl=xFIh?$55RweiE1j#qpVC8m2i zB-wOjX8V7=c_qw>VGDbz^!ql<+6$2oci)%U%kWKp&JT}Gc(|a8U#jU|^%H0MI|^}d2q@5T<=fXIAC^pkwSbL>g9tEF^* zpLHau=6vaV<;%2cSAsjP_~ecaOIraxUqaEd{E}XHFav0&sXx1XNw!M zVI{!hP^KF5dwAxR_LS~_Opj4exE&l6OI`5LRmDS?>E>)UW2CDe!;?v-3}U+)z_eOX z8nCDq`qbbkEoTJ3YZ|eQN{cD=dvb>sv)YeG$E`2eCRt#Eh3*sML-#q;e8dOlX*Vpg zq17NvSicb-#%d^aXKlp|>=0u0h&HV>$)-ESV2 zVX2GuHN5(o7CQj$<4HP?|KMOUaaR8kV&$8Si}^Qn-Cm)fDP;ofKyJVgrs12GxCR3P z#TtwPo_sqvrpRbb^7+2qxiOA_Q4HOB1{%w3<@$RV&P-|y=OiJ||2P7bTPIydh*tku zwr>#g`gu~%LrBV#*|N0MRaigxdj9FzYT`)@|E-taQd&dYXwBDTE*AnJDW$_TshkO8z7tWO0hVD4)NFjw4*(7%?EXh; zek!*dz{u_W?(&z9fp~EwxrXQmk69>gfQ|43`e#T0z4ml(b+67V9lhG?OXgk-`g=Xs z@pqy5GOmZ!mN4kF)b#Dea%Agi`J3w!_$7g3I!HO`}duWX=d-HW4_i7D)iLd$|Sv&X|^L?-XoK}j7+R_fo zp3gBmI~(8^w{KEA$UgB^CT#TD-QM1A*vRz<)Qps0qiQ(_zpQArn^+3knl2ts`l1k9sEq-jONh=+d|=-Yb9dL+K*Jm=5~&Vj-&Bjol35 zRTV@kf2I9caU7$>-a<3uce4{?ujR{Fnzy?VjBM3TGa@p74~Ut^I}%?7xBaYjtaF~l zw++2Vc;|h0EbaN}>GHjsRT`7#y@o}N-;{DgkArRkP!bO9ow^F4Rc@4mxIAqcUD%2( z&CSed7f0oFH>h%AygL=IsyOOgFL&!CSTP;eQ>PcQ4Zm%gc3VzK0?tZK89wbZ+o#AK z#yj?|~15$edXfNh*pxU3{=ut=G29K?snQA?(&^JZPopu)|8T!w!kMjNV zOQEt!PY94&Nm)-emZm8CARl(t`kmdWFda{Gt=?ukjS8GUcrK{ZV8_dX8QoyI;&5cZ zaQfF5pO>x-B%G9}2Jlm7e7vqPvy>tBAQkFqHYgI>JJ}jjrQ6rE6l>IhcZT|*Rg7>j zue?wqVf}QP`H_!WE(&XccIqrBd5bNX1j7c@E5g|?8uuDX4W7S)(LOQ>*s1EdCwHWl z7gdZSWLsU|E5WgA%j%4kclj(sD6yq>d&Sc5w0HNn_0&s7^|h4J82(~kri=k;0DsfZ zIT4l2jQNfkZT`FIbOY-$Z8sr$p_)`QDwGyo5qA}f+eh>RSf*Y=sUI?~ zxd;~4)2Kef$C5)oWfvlO(_c$ief^>y!9xOAJ~&}!zHg_|i9##u9nwuXKvQ^lb>R5e zb_&GYx*+|6;5;9m5&GVIvmQ)uYJ|4}wM78aLK z%=fNz^q2r$`?94Du7oK`*e7M==&lg#f zonUeheR;}`-l5BU1@<8dM%G!& zlh8@NQEyMT@qq8JMmVk%J7Bkbxp|QsCoQ)$Nz6TgzRx!znYsu3G}+wRV^vKVAf85aLA2%! zkRdc`rVWfydY&lstZ+l(0!#{7%U74FuxaoYO|Ud5HCPUqX=2Gt{9S!IL^du1fH&b& z8mkC8=r>qMRFtV`VyQ*IWL&Wi6W2P7%-ykjkvBcHr#_osE-4oco)6&2y&l3xX38FM zF`Dtlmv%&cRc%>O7h9ZauICjDiR5)kN*!XCv4K-)97%Rd29n~ZyjVr-_5QqvohVV^ zpgKvRdN_*42z`A96@yVdBE~rNa>lQGf`L~FSHFLuX2l4~LTX#EuOeR0bK?DGPI@?l z3WPyZ7$OqyTqI{b$LyA*KSmtCtzUqq7>0kwj=-M3qWwbfi|a+Ux{#pV9Kx*yZ*(1O z??u8Q8S1t^1n9TS(pyQvT?EX+qJx^v+AF+0I0c>5Fo-AvQPQ{<0rr9D#+3KMABT*F z@sa)e{v}qjP_UmsVv_`f+E|6R%r|@7B4qX2;Nd32lES?3r*FBw6C6ecJdm7`O2x&* z*QAh?jN2Rt-RH#k;^(8xm>!hDYz4#M5`VWR63fOo^uE3*B&WrufDXb9S$k!n@$4N8 zyOx(>6gzOlLuCg-Y=6cyA2{Q=iO&b2e*NlLGO@nn?xl*}p)d3gv-pN=+cN*~$WEHE zyXb(`htg*|TzwcSjMXsBf6D@LAQ#$8>#1((XtxO|A>_rLPMitNK`f9qnV@YTM+3;2 zZCO0PwcY#do81dt4!bS{oC;7pI%2i%H26HyMH;HIe5QjmDf!u-#1^jz|Ent>5g@^% zzTh`w#&@YxN*kKX9D}O^OzIJL$VC$>-u0uI1%k+$H5U_p5$Sa4DxJS(~|F5onf1wDUC=l9$At%7Li*(vwwnR4&gy#a(**z$1(43u+vc8`_-#v1 z{2aNE1=yTV_gU^=1JDKlJcrg7Cj9jP^o|NMPH>B&&Nzj9HJ|%IX0plhQ7NCMUx|s5 z66}COz>xrE5e?)6@>p5Mn4I0VWu0}-%guj#G8 zi73qGB}O?>|JgEN!X^0n8tZ#xmGIwfda;6Aro9+!>nJ;c?1w+FeoV;-zIQfKc1GD@ z^AUE{EhTr{t8(&%-a?bHxVaY4ST_( z8)5)gOyke|+gL%G?>Zl|x1-o9+&VUbri$p;CE5)dGR>Yz`Ch7AY1;)vBV?C;9%o3lS#~B|3Eea|HUtPgbNqR8wdDPf@GDU> zy6rIlqMl`FyExwbK`m(D#XT#dxgqU6TH0ODGPSzC^lluSoqd(0BRT#?uHjSc%*x)~ z>Ninu{nG}U=7|PrTl=oOH!Tx{xY#GZ`PK;swL59F((jdoJT5gtw%%L;xpfxxw4bqK zh(90cNoHuC*y7q1(BYbMUzd22^nPZ+v#V*)gJ4YB@UrKa*-|jG@r~iJ@$u{7*1EyY zAg8@GHO2MW^^KOlS5@nla|cUo5=qm~icnpa4wpI5X$teXjv3(L#Gjyo4;v7mMT;bN0uF zzotZPsVXv6S)2Ety6?@^dnWg!_F3*PG+zZud2UmgN@|KQp+l11UeO4mCCfLMGIDzJ0pL!a<3r- zuQXxcI!JHV=0~6ppARa+>2_7XZ{=_-GA(%=9P$2RQw2*UQ5sMO$9?qa2mc~SbRwo7 zQJx8n`=BPeEK|63afrDiOP&@}qxzx8_%(E*mWqx~7Ti0jw&#j3KSID7c)?!47?QtR z>BsVPSxBqi0T=V3RGj4&ws@$T!175M%a$kEwWx0$CaInj7}OsvQxy><;_&Z%d#70k1Q=D zJ=S|w)tsky#fiU@qje!O^_&S>FK?CYbT+JxF_xx?e!y^5fU{*Jllfjr z=VW9l=X`#v$)TeOQ70CQpc4e33k0;5=aGOisqT1wBu_%)OO%67tow(^PRR!l*_-2a zZi$S){M=T<)vEzkjXODib@xCGxDxVyr5#qR_S!-1M3HQSwLADLgUMy0s z&(;G3j=>NUQEryUe}$%?+h3>;9B(wt78uNGj=9&1gM{2icJeZRX=m-$k5K`cGNak~ z&U4YU(w3H~tKC7(*FjS$r0#>)h&D0rG>~7jNb1yDlUSQ7@9h0c(m(#^s~t?Xt-K(? zLf`47w|Gw)nLSz^#xPL~ZOe$r1B&Pj**^s9Ay7DG2ZC2<41LlGsq7@s{=;;>ybHND zEk0AO`+GAo*cbj}zQS-|YWOXG`;BEvwtjrIspsVu?vO(B+|BTO#n0o5if;A|i>VHP zQyCVEge+{0aq#z!*RQ|{ns!Momh;8I1|M3Si?8MYC3P7Wu$PMk(ShKd&IHFB*7b-T zeHRBnugl_kDE0RY+}Zi}p)e+--;&z9_2@krxTWhvi}QERVlZFO%_pbyfi=Xu4TtWr z<+`$0V@j#GZ2T82CitcQ<3|evf6+UAXh{+X;8@!?RR0_WFsPYU5SscH(FlYCCKzo{u18=uB@7A@B}R zC3CtvJ*fAVaW@D$=NoahX3i8^ItqfVvQ9gS1JzwQ7ClhA%w8{iCR#$!WhqS3=*F)i z1CfOMoia+w$I)4P0%4^s7P;|u`2M>>Pb_)+!A7_kNna-X{rkrE#yd-Ewl@&bn8&~M zobMrHc8TeNV?{5uhvxgiulEh4s=Kc++4ifyi!{TBO3&g3gX@>Cs{HpFQ^W)I!jI?q zoYV4*tG+b`@z7%2>UlwQt`P;$QhL2o>SSr%!efL0HjEz`^IBg*0K3gRQ_Oof1gNA` zd_E<4vb^{jGPF7bfi0GwSh}|kd=>6N93yJerbQNUu5x;Yf|>@drV=t2e?#Tkq8D)B zPJ2YH&VdJaET5%7L)*c32i^~v_x0{qG<-TwH0@WBpjdJRyY&sN@3cxtAK+WVe+XyS z09#E(A-)rQcR1KlUL^10n=gk%=zU)j2$$rn>q5Zw>*HUc_;0iZ2_*H+UBU0F7sV1< zZ1*nss@LVywb!t-TL>g$tpBhqMaggb2OHsjQyv0@WPROYFiUj44$qRVaM++Zk!>S~ zkDY@qFFlSOVubcIW-5L*?WH%kxle(NZe35dFF5PdK+8tkIzm}qWzl`f9lVso12}@8 zCz2}_SZ4#63n+DN#bQ~;GU@UW%KX}9XmH;jHVK+_(h7q~Rs7_jqTpbK=OCKfF_ z)&KzYbY9~o@bz$Jp$xz{`x~Nw=(CF@Svm7^lTn}hZm&x6r3+VDNX%sXX47_=>XTb(wNGyj zu9CHpxsNw6IXSK8i3zJTfemKu)ezGms+;oe*tGA>ewN;sZ{+>P5NA(j!oB(Uw1(^Z z`vW}8FXzt%x0}4Q)(*Q>j+W5NHs*i`v`gS)0QVdkf)PV*;dO(;%U@jpq@WD%^Z#(R!=YQNd_(7I&-f_ zP0(KnhlhQnD*%4Q^+^<$y z@;rBGDvx8-erpqE!aFu|SYh&^k=&wdM-!PUR^j*4qYN9pCgrDW=45Q!@hi5v7KCAK z+;3q(FE`p=Y|_6~d*4Dm-)p&3I~BY-DorAgklVTzKK*O42^mxOXvw)#Wq!FfuXSu9 zoQAsC&xTS32!LgDBQo)Y#q}d6KOH~NSIJPDZnq`h>oCq~JrJpmzaR0rlwJ)PA;G_F z>c$tLxp5S^3Sl%}^kn{pWSYRBPxy@tIwb?9$rl53g@U#Y_}KHyt^aBqQ|y)D)znYy z=5YYd4;*ppGznkJ(H=(?-|0Jz2hftfV}#uND`?K2dfrqSi(eCC#i=VxiUd;x>mkR-bMX^hWN@9Lo>BRO*5f-ASMW)e{Vr|{O zeK4Y*+`%4xdBOxx(g9-}c<;M3wyzZO?70p27fDY%5}tS%^;@i#iM83WFl5j*_BjTR z2MOr(nR+zh2doT1!ZNPTWdcmXUjnxKJu<9KiD{mXp@vwX%gaZVOV(%l6RbgGFr zo90!PkB2t)qDQr|f4v8>E9L#(W)CSyIdt!I%VgLX=iWs=j!;?@8zA6ZQ&z^Yg{C64 z0pDlyXhNJ5{M-b`=~up>L8l5*T&&{fNlQs&X~)S7fq3O*$Xynqn@h0j7%VN5NdGLN z-tcs2fvUbG-6eXl}{@>ZvLnyWM%&u@8+sq{xi~cOQ6OFkeoYZ7mixEL{ zVQX&(f<*^e>|9sh^<9D;-+Vy@1P`igzo@`+aXI&K2d{G4(`OR}z#L&Zq-3k#!HEj% zEYaG}o(*g-A-LTbtp_!Jarc9>7-<6`+RF$rNw@fi@&oG#pO=lQ*$VFzxmIECAFuyd zZT*QQKwhD>hS;06NN2E$XR17=XQO71FOhUs!tq$@y zFKq6?)iS4v)&hN*F5LI9@-kiu-iC1+Y7)KrbPXg}U!|*GUzD<*6mHdal45>fQe;Be zr;gi!?dfTur#qpC;%ypYIS45c99~CIYLQ??#;Ix&OHwYD*NiSBeo&NT09e{WG+B)P z^L4~!He>8(_@@no6;7}>L+-~R0+ICJLXL{kdc|};BmG1+-UY7xwbK0KWR3!R5YnL{tg0=v zc=vAgpY^_yhoU3WZ>yzXk-5IvV653T#Y#$#cH)t;t&^cgw+WOQ+W^YoPZRG7b3z?` zfS|XDr^TrAGS8hVp9=*`5wx*Lvv&GIQ0iAN&R_Eyz+Sl9eOUUb#po_O-npjJveOcR zW18YFj_7s$_8=ei)eY*WlH(t2pr4c3b;QYe|2fIe}{eB zjjq4#RnJQzI9f{u!9aP6Feh;Sa$!%yj)p?w{XDC0D3H#ZGU!Lau zRWqk52vIHMAby_t^xTjhz^v#Q7#SU%B!5j%@C%8GO3hebWSG*4&t49ZsCjwbVBaK1 zPzzdq)AD15lD0~QE8(o`^yjfne#70r!;(3-9qusLv3a^X^^$6ILh=x|FV&}xLhjNP zIO>;}NRF%S0yIT$P9eE|F%JiI?W}KBR{JRP{x(fq0f*=cg(a6%J!#_ak>mz$7W@HJ zjfjXia1RIw08aXaM~7hXPCr(mzS#ge)U#jOJYXOVIQU-K9{U|j8c=ZW8pp+aEtl>fRk}2z}d93yv literal 0 HcmV?d00001 diff --git a/src/drivers/dave2d/docs/files/doc/images/pattern.png b/src/drivers/dave2d/docs/files/doc/images/pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..faf2ccb78c899b5512cd2f6b57cd9a2f064142cd GIT binary patch literal 1148 zcmeAS@N?(olHy`uVBq!ia0vp^7lF8kgAGVN((*Y5q}Y|gW!U_%O?XxI14-? ziy0WWg+Z8+Vb&Z8pdfpRr>`sfHEu3pQKsvxa^HYLvL&t&CC>S|xv6<249-QVi6yBi z3gww4844j8sS56%z5(x3RPz`Zm>+n$IEGZ*dV9+;TRBzc_{aF{*XI@{v^4GHc;qc` zu=|J871sWJ4RSW`E*_R!Rq?_11@{Nu6%S6X?s)x5(TU%($HHq`)d^+Z$tBl4)f26L z)-3S(=BfTa-T3FUCA&F+4gmq{&%Tphi`Sgj_SBnf^Jb51bV)~?--Jfb#$KRj&`?tmN)ANp*G*@R`?tWw@KkawD?`#Ae zS+oECWr$uG2bcKizwI;D+UvZI|61aAUHpDTn!%z4d7q1S{{MRImvrji<@3(H+_c>A z>;nd+Uz_jzU$8Z9>epS%i+An&am=Whx#LCT&i^a6*2P?#57(Y>+}74FxNrH|uhUO| zTtDyJ&ExypEI>;8i)z+xwbMNw>Hqvqa=i1LgN!a;k}daLkE-8Z`akwORNW7sFM&J% zPglvGy4@&Wy)x*U{5PP(&I={a{J7}-?QeG9M9$^LulAe#r{MJW+WAjX4nNK>_M2|o zo7vXEr?5z+()6UbXPy5i|7rj0-)y$||G&S~Hhnh8UmY9_3=Ib@KP?n~_v}V6gA$YA z!P;&A*1znxwmWom`R@BqAN%i`f4MZ?d9L8~2=A^YBSf` rl*M09ZeFZ%y>42=_F|9+WLDHON(42f817`r0A)l^S3j3^P6WdL>8yN~9?34hN zM+SxlI$G(*rba%xIP-00fJ>sH-taChZM>z0scFJ#DG>cgQ z@ywlOzOL>rD$$l6o&X*H8l7Q$oxG9N7u)}A;AQPCEMUj+d~tH zJ3{va2TW;d0|i;?`;Mt*Fv5t`pzT*8NfE@DLoso?PWgBj>>%=8f%t?yJO{f?EgXtj z5x!&jz@C)k)TH#Z_|{0H-HH7`Q{KMJ^z_VwrSZGnkFkDRScM+wH#il3fV@9Ft+OUE zu{R<-JNM9gZ=aLILVUn`+N4);GSaXrFAX|L#aBHQhsgd{Z@rCk}vz<3@-@G%(r^Y58+-_c&m>wUy zFT6i7@$2Uh@6o>_pTym%Wa(KUV+S`0?MjU;lmh`FmsY_sXx$pOQbDW`8pu_yZ6ne!Tb6!}A21jAme8`*f>+jY-@@U&qWPVr$^J!0Vm=UMBVKdogkS@{?=v z{4&j;{;sFJX)~R1ll@no-ypx4I2Ux|>Wf?Xs~=uW-njPaE(L`^`>6knQE&k=I0&vJV5R0OL=tBxiv)g$n_MnLZ^~Mm*=PJ?Hlbs z{%AaM>5aWA&AyXm2I^86naP1`q*Jorpx|Ovz6{FT^dx%W=ztz@9n;# z%YHa@n|Q7kJwHmk&>Hpd4hZ42IC<-Jgn!Ae?;od|wF|CnRJ}a@LCI=&!Q%I*SI1?} z_`TFaNY?$2p+X+f6hbyd&9e2p)F#ssfF&xCzxjHU_Q%qnW17Ql-(7^f*)u{#$PdJu z#t7HXqfZVX_MCLH+ZbEBrE-MRMUeFIlMPhuD*A#U1ke z{F?jCFKhYIo!J+82moWX8$ zHl4?pQ=E+Ly^ne&2f=#RXpCEF8k$dO60i$4<4yXS!Tf)C3qEorl`Mfmoxdi^@S4KT-xExa=bu)r__kIiw9JK4V_C|eX<}pWIyiWg7r7kIM@~J z*qM|?f8)1^_cZ85?42|pr|%3g$W$0w1?TA=3&KyeWe4F>*|EdWK(ZCmQqZL!j#>&o zB!K#?O^<3GhFS$V53^pEZfzj$U;u7i38UZg@*f4`oARpz)(&-vXc|Y&ESS2pW~~8h z(_XK=R1VMS_~DL1t1HZ>L)|wO;>=z#HI_z)kFB*7?eSGx-5cs|&_71sdT0H%R}%Hu zty>TclOdUq{9*;{nzz1u7W~Du1v-Po7xOMjhjEJwaG!?PtrqU=wDCe8VtK)SY=D=x2 zsNZWw>7{wVb;e3}QQmBSUwb}TDO!()|h?-D`KQ#eda&~5OglTcq3U!C>AgTvgMYrmph90XFXI)nPVdWzr1 z&=B9p#up-9SD)HUGH|IHg@3TbPR6v!D1qEI3p`8D*R~p_c#O%Gc@}i^L4FlC%WS?6 zQ^+uiHu=i&$g&~V)B&E#d8co`+`d=s5@kXB0AFkcbQfh2VUB}_E(sT3j7cKYJ= z)la0(5A8pYF{G($G9B;Yr8chL;58|_aUx_*?QpB=G==@3G$gzQk^DTcKnm(#Z=-g7 zz{jjdY&ZD%io9k?I=BR zyjHW-W8iC>cRF?U?XPQ3dsJKXuO5_xaD@!3%Xgn37j19pZx^ULVIfVRsiv6mdter! zv}UAi%M!(}ewX;FTqXyMK+vrc4Nj2h5X~ijXpbEk^k6rD7()0Z-%p6n78JvE=6DDb z(VTSJaL;S3gy}fp@yv{Oxpxa<2zrR?@Tl4@lIl-Qee?aQ@XVWmrS?zekzDGMoqhCS zj`^XJrYElK=Jd|F4rg9Cd*V&xaQDD%0%BJ@a`N7Xfq4Yumd4~$xi*gcdt6=4q-Eu{ zU|=`@zNb~SDf-!|H)^j&4i4I}Y5p5_|C~Ap!zy#0eGL4Bo*^+0nwp}V!ztH0uMnI} zhcL&0NYi!1C{&q3kw=O^sjL!b5eQQ_Mblau7?Fcw0VqOrPl3g^S^}LcnCEK|BDnw- zO97z@z!@99Zc8hPMRR(ZRrP=0H~b<9hzC(g@S3kfm~FS-p!Lx_P^L?g5B}+BT*^0z zdV3LI@+u#sdW+fkc0N%TD!P|{amBc3>aE)<9}XH=t?a0v91^|J-sFu|e@!?c190x! zqj})Oc(mIe+W60WUu0MCTLN5!cq@XtN_0}U_9o6$DFXnO%p?o>qrn$PoxHO^x)^mp z#Q|!&>r-Ok{9bjYss{XvojsjrH^m;X#SiOERTtitZr{e`Eh8ub)2+o3iWhh%p6 zTF4R7hSU{1Zh1`&Yjkcj8ELdX(MS?kKXr!Lf2;Rff1v~W&KZ_1saV!VNvmRg$m94l%{qA|8aPpSODKkyn^jpeeu&L+)&Qe|?mo^p?yle>aUb zH!S{GE%^o6N`@v6(6oN!+txhkmXf!K2lnhC0E$#}VIOI7l?1omM%*i}Clc$ie4I5f zi@a-k3UPmay;Z`{cc0Z9yLJcCZE?H+VkSa=tS{`jkFHcwj9DpoMX-8+PRj3U)of`8 z=H!n5Hmu*PNlNW0=Z9@v$HY$|+j;6^T7_G0@pIg;|1E1v*t8h-ZOyarKc0KB6gVOt z^zIc;?SNcCFQ2dZku{?cjZJIx z&D0UX=gBGAQhW0#`5=6a zK#yFUZHEC5VS0rrdI%tLE6{?&X8Wf0aslVLbWl7JYKgbFC%c6L?9AH>!2=k!^zXx% zpSaXD0P~a$zAQzvu>+_S^iN^(IyU325Eep8vb&g{Dn=D8?G+O+PqCJ89>t~~2o)Xv zBg`?HV08glPL={%L zPmAlQI(0|(X1V|C;sn1lcqGQ13nxMWls^v;z_DrK?}8En|y z`mzdybSYV;ip}a7s9=hrb){yl>83_sjYr3^sbO>JNGvi& znZ8cIWDt{F9BM&i&_i5Z>?zDL5#klFS6vNFuuF|&V3x3usD@M!uq&I12^_-+c@T<2 z8Z{3p5bpi$$5G`Di z9vi}gpG)Uia!~JqW8C-Xw`_DCKC$KS86+OW#-Rt(&wXa2E3!dv{sCM#s1fP2qlTzd z?2#i+a`gz(ugOg!zr1A}nhHP_h{tOkl{PsjKM}-~N2<6E{^}_`L6ChIA3YNvy`pl! zSO_-ef{k&p1fGo2h^*ee-PiRT^?1!DCb7|Et66O8DVS-7c$+z|*%%A;J}T;V(LJq~8knj4GLi zA3>9V9}Ku zx1Jl9LEJU1j()6Uu~OX`jo)?eS0`0;W!R+4I35{sB=*r;bSF86XVUdg9b(KNVJ2da z7`*$55?BQb7vj(?pSXD(dPWGZw2f_4g51Deo`G@80BA=^+!H1Ac@w2oysY+jl-^A{ zM^UyTCB&8uQFs$}_GZTv7c~`+9%jQF0SVMC3WAS;yk-z*c&M|T-4El@RXm8r0qJdsZakuuZz5)l?abllOkhKse<5nKBy*#9wgEBI`J|#vyWTOtV zuLqTf98E^XeY`#a#3#k{o8`iH6t>N9`#rb7Q}^{Bn1qCFxo%M2{Sb>>c-)8o*yAYN zw*%RK>^JJIIz%T15`=`>0?^ucw9l=M3}mE$EVV^6pdAC5Cw7N{WS{tS)Z%4d>xGPe|nAO$g$TYaInLL$~h8`^LN{ z!?l3hqveA_Q~y4tJEPxaN0ks+&u$OD3-1q#=_Cvemkmz+0{pmp-t0rakH7vMdHb6) zD4L8M`!|#GT#=xRHs{9FQ3j4?^v;{~m^n6e{f}UVAZr8Z zFO3%vH6V5D0f+MLDUJ;Lx0O|9zo4`GtW1lL+$I2^rlJAAiVzn-I(`Z@%WXB$kUpCs zsJbO303szBn<(eb?k=K~3U7dn>WSvbi1D(mc|+T?FkggCBMbme2ErTw6|U3-yX4%Z z%vH{So^pv3DU(L3*LqrDRse4=7=NfjK@uZwzt1?IiCJR9_Wvky$p-{>KpYo66*+mQ zAMHn&80^~D5G(ary!ZMb^9Se1XmIs*X&?@tdLM;(i{IOMkA{d(V%Z;!GMbW*CmT>D zmwf?%z{*~l8rnorPK~z(C#wL3?vb=$DHm^Ht>Ez_1P{`jO1&VJw25_QYm6_5;_o}% z%~eE#V$jQ?Tgw#m(FT}s%U$XFT`E`vCRd7 z)t^`2Io(z12X*6PF#ie7D*tvqlx_SKy`zIFYy{@Yqh;*ihA~>l^^x9DkU2ia?8WS@ zGYH-Nys2lgrevh;(V2~gM?>TU{QWLvO#~_v?d2K+n4%|%ca}^a&0Uug3gbLJ?~ze@ zbfqw1PU)^Ap;0al{Yu<<&8Y!)Tk#85poT0vFyDRRV^3Agz$=bGrh`2$Mpdz#8Ll>( z&NgL$Y~1s?2G{;zXB&f0J(oD_Ng&e4`I$_**SVwDy%ms?@z3I&pY6GYiW7J5o&U#+ z4fEI#>J>vmMKD7#|Id|e#G!eFk|_1Q4i(S!A%?o(2WnkyUO-=*`R~~*R(e~|Ku}Qk@hgh!BFs-V<{AS%Nru;dO0SCC zYtBtgl{y{ee|SC~?qiopRZCMLO0y4R$kM0X`q7tg=`h@>NNE5hgk|4IDzbYOnG3Q> z5%ISI##}TimwhCw|%g8=?}~hlobAx z+xYGwC;k$;hlPUn;{@TR&wL6GTF`FvorC;S#;3;iJtQMj@w-zd|IwbbeGdpG?hFqT zrEAJUzFb-ITgd?b{lc+H=SGvJ?j?o9CW-N1XbJuH=EI$jYgLvZFAYBjQqfI7zUC69%C@PegsqrW6MwHa7D1Q|#R{WFL zM9!a?UsXN^>J=3lr>$&K*322`oS$nhMk#;@@)pYk9wsM^C3h1OElKN0tn`og@5dNx zL3!{EE!uMpK!MO5w}jbbW9~mr_<=<|*Pun_jU&j2f`c0y6b$2G=4unfg0$Yy2p$%G zW1Qd63B~l|!OB`RD7NIZ3gWGh`V;p`B24WM_WQVdU4;ZGFJa8WH- zX@!EaJ87lvN8oi1RnOYX*bnLX~{@ob<>;1Ej1!WRc5=mHs_*`%t)8=@59l*5WY zZN*m9G->y5;d^&wdJH>Y<%f%z`5Q!%kRu4Jsx>aJZLjt&)%lwAz8c>$OfM7u$8XsA zE~Lrzs06AWzD#WKsnqg06aIcj;|vsjLNM%N@qc&cr6&dT{Bt=SJ+2Po`s_dr+@51mh$8tof0Lsm2xb}D9H zQ?~Jtq+Z9$(kwz<*B5(3-LtI>(ax_~Z_wJF{`&HvCUPSRe%eaO>JeX--<)v%#0w`n ze<49w&JHWyieV-o+u1;yZUfao`;oqg;3r}oxiH0}vtc3Xl|D6Yq_@}qb-wAZKfBBI zp9lqC(|>0FO{)2Nic2q4|K(_B6`W7_ zKaL2txUE+oP2YZFI#^@7KJ?(-&#jNL&O2UsoGZ~Eh^Jw;4%i(@O!uH@eD_3Nxve#@ z*Q#)H<&s_DQiB*PtNGiE@?{t6ZE&Gvy56R+C;AKJ`r|-T3WQ=bsFU<$Q zyCquzP=`(T{hpbM->H?SPe&ptNKP}eX?W4Z!YtX2rkb(^K306QVBZ$Gx5t;MZMT}- zca~F>YSlvC@Pp5$c0Jks`%^dQasJX}u9@{i?je(>U1n+6t%GDfM!W2M?zaY5@O5IJ z8~~*tq?)vSrVLl}K2a|+6fNi|5Qv5F6Wmara?!?gtPI%##~7b1t+Y8(sj3NUenCY- z$ClpH+P@1Z5asx-`&@iBiIatoal-X2+6Z5+^Ul!+mvej4UUq}w1F(0qM+NUZ@+YEO zolonXzU}P)?5D(uFLieGob6Tu`L_^0hg0}qbzIK7a9J9zZ^EUd;~r4p-tohdO}P`^ zvpATR|B#fvLow1{48|CF;fHljq}O_Bd_gcBhb=v`un>eXp&4qAFO~}ygDnvZhok|I zEIOI4*LF|c6AM=Q!7fozrE2zgcxBalFGmUfY{0f~`H$ztdzCOFit(5)rJ61~6dTp~v%nS6&6Cv^>ZNQhu2iJgXF*L> zJ&+`aV#PKqDf9Lra}G$>gV9>^G~d_Iub@2qM|FvD8ptF@f~BeFw^S~uCK}cSRN9s4 z)^)BWTSN(qm8ZbWS81(Q`=16x&QeOu{fBI5j`zc_@)Y{LQw=jZfzS)A6m9KcNOr z{4littf=l~MT&_%zOp9aQJbMpM~Io8>YMSB?PUrh(0uEyeHs)Kr2mldH!qBBM2a^v zEEqARJNShNOGNs6XPML}T}50pU2+76|B_d~xPsHj3R8$5NK`G<*R=`%@7&%HYW=p3 z6Zq5rFdZLR)qQn2VSyO%IyQE*PLh_arRWrt+FmT-{Mvq^+Nk$L?oAg4zOk`klW%9q;3%&1s4VctVuKES(FsTk{%1RgVe zoW+j#wt%z#IV|5z^FO8`hcpC_2Bc&efU^*~M90x!2Gr8XQeIuVSdS`v;zbEgp%W6- zT6Y`@(rQ^G01K#XQdu7J({+gTrw(!&>6zZ)h49k;wA^L5R z@7E)qS^c40x3UvP-kWnWH^xfk`d7Z3=xdc9^_e_;L@(m*J%h)raSgX650sW-jBp2x zhj8&we;2v*@SX4akxw47C`p6}Jp31?#tjKj@0cD?e{ov{-qqL4%@VsDEHuF^@dqsX%6x;`^rf-Z`G?)do>B7ffr!$ zO5m#l0T~lahY9wfEi1rc$@q(dKN*-KwXH~*J5|6weaFH79$s>P3Nxy`lXKDj#rsg^ zk=YAwxt*a$Ro)*HTTA6MD+z`>GJ39^8T74?MU6Syt2b$4@7Hm&O17^WL52?YQRK*b zwd4-{jtP`tj?Wk0Humd0dLu*gM(Pu*EOsF^)^409^*G@9_7}#rTXLS7Q+z)2RqypD zy(0JF-m(|YI0n+r%|aznsjCR#;Y)(k54s3STgrC@n+OT}GJ_P$>SN+_96JWafg{vyja6s;9slwn2^g*0B`n0otK4&%%viiyVGD z0#JXCwi-9HqTAs_j9d}lK8Nq#$4qYrS!n=P`U);)URH82_cgD=G65i11TKGWNLYB*U8I8SwX>3f0v`Tgw;3#{`S z3tsl&Y%+o_vte2XmU?~`V$1_%3HOr1?qIOS}^ZcD*8w?CrOwr zM$Uh0sroTITpQbD8GTvsp#sza#Vj}%hF6wWoGBz(XcScDuARH?04vq-r}otpv_nhZ zSM*WNT@tH-=77nc{=;JSku7rh4#k&@*d-PHw;dp-+WaxiTBKVg8U*a0L#R?Yikt)N zFrs>3PX0r)nbV52D|<+j2*Aj&-DH?F5zuT8bgvI|7r}NDsU4dWk@XWs8xuzL6MozY zZa64b1PkVZwv5qwGl9;&z^;no&NkZB&A%?nwIX_tOAw3=T+e~^Zw3YvicPuT45QH+ z8SfJ4HI@g(7E!TEFuidZbwtEqJ=Z$+sREJ?$~UU~hPynmVJM*(&`!^z*hc?0 zA7+^keyA*h+=h*Tv)K=%rW+>xW%t+IK4&#W+H6^^QX7w^$ddTd&t?AY7|Wlr z%Lc%pXe6@PxTI}FmB@IHzxjuHoky|VA0%NYicH7Ds_0W@AQJ6g2Zay9ev8USoBnhs zmq!;Zw=7Io8Nznr?=!8b%yeug%zTfB^YG0uP?03hHMwii;@TAZcnj*nR<=8$s9`PhE0v6E@#gS z-eD{}#)pz59DY+q4SuTzWkG8`76S;-0?7ip;c$cq1>)d2q!X%hUNLi(&KzbQ@eGhJ zRr3*zOJnAVp;asNmC{b-jpxZ&O+D4oW2#X#J*XQsNdAUQK7w(dZ6Zh<>!Xa0$JvcL z)#Rv7OK!7d1fFL-QFQaRd0}07JPGK;jn_M#1tF+pMAwJ-nn_mqoyz*z3uk-c zWCU+&j=MQjen&(-Op3GBS2mtX|u<3EAv?KVEn#MjM+l=+nJO5nF7&9-83SogR z-G+grp_4`s&-+rJ*k$V6ik-r8(f~6z9}LU^KS~%N5%4@4UQ#|E^tx=;LoI|(mrc|9 ztj|WWMyKAF{aDcE`osOPH#_`YL?CcBCt>!dmW~8|=cvUAFSZ#;V>sjd(1xU`?ft@* z=1P8A;+B5+TYpDCB!#dMepY(GM#n|I0iFy@j5o??y#!)J0qPR1kD`By{FyQSRNdyX zRBYH?o8Hyv#PA=KrKnq-_1$iKOGHflrx{@THOA5 zzH%J8_-O3Kuw1hmDA5Q-J*Iuu(rFUs%omkk%c52^TStg>=N>sMbhZ4hsXXAuQ{d$i5OBpfDsev;p$Y{0rwCv7+AP3R0C4S8 zldd$y3ePNGaISkQeXf}qg8(h|Y2y>@1)=%qR+0d`g`lk0FU ze|O4->30)fKIRy8)MRCj9jltCXZSuhm#h^ue8Cm>50#!jQuSdzCX|a!KVY%tX9bK! z%OmzTZm_>ty*s}f0;^eqaQ8NmjSr{M)C3IJp#!yTqZenl7i-+>373spD9tqZY__pxA;^ z5$y00`s;iWRw@C<0FE=P$BGScV2C?dmq-rX3f2~bAg}Zih>ZA+uSCgL>n}KkRXGR`s4OZ@vbCm&(a$e%r{u5*l-yfiDm4Pe3e#_k{Lauy}n{5rf#DgGSdDA zIbKYnNCEa)iQ=q8MDjL_RLpX*M*fPP7?dS0O(r4;+}rMm9)A(n8$p+S!=+Q8?ie~@ zJv+%5QGr+^80Gjo&if9-^7?|d0WwQc-91r-K`K=u9hjjP3Z1+^ge<7T7 z;5H`g=|Acc72b|jeOg3nc*ue3De-glJI>B$ z^j73aSoFlxDXqG*@8;R5q?EPgQh!ca5H{kvx#qg9gMfGjM3S1sT0Cnk3l^4rIi_Aj zvbbtl>1|XVGbduCgR;f&7^8A$ahcUzIoUzMEuzFfQ9_?+pz5;Xvx62{EOy<-2J7d6G??8QbR{( zsaTUHSkapSApk_+QB^cKKH`^DN0+q2o9pmvKs}JGTBy2k>mvnw^C2dZ_#5`o;h18B zEUW3tq4N`C{qsW>FC4JM){|e;PAG9psM6Z!u_Z>c(BJ)FbUSEY8Z%}9cpAc#g!BpcD-{?ud=JY|4mwY=$mloFi=zj>6RF~-O-`W3YY{@In=(!DIHA z&E@TX^*+5rF7(cVT)8#sK$>Rym-5+XsoFx%n>Pk*Kzr3CW&Qx`uZkL_?@uI9=nxp% zVdUibyG8PbFALLFUJj_^ja zmmy$ZH@F^I7q8rkvRvXfsJ=5kLLkO_v}<8BNZ9z|OSvC6|NAKUaQ(7lg5VQxAhBek z%gpUDR>5~1Ugf|4Apm-0cj~0xVU_{X8_F_DyfFb7XP4I-X%pn7gYpaynk9Dk0Hrg^ zJ6;3|Sh=7>ZRV!B-r)VmHW$NtV&dqr|LB@2$Z7Z9d31IEZ@Vw^HxI9V`TYCFlfs8m z^U{X1%eRmJ`1Et9)7r~JVJZMhl&_HFSrR(gcX|2R&-KFl<7DRG-J%i^D&z%#0jqdo9BQA$X|~xNgs+@V?XiXXf4OTnL># zH%`gCl3Uo^c_GZ?zlnX>Gi}0}el7El7P+>F^cacrtc!x5%+|hs1je`)wB4bhjqAB} zo?bH|V@#~6#G7_uN3G|fJ)WpeV$GC-u?A?nU1xrmzunVD4=c;3SiToBm4GT8y_B?y zk~8fS%i8oO6~S#6=B7PST}d^;N>P25vbHUVD}im%8Mkep+<3b8fo7dX%h()Kqk8OV za_c#k;W$A)K(}m6^YHwk=bDENGN9m6-O`OK($DfH&-LqGnzFhfDqX*V(67_)@qL|f z>9hU9Q9rQst1{&7!>_6fuWrnhh07z}ov}a%=pM`{c6>@>hOE!;eLh|Co@MdC!JyMy z-f4k~JeH>$M>tlvn78*B!m0m--UL*ky+?w!+fN!2*u0Pau&w_>F|(XH zlly)>CmiE~xy4o=@!3O=XCEUE;w6lAn{yv};(s zmqv6xfUGB%_|gx`F4O#;ShWwyN>bD{8nETq9$ki+sK~2yoRL(^c}H%A>FNZOd0SPh zp>c9+@5{0yjamzYd`(NB84<1MsWW^DB{pKCt9BYFzNBeoU=y*)4)Urp9OS7$-9u%= z)ddyHh@Dd*ip+W}uKtaSledn{JIj-~wIGnaoUVo;ln*HCc-?nwMSo7%QW#zgK;lP& z=Y(hCL^M^TQR%4xC?#1W(bE z7y$!9rpY-fZkAL^*cV^BbM}McI%!l+Djsaw*R106DX`DMXe!~5SZfw2&20nAcOnQ% z@>!5iHP%#yNB0@#)_IZ+AiW&dl0P=MRX*4} zLV>hF;@g=*wLi@6gTChYMa34&rym+Khz&U5P7k9VT~cV!r$WQ}^h2okW=thOe6D(D zFsO^N#k+f_OR2n&_1af8)xk?YJWIxfv>fqK#{M=DKKXlU5jX{A zS;qK)2Yaj1PFS(R45g~{fWf3%u&v?NeP%?eezCw^?FUzLWej?%J38k|zt{IpmP5Yi z-h}!oy#s?h8&2uThIUI22XC}%lTM67;7X51hZ45Q1JjJ1HL~cCFQ~oIYzP*qaRxjU zaAbnvzk!OrG?FE=S*|#kq@bl)(YshaUG)QW5XKf03AqsRuh+H5n$6 z?m$>~X2b8@O8{O%e1ig_agp9>VOdA<^rP9Bv`_l2sO|?a-RToQ3D6Ren)0E@>Lx}c z3+J{A;vx#u%2^<~kL$F%vsQq^btZ&O4FX~S^tyibp7tb2*?ox`Du3ERr_(|D_TUc1 zczFZw$qqqQU8$-1#K~^!D*vdw7`e22Z5|Kj0Q-zj7JtZX>8l(}P*GQ7?WZM!WL1Ps z*|fR_w%NIbvLpDANUoXQ%GxF4ecH3(?||;Tc0cEVPNMFf8#~^Bp$@}N8&%RDxL{JE zC(m8Hf;uVC*?N8#1;2|Ag1z#p2FPUk&MP0D1w-O51U`oNa$&2F>x(jg5!%Xo!n#GtlWs7nX;l@9ykvbG{>*E|j}@B{ znxzqRPCsP~VgyoX6YF`OHu-V6It!HjuGjU&3ofy`cv$YmlGc!smzu8SUzJWXN`BB& z|1pt45a=pXfdNBxwAg{Gt6T*P=q7gm%PG@U-uL!BPr>pr^=oZM@0dVsg3T&>1rlkd zjtES*eX}O$DtD3uO7)!581m~jR4U9q(tIr4e%!GQfb@s)JvI|6*N%SUm)}BKskBr{oDgdo(DyU-nK7C#>n#piu z!MqL-asFHGzB;gnWz`u>LdfMa4^HNWCxYMEg`JingTlIKTDMA;25MdbZRvou83mI?MT?5F@W@=GCK!YkY;5f9|aNG?%(*=%5dCA-`s>Nxr{Y zK=%&7Hr`nL5of$cXR#o^9v+1M_w|+Jcc}Z$(qiC&Hb_RK-lq*n_WWwt^ZVTSpAnu0 zSPt~aurU-2`E~x+ingTr{BRf;8X{Vk78$d^rjofKsU>Z2%lV)CML(~Au-+Ufngcu# zna_j4XU@wsz2XTOH8u}d>mit60A(|zr0M~8A!yX|<4aEB>-kRMJm@0utM(z(8|*~) zQVS*^%^*%@kRP=kPPH^$n}=qx320TUZ5Q7>mIs9vJJ$2n=?|@p5>~NPM-I)<=A>c0 zm&IZ%7Vq_Um*Ot0Q@rqp=IfYr|Kc=+y#NT9Vwcd_s3D;g5uzN|;>x2rXHxW~s`MFH zI*tbcUKu1-x%0fxF1m`KX^l9hiBY2QMXav?=umv3FMk@C8!i&GpkK@Y`ICml(}q9% z&FZU+6Y1Hxfg1U`<>7FN&HTN;aXZXY;axm)@{~%SuO-=QYac---_wrlrBXqVaq)7% z@)2D;buw*?U137^veKYV)a#kH5oGi|?dW{4w^1H=2RoH{+7&^ti0zN& zhY@`|&BZsGeFVE=PbQaJ2*`P`Jgnw` zkngm1?j-Mp#mgsqe=<&9;0GM2sdOzd;VB#(oO96!2OgLVD5Jwl!w=+aLA!d%`aeBB z4-KDt3}o`mRCV`rpVkFHeT9%YGoFq#3vl7@C(F3$05*#d``VJA`!pjS^Y9BV6J0KJGb`f_t?#|>tw8|fc0ueb zfR65BKh7Dyyo--{x=H`=%_%Bi|Ej{jR8uU)+#716BWLjlVv{LIfBbkS(Jz8qT(_co zn?7bU8<^gF(G#ak6}M!2sJIG-x87f(E7Egu=hkBr>(*qV5}&#>7T?%d@>6`A+%P7E zn2>oIpl5&>fWcgAy$nb`;Rv4fV}|Rdp5^?IoCe4g;j1j7%&vJFuzd9qG<+8|O~W@0 zJESRor{m(GOfJUH536CR2?&}I>z+>Eh$ePOVJdYOV%Z!4(HEp{W%;NPjnX98AvtI< zX`XsioobGfl53=zBWQ*!hI#(QiUaq#=1-g&!AEu=sv=4Njp5ztYJns=dl&ufPcKJ+ zdc);qSoL(V{!6yZ``|XHs}Xqqv$tPk@iW&B_P(csbNt`JB!3OU$w#zP$|Y&WV<`p6 z%8NDEqzN~m0EP^~xO#U7l<%OAWnJWT(4o=K7&l#b#%+A3#lL`=XZ^`DV~X;l53+7X z_}%BVF5o%!K}=^K{tSK$ZsS=EJcOB1Hrx0*l(*)bP+1_xp^a~rvk%t?0jO`S`yft~ z3-h^q)=|aLWFDl8XAOM~HKV|;Kq4QsbL|3iUV1q<4nq+HiAia6X$h1wPj#O1^Ui$h z9iCCwIHThN1n}al!93&ks_Tr)-mwCoI%=h@sr}O!GhD+!2-KUPaIk?-o86KJu{yq5{A;dFmA~B1hfJM1(Rk`gxL+uaUQSN-j{Qjd^f=#WLn`*V%x<}12EY-F~GFGoVW zyhpSef^(n*ef_EokH}l^<7m)gyZxqbQ_S6sFP|g~?|v%H8WYr|2h!T*4rzIxe|*mh zIQfcrVjd`t4hDT-%YJIxzEr>cU1R0)M&)PTfe$-EKFrI0;DyX{4t$V!WQeFAz8v^q zMVsAr@Ss_gbGzs32dA!qrrb0E4DWM+m~?*e&4kd2!gDc3SmJwxDinuF?p!gOIi4Q?Zi{KD@7OKb8S#Hun2LT z_|avmxEcZ2`adByf&%amH##Im!g#490{rq-+-3n!G4Z@Cq2L8y)99ml{#%)f(oT&t z@#v8=+W=dUSLVy8wsdd+An!IP22dkbWP$nyM6ZYoLeSjlUMB>Aix^@`h8o~4l-@8L z^^0R!p8EI)pY@C16m_d0LteJWzDHPmdwt-;yr;pK>?=z5mclI6@)NrA)Ti|;YVfZw z*6u$Y%rfAhwF_6izFbi|xm{FoUvooN`_%#M_4~TlLUaY-Z~Y-!v=D=wA)RY0>iq64 zzqh^dF1DIo(Ym(%-RylG2lQL4hlbIx6X&bz92D%rmpaG;u++6U5EMm-{m}4N3t!ae z5d{S!-*_F71{&(6B_2k@UOCjBM^UY^1eNybMg(B0ID*up|Q*FqfM53h=c< zQ%ozD*KRxI7E9Q=NxET(K9|#eS7A9$WFm{okk(8?oy>4U%NnIqU z%u9x?SzwHqfFpj_gkCpK$|as2vc`MqC$(zfA(lcP<;Cx2wcj<9aveF=d;icJr#!pZ zNZSRP+u-E`9y|NeUMsxF8Tzse7N53x>*Y>)o}BvZ+0f2g&3pyuyEhSI;JIR#zOx4! zek47wIq>fb_rbXSs_1NoX#|?tj!bH#0!1O!j4nqp*$7|h) zHEzp%W(f`B|Fma+P&$J$IL9#bM&KOBfXq*>2pVWEb;|%vx8t#^zBf|Urv(8Rh(4VO z2doe7P)7OadXJeeLR^w|8lT&71-r*>%@3f{)O}cHZ)scOqbxW1PFO0C35X>g5RW$U zUTZt6>hN3t@pDxUyNkU_we9<+yl`!g`Xk?4q)Pu_>L&uiA51?>oe;*1?VUzlzR1o~i$j z<7YP;W*cUi%WQ6u+gu}~jUo5Bri8gyREP-Gmb=_jA;~RN2q~9Jn>z`i(tWP^7IH00 z>*x3Xd7M8!pU*kx^Lf8t&*y<$lfQc7j7wt73#rns2wy_3_^*TchKD7iQzlAW8VqhW z9cp4UtQCI+*O(bML&|!o2Al-)G1i5nAaXazL)rX5v-wsxwd8&$xKjFeKCMc}-1zAT zI1+TW17UU1rz?guVcZ!MTVdrD6Q&NfNLHG1~l z-J%-V(W4;0=!}-|A2=bC+{Qoi5k=|1N7_Z#=x|$l)Q2=%`c?W+ilt;?n>oVkLSoCu zst}zgx5A##Hz0$TKh)a;O~-IyO^?5n5!BRLl_DT}#Xxa|JrXfD4$cBJY=2BygVP4c zEZ({Ra}=onjsM$KBtRX%h%avLI!FhbA-~?i_vj!2XtRJp*uYtx@F3?DqnX%=&!bPq zPP7=uDTwZOf+o1M7CqkH0&{MNiJDBTn+KXhpHa*aiYs?sHAkJh&?8?_&zQ4;e9!&9pY&GAGA$lUxUiOo1Z?x)-+- zlt@bti*~5Ei9SXBGhAR35gx zlRG$)ED}ec#Qrde{pp8@Io8$`uq)Tlqmy~~j;<2H54{&|uJAg3&DZ&!Dty#A*$9Hx z*h{vU#=(RmQCJUSz!rULNr&#^Y#2S)%yVqV;v0Y8=qp>m!LYHIB( zp<|n1T{z%4w>U2J2$N;XQtK*(e`RaHnf0w;11B=nj3v@pm{J50@bD)*U$Jo>P+B^w z&<4biuMDWFPJb;)J23u&@R9%fN=al^%$VV1uj07fBtWH#$1j{8*45a4H}+8D;YP~K zxFA6$AV0FWuAhVv;(^2Yc`n3@JKOhljlS&k$z57#t8mo&dkjIc*jNjFH9U=dW#eG+ zag5+@N?&($vHvSx2J%Cslo-`ztdH*(eY7@csH?a>;o3)`mOuPG7%<|&7be3_uklIq zAn+R%Wh)uL!;(Dd&Iu;C{~S`h9o0UWQxsRS-Ebv-#i`QF^YJP6>xkvHz{jR*ZC^8l z?uP$(B=f$tJbjkV-770^FdI}79As?nv`^GwtKLvj2w+QxJnrKR+O&`>>5`cbFRTt4-UN0+!8rOiLnl-#RVleIB(l4%y6CjcAYZyo#b+LJHR{Rggu&@+dMCe9vTQJi zpQ5=6s>ce_avd+q#}y+tn$)Km9d%)THKxf@_eMwpOAoU_sYgoBTkfn5Xnol^k#A%c zx7haO^M$3U2OY`VY{MCR(9p=iOFM5<5AwGkd_DNRZ3KRebDNJbG!0Zy5dL(9CRz{Y zY`!L51l4k-uIExkg2-Z%kjpzNF(%t-4Y6{OUxY4~(bnEUG@cuc;r-T$r!$zqZq?P) zRhxzP;0kdXhJh?B%H-M;c9B!thqUa$j9hu0_9OV6=Hd5 zNj}cN&A3)`nyyEe&l@rej+r4$Bm9NuxoCG8MR9~}3U8&r%49h=`@+VI+@_>3!NW#> z62u|3lAbkFW^_bO%qnCj0P;gKMr>eF2r2tMLt{!@gUCX@_inv4Zm9nqb zxynA_qEsy@<1*}=pOi7As+l(6=02u7az6jykSN5;FSy_aUP;yV9XOnlLa4JtDyyBa z=Gx^FUU&dHw&#bw>xqHR9kMblvabJ%P%hf?5H|6CoGcVd#LszHBKM8LP8W2E?vS zAX9_~3yr{9d2T1&wes8Nvib@iOZA85hgU`;24oW}dHB`XZ-=?RCoTtcZk!N zM@Q!m09$?@Q$^_N-!lh)VX{d0a#^d>Df+@I*)BJQ-c}Dvn5TJg^hI=TFH4T+T%`d) zyC8qNkb%RAHY@e{uYy733bqwdK+l7lAo+0$KY^iVNs&yKOla}ttpvrA#ti*#4!k9% zSHrYbU{%R4t~&J;?qm+kk1~UOZ=1NqpJqJsBqxOCLV9%eX+O8={)yB!?2I_YHW@R8 z$RZMw?{K8OSF>(Bom0|s_ZQ!dL8EJamG%NsXIXC*>2^jjmgQOb1;^KBKa7fctSshtwhoAsQ6>zZ*w>+!ovXgRb zzfty~)?GAw)xkWn=(AMq%(c~#>8b#H`w4>!}VlMK;$B$%i>5(mb~lPE0H3l zurItmjbjrjL7k)NoGF$>J%6RxMP?TJL1s0z6~X>0dV`h>M((U@?Xoy;I; zB3Q9H=iUJhOD*imUURDhZK{tdD1pLAAec(oQwR?SOD^c9`PG<5x)5+Ziu>vOdp_x_<`~R73mZO2Ud3W4Ll6`p<;eK(<6(Qem1gWEdzQ8;P8bE8xC#POoE7L?BD-(G( zc~zD#4qw6e6Q&M<0KYKBP!XcIaq!pypzy-dnSa>{ia+qzeJ|KcUmfQqzm!$9ExFYH z-ss_Dmm7Iz8Y;6f@xdi&Y)tn?HkK3UE zfpu~lWpcw1a(|E3zA6DdyXB&n{Bujz$}Bu@>aVFe7&h}`M-ygcE?1-~V?gYeJo9c; zm|=PfI7yZ9hB-NerbGQT5Ho~9z_@fu-a7|TyntoSVEY$@GKfG?nlx^xxZ^ZvRH%6{_HWOkg0HjhSnyeOA{29(v8>0D{=LF+IC z`5IK9|E{1x+89_kMo=4rw|qLykzomGbiB|Xr2~ewXySv^_8ho=+IMIddD`MRj}J<> zJh3`efp;(675D9)H?b;YboNF!P4j9mLUoV_?1CkciwIy^1j9N9FLMs?sp>G>1 z_*>}(5#Jo;N#1mY4-NKL`Smx_Q{^0{%w^2_?dDe0U;38p!V4LM`fdY

lkTmlphDm;y!() zRW$U?6!INYvDBXqugdKhdSQ$qiuEUa8(v;$9oDT;xMw$m-v>P9Bh3~g_f`8%$)!7h zAE5U4o&ci#)7w=TocqQo$3@dRfvU3o=OD^=x)%Ed4d0X@k5x+kK>x#KFE{w}2dT_? zHuSBA#v)A|D=z|41OzIn1S;@`N-lU1Sh?r>TdZN zXp}4dc#wOPs>@>&4$L@J&g?x1S*ch2BtO+xEB2uCyUMB-pv>G|jFW>E6J`|)-A!^; zh>g66MfD2bF=y=K0CKwcQeHi!eN>JyVwCoZuXt9-c*D^V$Hc`r8@JSd%R;HFg2bP! z;LQL=>C2pxyW@-03GxT+BYomuKDKY9i84iGX~_8jfHPGlZ;onsc2hAyC;|#zQ1_lk z09y}an*czQCAG$WNez%6f&rskz&4>(v*J!9= zDmb8D8}1eZ5cp~?CoQxJ?m3I|leFwAWL11QAH^SZzoc$LDHL|z3YX9xwlr#%mPeCZ z1P~o5lBcH-sZ5d6B>ZmqFNP(SN5YQ+qfnarc@BJ;C7DMOW$_Snwq$4-l2wXKWJ}UP z?hMVle=M!u5DZjVQk+!Q4dU(eTT}BW}BuMBb6QM`Dpt zxDq`dRX>q1hp!vgFqG?0!vzHz1e|!|f5KhzH!;x3J<#63 zuTR3)geJ*9U=XnXu|MqbVcqMJ*GZzs_5Jod4tD%`;sOuBDizaoKOXY)c*;-z6X#kf zWhY2KtKB6Gi@Oi=+0tMv;yp-?KD81vD|eC@vB8mzJq-*Koqm^Yu8|6y1Fi(10kNs> z&)W9H#x3$@p&4Rj zx$+8Kb~o;b13;)VAh#rEu@L>o{@@|@bH*a>q5Xcn zz`yN^hGLhU+bfopyQp|G9Sn6s89DfSM82M0-|^~I^WjcCP$OpX{3HLxT4x}Y<%MwL zujSvk5Y+%@D|{-MlGvjrKT$5*N|Jd)gt>EYtt5O55jM!fcXGv@i7*|KOy`u~J)+e) zwj_lJneCkvirs-Ho z40u?ZErbCPew`+B+7}jUC^IyLG91L!f<_C7h#^v#0TU`eCEZzuG$<9wuX2cbq{97B4z5N}}P&{yAAJ$ydcv-Sx`TSCZ z-MQ)$pWYAGpFUY?-_jF0Dl^?9|J3GOb?RN6yLv_Y#0W3)`{`J@G^gw={oO!i{or0j(WLep zX(X~0yty?!8d z*C`x@rYgqXH^vgI2QYq9xB_E7s-|3ZklAvCi#jLY?rWx)=NUTJ-XUR4@5Xd&bf+uT z8EbN6CMySIl(f%{+E)oO{uD?j-p#6x&Me7b9BHCVo}N_q8vxH>@E?6~ED5lG(^B_D zgg@uGB>r!?tmYr(x)_cCllCF;j@F~+(@JCk<9lS)Pda5sM|qis)0%0;70Hz5=Fl9rtEx(~pM@_T`989c%(X$~?S45TvLX&9+dSx~Xk`oLu8x2_YG4C;QLDRu& zxe{&la;>X`L;Sf~@TYspHjM&I*dWNw0-~&&E8)5JW5vi&*=y9({C>JRph?d#hy16v zs){ym{x^d|4HX=^5FPih2g8JxfC#*@=jGp=fCt|SbPkqffCHb(v{M0ovgVT&WGX$` zn{ny~Xamf$S|-7`<#qtypMwSW*5k z&)+tZdrzXqEV-TweCu#{73^!fFMR*LQ3|RH3QL$A@-2LQS(3h2j84P;=Ao83;&hVO zA`c}-`;IRAu1dpFxTp+{PzF^TJB3;#iuRjg=zDjs5ntq>z-8aW%f6FnSi>n4-Ripn zdr5+Z9e#~i=AAW538#R>=wH8!SARF*ip$d?m%XuT2|Vpf){hl25jQ%9J;qQh^8-8c zugy(1#DRaydpALZEng|IYuxHrD2nRb`dRQl)Jk{W+6L|U&UE+Qy7*J0gduV9+-1XG z;ttPkBn})LyPONU^2#@L&MoJanzYF;HEXaFK~_;&gEIAtRbl2rlv(5QsQ@p-{fy;~ z84yOaN+;ov^5QJWOPQ<4zn#YroY>cQ29E?7h=HVWiMv%)pym8Jfb0+dQKA9@96otk zDRPp-e${9nySnoEd8UkU><&VwvOibRwuq9pHrp%+1_LpI;y_n{USMbFe|Kd&E^e>= z*VUKpV;XOo@N?p=t`Fnl@5}X1#F;_%Mb3Amki0y}SC?!rDEGi4PcY&ST~pq9_1^Nx``|?y0aAqj}q*7(dPlD8EqR)V!YKJ$5VhhulI6i1kiQ6#@@yheKbno|_ zZ|i$l5_9}dM~OVtV>L@8vcET*zykF7sxla!Ye$qLG=ul^N8v|Z)elcDp$~S%XZ@-Y zp<<%``~-N7zyFQgzJws|$~nIeJ;XX6{HvJnd}#IRjmsuekP$s;gS%)ODTd4 zNLnubTB)gW$?<9L?X4NK>93)O$;tfiEuUmBL}QKtx}?Ul~R zNi&?LG|~`L@erX?tV9I|BB_#-Za9Py1!E@S#clZ|X^G;)c!g$ShGF+a0~bG$Uy&wy zSX~UYpE`@*r!5^C2H!vZQPd3iF!3r9EsX))RgsPf8;oyX9t?Rv`cy&4I`hav{h~Mm z;&@$k?b@8T{U-@U29sNX@XrvvqG1OMO35~1>KDv;Oi!CT9%QnkM#4e@Y{wswy>8CP z9Y&S`>emPdAeeLQr5_h`AZnL?yRG>{jpb9 z1_nu(ce+}iXpW}QKm&{XEAgt?(8fn`{tM5-t-+|b-qjm+zFH)K2D>e#JoSS=Co2p> zPiZ|e`0%UMB>MWlf~yd4pkt56F~npe>H|MjV&XkMFks6$>JMb*^AFU`N;|7#BGMm{ zo_lS*r=18GF$tN`bvzIlV0-TB2VWI&e@Z^Y)9kvx>96lm4>Ly&ErqSWlv1r_+8XX6 zfM)ox*gP|#YhmIJIMqZzM8ES`c#=e`T%MWmz4(eD(fv86MT z4}m8hyRp{%Ddd0RW?8N|grAIFkX=l{x&OX;L5w*NVp(o{XyxTSL#08B+J+*hgA7TH zR!Uo4Lg_t3K!Mz6lDL}^Wpmis)KO+G2cVB4&SV9zt+{7V&oXR;wf=nnu zEfsH30%0#4nL%oDCn=vVW8&2n0r?O(M$s%cc%>RCc)kpLP|#+(@`X&Lo|Vy|^MlU! zn)2`J1+Hn5FALf6z|BuN>S_#IPj}$P!(t_k3+LIM%@Nn`ht82-u!mf(cfp?z1!@GI zcyZhTxG`2cr*1*B0dCiKk3eN=p3Ebev~$NM)~2* zYNXp91IBRtPv_$44JFNJ0Wn9(M2QRqd!be?+Lrt&+P>Nv8e!fpfdtJ&vx ztKf-(BHJv^HM-%ONSnzU4cmO>mOTZbKPtj8_Zk>tpax1o+KWE4}DInKUz{#fA#h6d+6u*Y(mR-&fbflM~&mE#G%aaXfIg12$ps(-8=Hq`ozPVUu3Eh zD=X0Hxz;JA^fx<)UJpCJ`} z77PCIamEN#{=Gss;Bcqn8;yMC&6{c>Uw>4+I7PQc=wC(>EZ2Y4JEiHzd;~MHC(ZT3 zE>OKn8o^KsNOl90bc{~RKEJ}Ge)oXuL7BkyqrO58%@)R;P7vq>Yw|Ib1z>l{{>U=s zXenIJj0K=ZgD_i8FcY3=0*pd@H^9l3MU2e}O@av@JwVZKUZLEHOg^Z@;~_WYUfVLi zLg!Eqv%}BVqh*55 z$i#1y#-Hti$|_!}?fUZh95dle{_z4CCU}qqXE6Rd4JAvZ5 zBm>hLZ@xr=aV}aHk!*cD@oIQ{!>W54=lD?%3BCs+@o=jg7=Ye%F(w-(&_xppa0&lb zlnQY86*7AFD-(JgLreA11?_SBDta$xZ}o~uc@v1bYx^S$Yhb|9%)PZupl9a#Bp&1o z5p|CY8NDhr)gVA(Ku+c%cXf~<9FdQu2oeTdi$P70_t6`WrC~6i1`wM?xw8Q3#-QHi z?6o4AMu>q+$X5azKt@1DCvYWtMdZsUO6^dlmkUn0e9w(C;$%(uAOi#^CmlfSsb0r5 z_R9IWWp#pqMxMseh|CMG_SmtpeZPpiNzL_Aq%bUM?vSLUbNJtwkU5X6-=f0&(V&eO z>`DwimX^>(l6uIC1fTb?*5My^(pUcj6GxOH&(X9oV?nC&7R)>>Mn@*WTzeS^moPdE zO1tRMdQr9!l@kG%ZrDv6iiC=RI~7nRWR-qNlp_YL0H_YEWK1%g>^R`27?m{e-bON* zw4yS_*d2wdU&W#KUkgt&1dq!L#Z5yJz$(KYX*zhYMwswa1JcJ@?Om9V<9X_9#Eo?} zS--}ezAFA-n6*$9T|77mEWQVXfh;l62fFfR-g7AWgx;RuZ6=D|z`T7T+;y)QGu+QL8vQYh zM9o3*fy)p+BTP34vyy}UsSN~j&{Y@{Oc;576bxzrAMh1E!}b1^qib^xJxYWg9u=4j zL+3LwjpY6AIAFG14}yW~RVs9H(9>iv>qJ~56XPjr4dWHuVdpauC(GpDNoe}%%mEiBb>hWRd>}dC z2^LX6HQUv zLAxSB2cb$UDzdXw$WjUszOTw^cTSE9ScM66GlfgSc5fuSVO^ujCetq0C^lhpXy}m~ zsnk_h_au_OU$DWHYX%z_@>eR%#iPvS=gs6%V_57%lz)J`eN%9Dkh?QC%b2TvtEk4# zS95Q<`a3RqWfUe=&b%j;7_nJ!nhoSr(LpM>^Nooj5qr{%@``+M>p2MF(*3yqj>{#d z%J`zeFrZ9Z3d)q)XkkR>Xr3&)D9FXAV(=>`fD%6#nGD22)r-$V1w{`5E3Etb0cF6X zg(G<(2NS#^hAoqY)3nPQWcizMU<~*pCqTeSz=Ug_B*br2BHiOn-#tBp{%QMad zUqkrkLx@s9G{#r694lemxUG6m@&I}~3?vmN*^wTRpi-t8F7)|ulTrx&eF`3V7cEeT zzQ$`htbKt3zx&7cA|wo|J0t5k9pn-5u)R9&9SuF50~_00ad)4%K|8*LBS+DZlHZ5g zE@c21xbK=?J)0KM2tLjg5?~9Ac7Xtn6XhWQABBA;IRjzB7(<{LgxnVeurbQyYa)D1 z1L3#}K)n1P6?#?_wLuj*!?n&8ZM^nJ?H@}CSA;*hsf}hS#0ij58@FQvl5@k$QjN6C z%WJTS`gg<4!M|^VN`>ymm2DL!nq7W)kWa%6V49U%ZrD!9;m-?iF_mb3^1i=2M(}pvk+jigZLi_GcIVNkqo1S&Z@@b8!w{q6 z&_b%<7iqzwoQ@gKj+9aOb2r#w4m6B+flv`0g1qn)B>)+>sGC!4Ef) z*VVXkq-^UuXdYa89S~s`959wFazm859%|k-uBz#ndnRQH$>TgPXYMfJLIRz!X-T@f z`wY(KIV?3Dgzp1^afK{CtP=najT8t zqznK@$eD#03EvI0S{NW)Dmua<@dnXej{#;7N|gm@Gj&dRT8W1aI3>oJuyN~*n{Oks zW(pL=@k)$xMF7Zx5Rqq(?JwL(x^cb0LtgV|n4j3Y?C2y?<2?&P301km6>&3D}w8H=mYUuBDAU!8^W@)xC2S*fV~!;(c;I?Qfp$TG513>dX9+oZ zksBRx!CC^`0A9!V9)*z}>__HVSoTz+O;A?lIr7F_X~^U~LSN{Rym=0~-NEaxoB%-8H*{45Ys8?AnZ9Z&^V{M8dSGsGU-00SrRhV^^Vw_Q-{tU-bj;F6L6yjYz^@K;#4z zzSkT5OoKazf!m*kJA9tC?+^$dg?AH$4rk3Bsh{&4p7ZcN%8zEkL&D(UgN~m8GhUcmog6H0T4JRIT zAP!+?oA5mMp(t-9n}mFc%(-nRz+_uGVT6dLb>G*_kx%8$t)$^xJCA@_%y(nLa%j#%=BE3Z&(glA zCFGN;hcE6F({a)29%p_ApZRI?wSka->A=_HPCDxDD(xy;j>-v z00fpaY2GziX|eVLzi*BFF8;DzdTIMMU+(vufeX^)JEyqUK{78AGZM?U%2#!{zP9=O7`;F{aJcfw_`H3w zQPgsVp$NyZ^dNi(Dwg&6*`;-Ya%jPbZ^wCuTc7=H^iP^rI(&@+k+C(bQXddYMEbhA z2XU#=;Tc>)?M;pQ+fIw$+26+X`Tj4KMWl8Qix0fn0@Q{ef?17qqjII^+j{@%Y?0}N zl+&=O=YC1x72%jOJODuLc=?ZPjQ4EGm^c3#X?|Aw%ey7n-tF;HdsX1g;etG#c1eHQF*p70691KmIWdu2}gK{kaRza#V8|KCWw z=>?I0jlsv!KD)jac=78eUqV>JiD0#c+w$yFs=uVx_L^>r9eeQX;@W?3xrCiEa@o`N zafc_P0+K}5-*&OkTJ$EkF*%YjSk2v%$r~{f`cs%=mb`N0_|uK8HnB~3L%anxcUI}Z|w}Hv44&H(4-AQ&5zGAyJrFaFY?E3zrj!3RQBOf zh5o<28z=kgFUxOKli;naLM6GVREPZvw_e=+C7+oiXIS_SU{jw6>DL_GhDIG8zPQFF zJRx|7?IT~&|LGBM)$MxK;sIG9Dxir;xxL{YpDl-9^?fLJvHjZM)74hDGZwKW)>Gza zi1bM>d8>`EhtWniSyFLA&Y6@86Vi?^!=CiGcL=^-Poc=JAAQ^BVDk5F-)Q3RoF^c^ zGWTbQt{%}3g702jf6C&k8vG!|zAEWY-iJ^rz3O%_e?lp=&a7?m0h{pS6UKq~H8cKTsrbIbOC zj=RDmjoXHXn?|~T{j$*e4zpco1`3|)BTO(tYTVq`=i)wwFF6HWet9w8^IH=_4^M6v zon#est*!Q1uV4JI9WkW)HohvjWGS*)^G&0pN&2nw9J8>%j4)4`FZnCCqe>W0rta-I zy=S@hxl|ic@4h`+Za@2L>t^Un@$ATplb-5bNw+gwT)L}K&QwhH3j9p0vLd=~>Df!C zr+TVMQDzr-+EzdLAIBfudXNZ7IwwMrxJBuB`Mu>I|K`%_-E$zE-= zrn^-7Ma7#bVtP7dC(J(m{McQWo@VQ_XZ%g;GM5lv3j#q5IT(p5gO@A84DL!_ce|VR z1z2rHwCmA>JgDWpnt4Jv)2FU=rut=~&1Gfb6ccs2#_2m>uY^a)K8{7032D@LFCFK0 zQg>}JiuLAv_ZL##yT^dj$d{%ocm347wrz$BQ{DBC!%s(S&}7%_DXsbGS^Ii2g_)Mr zC*Q^|fdlR*o(}|x7hFe2)o|LntxwFXUOzv1wl}_bO8o=-`k>hcMU12w+o;li@7%%z z2``;n!vSvQH4$*==*h!B#GFY71@DQa1p(3IzI~?xj64KfOK&DvrULnu=SC~Cz>0F2 z?GmQeppk5p>}1S*cnU1E+A-jFP#vAFLXyqXm0p-LSK45lVmt0rh*bV>Xk6potcA;I znOD^Y-JNB--5HosNsRYV4&?XuqhU>z9k{jZ;Ly^{rH5`+^}V;fKdqsw344F>^~TS~`lieUt~H0IeAFI1NVd)h{F>yDnYlB?PQ zUwzZ^4n1v^r`1f$S>0sO6Zev_Ec6h``uS#9-uC4Qr6*DDhNM}-k_rU;(Gr(`=Sra3 z_z(p`mgb$~J(+zCA`&H6j@uu5dZ#P$`UVF=Il3kT&Q=Hz3i*DO zUo@z499K#qN}9p;f%kYE2v?f4&py$QH=Ln#RXN6*Uh#bjEzJn8L)B?oe6C!`XR`04 z5a!8^hHkZT&stB#-W*uaQ)xc>Px;7z(fM87%lQvM4{_I77;a|ab%*RYCsRyz`{|@31XWS z89zm<2QE5AU2@f{iz-OUy)$_vDddLVS5JARg#_!rrTE4Z=R*DNJ4E#bq4`a1N`$Ac z6_U=vBBtX%b(D>s0)k7e?j1GxzWZ3bNq0B6bvbYPuMV{MA;Pfdq06sZgyi z{NVcq7uK@ijlt_@c4w3KDG$D1nK)vmT&&gJZeHH|?ZIgcz3GkB_gw?uY?Hqso(O$4 z^buerTogJss}LQ~_#X)!8vve?4K`w!jUxSKJm+nHrpZi9WiP6xn!cQGTeDMXV{bmq znv8%e@*^sTn?;^$W|UsNw%pkR>IXonNtB=Ao3Y2dzW*Nmeg9YPW_`-D?+))$To7$u zclMfmyT$%JT`*idl);oT+h4Ypcrkha5A_rP`RiKpBC9G)R_x)CV|<0l`=Cg!tZwkr zOLw(FXVrUEH~ZmpYCh-}E**ri;`lkO2j|y!GuWa*l3mcud0YSYouAdIpo~{2+O*}* zp55SRo!@56qQ3}?x7%31bOIwm>;S|rwoh*Zo-r5Qihk^T-TQp|MM%#+#F0My#G@0K z+;_h?TF+LDWQFhOdGB~WOVRbFrtYuw`TITi(w|TN`1|Qp{(AMLze|@c?O1VO*GDb> z{rz_dKvF?aj?cn#pPb7(wp7^DgX*k<@ObL4I5w=91B(X*OCChZ)SM)OP|W~(0zmIj zMF1{FhK5n(iZ%n{u3YRa2Zf|bX3+4(G|5mJ3JGzQc!tV zX-LBb>?%fSxWumg#a$BWTthvYdUvP6Q*$*v8WKp5`AC!9;mTs^By~ESLMQFeEc3z2 z-R6fVG|Ft(p&c`$r`<-~bo&WFjM*i%V`d%N#Ym((6?Ze5S-N)SZpG#LAL)mO=pM~o z`**QX~ScT!5O{(akq3=o2)idN;wY(<;==mQKSDb(+Ro1Xp(1>-8MX?+Ga8 z+R%I4hAjWIrMSEHdhGPtW|)iek$qv!oe}DN4zt~RCZWDEmeKK6Oc|I}Mvrl~g?+b$ zBh>0bzIkl7)tO2Qhas!@_)b;;*LA`&@u|$|k9`-Kt%92S*c;t(@%<*VbSXsAxkRf> znO>T!S#V^3Dy1(cpg%3c@+ieRP2Kvc3^$U}pBO)IbE=n39|&$XKhivqSKE7uPP6W2 zY4rDJB5i#1EQ|9G1vXm;%?=b{59JN@T~h3;z#gj9quoffzE8iN1RXdV-(PXerf$fh zq_#J_n?(l9$|$zx`Bo~6Hg$H^)wLF3GS;j}i`3b{a;)`%(1H6OZEHh&3iAhVRSvWl z4@3mK2+y~{Hb9$?+3{(vFK%sER&~?w6x&u{t!v_YDU}03&;b|9(7jpP(dN9`44YI% zD^`Hbo#LMUW88e1{-{NZ-ibqUk=kLvF?`}p!^?aRA~wokgPQzp#Oio1Ax(j?`@yT$GRDY}bV$$dt~};ougF%UCM{wIm-2@jW*r&Gp+LIh{KoL- zV#~93gMaPpkA#l=s$~@A3~VDuJh8(AG6S2lqo^L%0bme_>RW<3jz`-3T^x-KuuXsJ z*jU^BGXB+*X1=X;B}4e76K~~(OFlzm=au6`=iqD~Sj5qe4x+POip}*Ciu<6lJ=`G+ z$X{ENk9Na5_Pk0u3HHJy(Lv_5ldSB^xs2fxi^J;^BfO!PEp$h*QqZ|$&hKPk<;Pyt z(Z{Wk!+Rub7mA(nOHQh=u^+`g2zqGHk8l{f*1jZoaUG^GilI)QP@I8@0Q_h|e_=x~s_IXV&o$eP)1 z_V~G)t z~KeO%IR8Lgo%6P zr#FsDum2z&*r=#$}dG}V4r$}=l|v4j2V3CpOrP9iU2B;If*SebK^_q!Py_Kw4@ z?rn)StiSfi-A!c<_`2*{Z?E@O789O&Zr`3d59aqe*E(OLj7QBm59}N%O|s5@Yn-uWy z@OpE~>+J=v$xN?zx4hm*eR9tcIMwg<>66#zC9f}ky*`@=_}6$%Yk1F?c+c8CNbYFFe{0uU6G+gkccqfSFTDP>)j-tm8M?kt1-Y69KKBw@Y{RQPbJGwwPadL I5CItf58ZxuZU6uP literal 0 HcmV?d00001 diff --git a/src/drivers/dave2d/docs/files/doc/images/trifan.gif b/src/drivers/dave2d/docs/files/doc/images/trifan.gif new file mode 100644 index 0000000000000000000000000000000000000000..adf447ec2de32f2ce6bb2de262e6029974e28057 GIT binary patch literal 582 zcmV-M0=fN1Nk%w1VUz%Q0Du4h|Ns90001li0001#0C@la0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?h6Dmd<68J*oOYj_>bVVY(gN-*NYjAMU}3(OuA&$s8o5h!m2l@ z_6rV+$K z2zbm%Y=Jzg%ruRuaaw(pZH?i&&GO7_IGYx3OpgAO*ZTe0eGSC3*}hy6ZDop={=Otl zuUd`XzGjRl1dKN>lR*#yi(T6$P2m2Br2R*q~%Dk(D~KL*imuDb*C*DFH+D`6Wd$)>Y~JfRg8YII&xdqh!o2|4wc zRiId7TH2bimREMX`q1Qtw5-{zPxs~-w`$uivRi|0-MjTP>D}9FnI^#M?oRqk zxYI9rh!eXl1=%sapOX7kzKl7u=FOZtd;VOxG3Ym=w_quK1@#cssaZR5y&AUc*|clh zzKuJ#?%lk5`~D3)xbWe`iyQCak}uPC5x4TO|iintpPXC!l8i1(+X#+j;fhe7lL} US#rlsNMVH*UWj3aI1~T?J4F5|D*ylh literal 0 HcmV?d00001 diff --git a/src/drivers/dave2d/docs/files/doc/images/trilist.gif b/src/drivers/dave2d/docs/files/doc/images/trilist.gif new file mode 100644 index 0000000000000000000000000000000000000000..2a47f4f610a3ab9074602e7665148f1dd41e0af7 GIT binary patch literal 568 zcmV-80>}MFNk%w1VUz%Q0Du4h|Ns90001li0001#0C@la0{?`MsmtvTqnxzbi?iOm z`wxcVNS5Y_rs~SJ?hD8AOxN~}=laeo!5`=eL&2fZQ#>j)z~u62aYCmM=@3Y5B(1$| zmVu>mzhuC;EGC^lKlEYEgvWz&W&J`Yh7I>?lW2z2w$SGm#ka8sW~lZTHCV-HQfLM# zK`BX5=XjXuqKJWMry{!OS(#Ewc$$}r#ER(3q1uH&J8>H;>6Cjpn`zY>aVvboRs2AU zOf$CZpz17h7H!(;21mVWjfTAwb>D9%8lo1|+AGMge#<{ag5&CC+5bOs&9Q$*5Q5_hEZnCR&#lcA(e{fW!! zRjgICZVgny>sPRs#D0}$cI>9KW65d(wiE_7wkzpUC1iIcj*nM4)d-eX&D|L#)ee?s zD=<#36XUXSybf|(!ipzbzKq#tW~Y@m7u}qrGicGCK|3|AgEZ>ZtXsQ&4Li2%*|clh zzKuJ#?%l@xx^>5}8S7#QS(ZlBDh#JK$!#_-0xI(s=wypF4>S~cb;g&6LdW7Id?irV z4k-=g{tp-^I7nEy(TA9*xX9R;Xz1WKvDP6O zxKs&XNwN8d$q^OO>FJZHDGJFzrm+f|x_~tLHR~aJ7kfzS`l{QOQDxi9dn#NZ7VJA* zYKC!!ysYfpjK`{+%xsZ{{QRbU5f{wOR@a$lD_%x!3~_Ev9LX6mitgpNX`k&bxj(sX z%`Y!rzi0v<+#5&`A-sYH_4%WgkKMnB5FaiaCJWrOi~qdZRkR3e;zn#ELni#DDpyL3 zDvN>SbF$<$nb11!no0BBD{)fL0gG7;=P#Fqe8Q}C)FzyorgWyFM-1vRsXe5ATI$pg z)vIu*^6=_aQ&=S+9GNxC@)sg^Qzortn*&duaZN~FnQLe4jk=fM%F*KYZ(uii2M=Xx z*aqLkjM21M+!$72U6b=>1rm8>j>>vClgvys3}};>FN5}cceLu&tXsQ&4Li2%*|clh zzKuJ#?%lk5`~D3)xbWe`i=zRYlwrWoaOstE-31e0K#ZDlnPr+Qqxa8wA(8Pu*v%pN~Jhx~c9Fi!RLnU3k^emsEPurRUdu1LC(JduBM% d9(dL523387P=}Op8g9s8haP?iVi^Sh06P}-EYbh~ literal 0 HcmV?d00001 diff --git a/src/drivers/dave2d/docs/files/doc/images/wedge.png b/src/drivers/dave2d/docs/files/doc/images/wedge.png new file mode 100644 index 0000000000000000000000000000000000000000..46fdee335ad032af37a9a8cde109185967f07c1b GIT binary patch literal 8950 zcmXw9by$>7v_?u&N?MQ-P)b5-DM4C5LO@{wMM_F)Kb96L=>~xXDG}+8UAkL9nq8U& zi6wNAzRU04`_JyoIp=xL%$fPlb7tQ8{6bfql8l864-b!0Q{$Nd9^S1&T>A$JKJGU- zp)Vcxcgw>-T^X-@^xihELumI@=P4duRUG-n8zNkv!&<{Y2M^DO7Y{Ee1P|{FCkooa z!}EHKhxgkG4^I{c!1y7nSzithkIPf@*;6BLi#?c5G+R$yAG(Z5@||P{H&H)-But-! zgy^2r+fOMG6;@WI{L7W?vG=(6Hnrb$tJ8`Pc1pjRLf}6_oF8;i#od!hbR5E5*c=$Z@o;!Qt8j{ZU0>|(D=>J2@oM8F)^R%y zATqyYqU0I?@%Q&X-W+L<4XiM4S~Y;*jNoSz{_86?dXU>HA$k2+mdqsdLCX!>GN4 zE)0n^usgfbQM&L2C;0R1mJn)X@fL{d6%IK2*L2j)bX1I$LV@Al#Cj00e{b+er0x7- zH$G-~XaB~Y9q$a+?}O#}`T3qG#_-a{86^D&qGp5kWB?A? zOBAY4O-p0*13zg}oS|nb#YY|pFPZ-AkTM-Qj)dc5$vlTaw{!fH&gsA(J04MY!vPc& zEns;%2m?@>O7okhrl#MKV)OE?9rJl6i}XK@IU<1DckTrlF4Q|a5`fAnSCFf#T$3!- zsXbIC?KsD@I1tb#!!oi^JMFcCbWR1oFEq9(b^dGv7ljukN__~A;i>xgoSP*mzPl9$ z#5Ni2p-FcxDYp$#!P+c*OU`o|mK`Mh%^F5vC-_60%5WnsFTogLdeQhOpus&cChcEi{rsDx2{p3M>zo5so}*IlDM4@zS7UmoV0` zsC`@~=I#g7lf)rC2+l3DaXVD1D+aBKTi1_jWYQRxfek*~VzyHVJeIX2^sA0KBG7^FCi&2x`V zx$aNkHj3|u#cX@DcPQLJ!|dw4Ov3yJa>WPxU ztTsCaq~O%;vCuvVoAJXr@59pL@_AuoThva&C|nvTyUBJ1)+H>)o6CxH?SatxhVz4j z0?`QVQP5@}@2E?t#AKKZUoa3M>6Wq+HqKMPMT5}JTev66mJOD19&0-9njM~Hl2KyLJkrH4UX}fLD^e{b^GG%){#T_Ow1nL4 zxgRSsfYrF=4f{XIa5d1^P#;Eu!jyv ztq8>PED$03K?tz5e1%LGH97~}#qvXsU7j~YdP`dJ=jEDFVg@;#b3V;s4@)_yhFAD3 z5Z-Pi1xd29nAQ1tC}WYC9#o290xOs9JOID-R#?gy4K{D{LiKD<8=~~TywzAZwyLMZ z5KF7;*Zv|y(KANT2lAZ@lm6qpPmd7L?PLf&>H(%sK`)WNPo#vyYUQbH7Yi@5Q?AWdqdj+tGRoVu3(e#)NAdO79i_*@^MV=WQn3L)iQzw?j5A*^H^A%@SjBXl zU*?>1V7wW(nF@BEV0a4l0v|63VN7iwRB&~_Qfe?!JqJq7*5}LXU3ZNove`%ACYJtQ zyt2uOoo)#3X{S?JC4V{XP$1W)HoJsA=hM?e%N42P9LZb8dY zo3Mypd(r0yJ%_P0%AQdHY`FYY`4yq*qpidbcIg6rd27w38L;A<>!&z=&~S&T_^gKh z9~eOPxMzKfs+GC^T~fhrRwT6SdwqG5lF?|=(6SZ_!ZXg7g08QNj)xJq?v%s#e-#_* zc&#OhA~S+Tl7SYn>d4O7gFCLVQj|)pZPETK(I&hq5Y6g`cHSlOXIuFqhy!KA^Rp3GS;fFiCYmUo4VrZ~5 zoq{6W@Id4vIrwUc^3j9%c@UNo;=C!qlg-AmdBp3&JjMmHx-(X&I2urPt3ff>MvfJx z=!WX4MRuE9kT}@gg*bcPhKH|>q&OE+VvLQA(@F2$-E_Z|51kRy*+pay!Xx|hhC!XP z4wj%t3SYysVRuD*TDfc+XO(829lI=BwneXj&#OA1Qgz1(;n}t$)(GzC4G}TJ4*kQq z{G$dg--#0#;6_O^0&nbdPA^&Yo@qTBg%`7krE7?_I!!`HV+GkglPE`jKxfRxMla!# zE&aItnSGOQ4ofE95;2P8P`$UFbI?vvD;7cZT*9SaE|{t=(n zOb%<$a}_2OdorTIS(P_wCkt?E-aZ2sTeeo8%JcqWq4(sqLLbw|%-4EX2cG&*~y+Y%g9;r_pgk7l{0?uwnX84 z>fZSLFC{L6>(Zp6D)ZHFy>k!Tceja%nk-{Q>8PNhJ4d06&VD$>_RSQ$df{S6wv3Qb zxcwT=P!oM)sEwjekeaOYK&i6k{Qq3oj&^R8mVyQ z?YX}gal$q|{f}STQg%kzf1BNEicR) zLPNn)OMd&KpqjQ_Wac*H%oCDvzX_jF#5VYzysQs)Zp9=9=vCXx~mtR@iCcQk6F0IfRZ4nq9GL~)V3e$2DyWeOnAtmLrmFx7_){}Yj zR$HZLG-Z;C6ftSDbNRwI9qqnYFfGyo`k(css~yjJksg zNzYe!_I(*Fybr>>a}$;-prYIBWs?tQOH~)K@hsafhav^M({^~j4cp)P_s?I2y^%is zl`}B1W6=ROZ}4l!^J9JTE7Z}ObF02O@#&9gP-ZWj>(=otf`ci@g_7g$6AY8}p%#fo zmwzNRY9pid+y&zC{p6(W_Tb-b2b>$?+apzN2Ud?l0M!Ge$C&-jH06}9O$dii5KxD# zqrpTjFSN>&dmH{m*&3I4)JIcqh54+^p>SBuw^~_UhgTP|nkm^wvHa2L_tP4SZ6sD< zBxHYEuP?{T8f@D_?)itoqN%;#=m_Q0V4gL!T?%=yV_M;EtU7dGsDdhm6qe-3PQTh{ zXou!>k#Is2KTHgas9eCSzQ@#x6|bw`cV1LmnW~bhkyZ{#(jATHx|n6ymKr9ds^Q_oUL#v6 zztd$Jv-MAizkj_lb)&wlkc%saoOkvFs~+fjcCqH2D9?T?s7xrtKID;DRg17keRg@5 z_j7L}&5>OCG$i2gPQ#svx&cbnV_{6o(#7W1{p)l=W7jv~Z`*}kLhJ|Ne!G{`4J^_= zehrL#v976T)V;t2y)*ZNK3wgn{@OEX=v|(ooS8u@Ab|^p<+ZGt+|OUkt_G?p9vu?8 znu{dki9keeR`_Sfa<6gKi53$C}l9wTJF5-%^mzN(UHO2pg`_3M?|5}nlREO}c;cv-)J!~foA zs>=JzYWvkt#^6Reb8oNo_)$cJUEc)$Fg_AuwpR5+1krUA@o*kj8$tQ1#o`W=a{Mf^ z13K?C@$(5}&fmvL2}F*W!l`B$)mt}s(e&HAm6MSDt=j6>d6(naz!nzeJ9qSNtlreg zlD`bJ9KM=ROWJmnSchh7uKF2V>ziNs%@_6guB!kst74Tis50&XS~?f%T3u&2PPc8ynOD(gNxp(c;M-fQHwUFd7B0WHiwx%e=vO2*?k@)vn%wbRgfO@?z{KZ>F&l4c6N#qZ-|fwZ;wym zDr^foYyDK8h-fPj2(gYxm-I+T1@shKu-$Zyf8wzpA}ZDc^hQCRM?vc_$q!{t z_T~epsS>b3z&?VP#@jgj=9QT0J4VG#D!*RDI3#vhDTlfPAKx5`jr8KJ3$~ zhkks#8u+2=0+h5yI&nZchwJ=mnWy_>g<@T)?ZZ3BfNNi@$L_Owr-2XyLf*gQYp~LY zjCzt^8Gx1poaYMsWOtoLYrE!k{&Yb3Bh2Hc)12W&WB=MuL!ZUgLKu`&fGsuUM+vlb zyx35>iE_vzMY9y(oxXP;Wc6OuL(D<6cc1jBxt{)r{k1S5gm&t^Nv_j9{$7=rms-xa zeT@2`Vo$FNll}WPa+_1*Y1>QrT4~aWY$6Zs+lr|B z;7YTf=N#bQZPunu8^y7Aol$Rsf35yI{F;p`L@ip;w4U!bH0O26sAe|VnvsEl1T&2- z_LAJql9-<{&c1`?RcsiFth+3rU?9fI4ztQE{m^JI2>2+>-m!~2%q=c1p6`A0qRhI> ziqfZ%OqK*Wg?SL5R#<98k7nQWf%YhpjY=P4GCFm$^JF)qrj_TJ`Jq|2Fih?_zQVpX zKh8MPi6Hl!m0uT5^=u@v{sU44;!}(n)4ar&k=^wDYKR)Q{fr~wJCF%);woCbD!2V% zZ<7R#Q8-~o=|Q=UhT~en>_4FT8@j}jawMSskkC1cR?EH%UhU}A4f-?;HoPvU-1ScV z{kvfC9iX8h<3P50wL?f7rqYe&6%GnyVd;u9 zVK^DOFj9nu<#4o@mFxubx-<566@!SXR?9cb!w$ZdCqR$gLU)ZRyV+=^_+BkH?&uU! zE2+c%^6?tmn!u-=-yOk_@9#a*5BCT7+8(RF?*M6^lMgJ_g~MiLUm7N}{D2105xCAX_JFlBJ}rV($c`e|e^Aen1vC6`GC z$@!PqJml#8QgVPD!P(NC2>69I`&`H2t_6A%bl(p~-6GD-sS50q?r?bJ6wv_5+|^6Xn;M%q7R8 zVx&)E0IkY3Hy>1p4Q*s3)A4>u z&@h`L7cR`78=unzJF0{J2N>Sgog~ImO3dajp)>L`=5qi+P;p4yyg^3hdwmDBVfgO% z^qcx%eb0MQb}!%bt!XHWKITnzz$O{71U15Caj)uRBdKlk=VFK!H(t^CNkT6PAQObz!zGKbQq% z{-q@#P1|l5E|>jt1J;t0bv#N8sm)RA>~}A$O8+W~`+8Q8wGZd*uVZce^#zjG)Zba7 zTFzatT+T--z7HJGSKuq-vEFqU^RB%{4B-Z~ci)}bNn=J?%pf_%y2vQpVbJIr83FW0 z_45P*=X(H~0wUFqA`7BIiQ3jV$MR(N$UgD5LqrTK1gf(uaa%eeBJh#XYjbjzr8`S= z=MVeh?gwt=hL2bktuM{>*-*(ak_%yc znDk6Zp{wJZYsMm_?w9|1{B(m<(g5rg?7{Z>E7q>Ini(DIju>3zh>hVu1>&%GE<%^d z?ejT6ljrt1A<$0I^39SfZcG@)g`IC5Am277q+kO26fTWo-oS*lgJJ?egeZq@8`!}p zEp!xaaXcD;EN#ijtGc>rRJmw{y=ilioEhmIvX+vH0rNy#x;NxhNJE_d^mCt`g0jDU zBv>1Lbtqj(G^HiI73ZQw{sYd&M-h+4m~@{4Y8aEB9nnj^Qu`BHm#MGq1+66+idNlx zM3kA@P85vQo!2if&~xF2iT8Um>*vma(*U{V;~Jyk00%vH$M21~DCMRYdEG6Y0*Hd{ zcP^2)fyoUDGSf3NCFh}s(r*w~qb`BT;188pdSfERl{F9^8}$LiL*OfDQ(GUKK?1#^wwRag$GZ{B-DZXX(D$8VP2?W;kU{j0I5JM$-T<=#W&bq(g0ub5ZJ{;p_5 zAu?SCv1w(}?TaY_CfzjxJ|6M0-u1@RHF3`jX>TB|9d00U=D+E<2iIR0?kV!p?g+W!#M3MC9=8(Kw^F+11jdhLfji9>Kz+VQF6mqLx&}M~(&Sp3b z=Fjwf!g`ydNhe~JmeZy6U_#VS+pAjFHAmld=Ou+zp|0Q7xb$3gp=$d`dUVR7Lgrf1 z*j*eIGh)wr7#q)EqUxX}Tv_x$E++B?>>_`I6e9-_7~(XkU^s=13@dqQ@#ub+>@R_R zN#WWM6?`SPMT~KuB{~`%7O7eRpVqukL*$Dd^hU+nWR3q>e>603e)Vo?ABX-wwIp2qHSDbaNH|eEeI+rGzk~&!%d*>0>vY8um8(qnOT)^}UJFxM7 z=xkQ`Yrmlk5N-f8SI@usR?EF2B_d_^Day|H_^kI!Z*T7!HUkOm0 z4+QRid7D#KUeXY%@9nz1QeFMKbF#a={H$#3;J12?gJREJ3!`}8`f@GG$lG_fe&P4+ z&zI*XYpb8r(tb7#kyl9d6m)}n>&wha+9xP6)SmUUP;lYiAky~#8qI$t6V&yeqWn+% zV-de=!4^+G!Y&tA~o-&D_jWR|#EybR

!}!9wVK(w}gLN4T)r((b&y9v<@jw^9>MbwUI&xFbl3 zoUqMFJdV}bzdB0u>Do;P#7Kh(rp7+$k|+2|*Kv6$uzXZY4C8q9kuIY?oabSBY5$H~ zj&zx@p2F$j-lybq0z5#xaIenf?62^L1|}1Y=&9mNnfy`&b5lAtj}_e}@oaVD>84 zfb}u4R#GIezDr_#eKynHhYbP@47_LVH!$gfK&4UAlyKO@dVMh2pRXYZ#lhUdC#k zI)X0eOZ~M|VoPCxXqq@gKS+&RZP?ntlE8)^5-!T30B(q?TD#jbA)8ej$`!D#)J%Z^dh_-_lJNZXe{A&8d94-f)q1>MTgNjfWSN_V1DA}qFM&KwHkfj~tAxEKhddJtKiI;0< z+V?Q&8Q#B(oz{}p`nXG`KqyW5#|ky5D8m7!AwAckz0L(=<1r4{Q*fm>GiOHc-IXa( zP*O*o4#wGN)GvgDlPDA4X{iMVj zt`Lvz#{~EsQOP~ZwcTPAS!FU{_tA4gnAj-BkYoP`;^YyHdG!Mw^@!ih3ym4P2(oL5 zlb0$a!f|)dYzjz$igyLpfkg-BdL>pBP`=RAIzKYKqMz|Ma0n zMWO_}cdiQQqxbz=%&DK=LCkU5w`ozlp;?4Z{ zxc(o-f$sa@;H`*^S;}d;1mvfb39#W8 z_pjZ^Y_+%^>f-8dHl5oP%>pXHo+hvMX9A-4jN{vj7;me7u=^XB2&?Ki)0g1xMU@t2z5~(fr#( z*b9Z2{`=#y*H0gwg7}u%-K(SJ2)4^Ncgw13MTx7NvOc>?E9Q93 zW06nd#pLB;*tOewCb~o3Im;<}!&Q-wg|0}LWx`Ry`R?=kvI6}{YVSgnC`CCXo>GqM zJX@%B*q*J@_M^xwUCdRPyYAtwXpuZWof~_L_@XrQMIJ>j5cVw{wiWSCY>z`x6>g+; zO{BHhHAzi4{MjX_;=9?n@PfLBe5r3H*SLPvn!UbM7E5 z+}qjNIg&ynqcd6&+Q#DSURf8*wMxZLpx{hMJ>Z~dkusao7$Ds)n9OT)p3@KcY% zFFvhKEejmSK2Cj>J#6%WL=*;amaU<2?;w=4h{~HbGn^Od_kMtIj{-bU^c^RwQ6ge0 zU_t7nn&f&a*MLNdZ5;f|zM zZ*nx)UGp;RCTRIV$D=ykIB#KjIEtQMXz#Bl?u7*!ws7-of5*(&&d07T>+v;Y7A literal 0 HcmV?d00001 diff --git a/src/drivers/dave2d/docs/files/doc/images/wedgeconcave.png b/src/drivers/dave2d/docs/files/doc/images/wedgeconcave.png new file mode 100644 index 0000000000000000000000000000000000000000..c979322c60fa3375a875dab248f5ff74989e6d7c GIT binary patch literal 9967 zcmbt)^4tLR3;DM3j+=Aa6oK8l*v_Yp;zC>5%RLf{1{WG#eq^NJujn z-Ghye@tvRV%B#r}5mkPnx-=&x%sDOJYN-(sc|9f~3iwP!bWT_b z*dQYE6ec3tG9x0ABrv$|lGUgwMMU)2QCUI$J@msa+$8+N--hmWJg2v$hAo zJ+_oI?4L!5F#nj5W3-(q)^<#+jDJoiZU<7!+Zc~x8VXr^%>RQ)L3lSNfr^!OYORgx zE6I|{K0i5S<)2so-K0qx_4Na*)PXSzWB?>EZLsa>4$t zXFrIG1Nen0DOvre6x`JHoIW;Du5ToYLyTXi2wW|R)#8NudT1Arlg#P zTw}fa8^(uA{v8|V?lU7?U%Wzfs#=Xxl|J%?89%vL@JT)m4l+;3HQ0tf_F}`g>@XG_cGc`!0&)Pt` zrmiurjG(?FA7>w8dfLFfV`5++I;gz#!6b&DYKa^eDL{Mg{eFzY;8=7CF_yA=08E8H4@G7d-zC=R#vjajq*?-Iod`G>Xe**& zeg3&M*47a!@$zMFb*Mpqo;;%l>HENNO8tY_22v<+yffW;`#z5GN;lg=NW;k2nD8?T zeha`3DGSB?B&hfLX8_hIoa$ZTKV8)c4$fK`?IF+zcM!&*_505@|Nl3%>JM8> z-h6sD%2TF~Zu^_E9zi>_o|%K4U6IeD=KxPO7%1a06-WcRzi@EiUyZZvx zsPACj@_*&IA_VWlVCWv3swole@f`w(lFrV~e5Eh7TBKp;`E1jrz-?&K;`sRcQ`jc^ z!j+HTz0`?Cvqb@2B1{jw*AR`wA+TkO-7+6&=G(5jv=|%?VLV1%~oL8ntkSw!5B# zKyzKpFP&we53zx?#M>_Jq^OCMroCWCzOD`|G1iNI{G9n<(S%{XYk#w1=R9mTy_A)M zgCkr@D6ghhOTd*3ODo&t^0!|t31%cFQu_OEbAG3mt=DTe4gmbn;sycQX)-46DmSlg2~l9#xN@XIlK z!>^rF#DeqXRT^>=H)U5X7MT&$WtAR9}1^?4Is)sdl&{Q>c%8&P53msP8aOfi?OyL zG@YuC@H^oG+Bv?HM*#nK%~sDV6T$fmm|lJLJYbUyp#HXbHdUU4=}rarfm?`og)o$< zwHHG_2~uH;eAi1eu|w|~)p0}rBcELb_5U2uC23*#v!{(Z25sMi)s`-^&N9Z7d*k-@ z(e1BCa_{o(bc1~cTX%^D@q)~2VoCOSS>3*+C-}%#tF)UWgTM3I!=;>2ny!Nn*zXC) za-Je#whH-mOltdQ2eIsJ8*5DBTKBjVAZ2{tf|9Ba$roJ&`Va;A2I)u^56r`s~8i_N|l#@ieR zJUl%8I&s(YHTIJmY_83aT|nwAt51m3|7?(doBx0oTNs}GdE42OeXSS zcGCB)RfTPJ-)Mc;b*Jc2TE3lEP;!J)cgA+P02eYdGt=_1%Qs;?ij6@;tGUIh$s^1ssVF}b zx=VK+@*Xco{sf#Tg*l_l*|Q*(ULHi;X}KEx0-$|^v1PvwL}*QPGQFW;to^0~s-$1n zX7cff2jJ0TLcEcp2f;1FrD=ti(EHiGt0o1Z9*=E=n_JZHTSB6j0KY9h%%#V+FTaqk@ImBRZd?XPLdP|!@$$*1g|i|SErHACdeLkxR3~3|y%nD- zQuN4J>BG`vzF1XXXHC@Etr8?|ObxbPXk>U1TbHUP^`rZ9hW4v4Vu++E`u+FS9zvjR z5>9D+v~Dupfxt9hWNEz=tk6ciWGulB8I>)`ubR|{p0R3icBMh}A?i*^P<*n@k7L>c+-U-XZ;@_yMmYmA_MG#yWg z=0YA4m#9q;>0gM~-Gk~muhMW6?gfO%$N$syAIAw=OmUpVH-a26JsAQgkAIvDmrZ1` zq4yzuU`!t&-6pF4Q!5iG!0r6QoG>r*`G30941j~BXvz0>V-4j_lQ)}A?wDaNQdRF9VOX52xjPmzqI$o?xn4hQ#uC@?7x!ZhfQ>7C)={Fbutl> z+)|=`z0#E}1D`Cev9BsA>m!xF*CF!iz`Yw3^+m>O{L*jbE&kofT%yuzt8ZknJ*cbJ z|CDJ*qNAi(xM(~FGj_I0+~pyA11TxZ<1t`aTDBK<9^RV;#)M1efD_^gD{DXLH?i*k z^B_?RWVi1zPgQz4o4dzd55|CDf}rT4b+N-7Eq68bdG?nOsSJUdkmf)|=%U;)IxN@| zaWpYqw;=OUL!vR}>}+S-bhrW^TF_1*NQ=B-IK5=?TqNFcHf6n$^2B~Z)%O%V?KdxT z_7L-YgI`!mGEopcq|0;>OKpWEr4GI>Qh4UhMpU z>Hm%ytoidT6nMj?oxCYb#L)sg|IB&2YUykp*A?0j`0{c@iRP#@6bNzhV4|Xe$Rs{W?n=_^@Qr!L-39L@2g$14{g2;T(6A?va@HLRHpc>Vbp1~vaV-tTX$=xva zzM}ORFEA~bf9}v@=zG`NRtG}#bgvm~)Y6P7oxBPA9+oRAg@+y&%8Hwn#kGY3*8AwK zrTwl?O(q*|a;%{C@%K&_vtN#9_RIdz?3=?E*F$d?dn5r+bEDc7C;xo;$=4#R7iH^r zeyopsA*jJ)um1?>o|)=QRL1yD;&z<`1&_qCD z0nRM#)aHx%zB`RB{*Xo1$O)r`Fpql>xv&UQr0^tr+Yj__MBY(GbKOWtk+XMJsI!pN zQn*hXus7GRU;8OoicM8fWrJ(S5$$$GxE76g9k|#vm3^Z~ebmSL!zPZFW1@Uc8fxod z`H*r;WNq<&V<({?Fmmec9^d+^iz{b8HaT-VY??GR-Tdx(4}xh*b(~q5eocZc``D!V zXqwe)ZZ_&pH+(fjyxVjjxtRnH-5Td>p`6FPm&Ur7r7zWSJlQOVqL2cHPZ?$A)S~i| zuT)yumOZ$%hf&Da5^K+x+;f2wIma;Q$%GMX6}N2@70J{CMg=PcXCC(nG!-luOo61* zE|$w;_1}#h)nXz~7Uji~Z^0aiC)hM@y110q?+i-yTq!-DJe~3B>|hR;`pN&@)F1DD zo&9$dYU>X@kSts%kgH1OQ(3{io7?wp;O zErXVXncV!Xj}*%}Ju0sX<51@bxXzs353pVr`Jj8$tB({wim;XkbyW9)Rf%-X@O!|B z*?l+w?Y=EjuR69n{*dJ_E!887{22R%bpF#W)&@^w#&a0?4pWc7E05Haq{Y}$BfxdG zwm|~*0{y95r}IlcxVi0;o6N0{I0aM@HA}LDrJZMoJv{Mbd7X*8m>!l{_`_0y?OZhx zVd!yF(uD#%!eWg5Ac3SWgd-+paH`FyJnq1?NU&mY1$M82hXtF5i)Fy?hcUYYpj%M0 zjeDYuU}5eNSeR3E;Pcqknl7*zbpm(75R!kw=gqM9)C2tC82m>d9Z9Uh4R_1V?xsKjbL?&?GMv=V{EjwQm_F2D{ z`m|wX%vuj0G|XvW>et%>o2*JwRJ`CQL;Z)J#e-q9fR1zSrWWaL>iF~221{xOPsxb= zN8pC3aH@7-{N99xEWO&FB9)Gg+`$?GGj$rEqUoM+6t^Vf2yFj?;Uv$MXA6}m^I8%(ld z_M)rah+sapjU=IO%b-RPw6?g3z#uqucPbg)#!bc1Qf2-q!j?Y4$80J#9pTYfP=!&= zV5X@sEu;)pR}%f!-wwH{@`MhiOfY>|7rm|MSFR@fB36hmP1S|UYcCbJ8jH^TGP_mGrV`j*Nd*kgGr+iy%i79duP zj37#Xjx)xgICg0WFBRSy_^J^*2~{D*ZN1bqd@tRn3ZdS>5b% zDBQ-9WtmVJhSU=tCy@eJD`=SA08!cMMxk0$ab&RdeZPrBHRAuRx-P78c7S8=neULC@48*05MCR#sX}86svMx4t_Xy7SKERW>!| zPs}z=!u-z*YdaTTi>-JtPK23I>`tm2EIgn%h`rjqa~t==?mC5`Dq0uEHL+w~`JL7{ zDcNbzCXV@ibPktBL68q(Z+~_*d3ySVvuYYEhqyHho`5fXJxIVzFG5_zj@4Un@dKf zvJ!DXo0^h&D=`#r0&L3gbRn{9_UDKHMTX1ahNkRjI`B(`GjiKDSV{z?SuZi41mVFB3|N<$9-bTfePtpTz%S2b z^bxfC&+9{6RPhW%dgwu0EJ?-7^d{F$V!T^p3?NPXA2wDc{!?t%>tQ;S`Abm>M*EK~ zcVG!f6-g^q-vGcuJ^@(eT3$g0|J)bvICSx<4gKh9ZmSiNll_rLDr)#eb}Ju-EB+Cz zTkwgHBTd39sGg@}0H9K)l>HF1VLJU9&iharlq)-!fD||>?}c@n^}X}wpL8n8O(BNt zlgh#aR~Q0&P0w+3pI=G~^n&j~hNV5pX+rjeI`1fo_av@>8cp2Q_*2EK6le4CD%e;& zV`4uwGtWARySwEq#ux$WsZprN$5-yBm3-GGk&-!o#A6epaBmI7TRzQ6DAE;zHFSFD z*FeDeL&-QNAE_D605$ix70_;8{ekF9%tLYv+0gL!U{KDs>7S3;@o_Q?R^+^;PYD6=J*O760*^osi*gU=_& z;M+F_x!dp#=y%^%K@d?t1Bw>ooF_~?H^B*$Rpy-tvLucqV><^1f-Out0!lOTj@Cf^ z=SW>%1fwA{tPQDBT@q%U-FCl^3RgDuH!%ya01K!h#M9`5L8jFWq(i0B)@LTQSX}I=U>wgd*dvNP32=RAeTNySsh|1Cb-*=$eq?m!+@q3}t@azdwy0l;PKs{r z!5*7XqLhUmi1l0?*G)EE9rwx|>~g$&_F>>bWX5Z@rHVyt9mOor33WBRpaolxJsyF0 z&pH~R;l8AlUp5C3P2MLNCI>884E2@g(GYVm>5A{J{dH6Ip)9(l2T#NIIG35^#{&93 z2v(x2hDYDNw$0gYP3wFiXNbBr3w)7nMp{Sxa82#WiD_2Ot!#E$Xg*zvQo3oMJhseN z`~B?JScH};=PcWD9;Xwj9q|nzH@4RW#e~T*`1ODvq_KS9Y!!f`gr$+LQE$p zF-$END~VB}J!5AEx2F!m=`i{(tul-)4`*aacWBvq%qJ-^T0dL3F$rNhJ+nZ>rRbSw z)f8aU{E7?~;Ux6M&BAOsP5EWezR#OVb@1*f=%s2?3o*v?8b54Ka0V@hjlAcf+4-$r z&Yj`Mh7tk`?--DY^4WXk6%xUHA|c0me=J(AuRdR(yv=xq5emC0(GO=%K6GlBqY4m; zhR_A?bbz>LnL>ZfDvzAjaruv2FQ>x-Y;7 zlO9NjAXP>s52va*Ex1|{ai6<7XOlwS$xPc%*H|nRq-BXS-(inTSTR{X>*6X^U+f8R z!;)cz?qGXnjwUDVaGQlW*x^ETxM&O8OE;3KbaFZNuWROL?wb!`dhAllL*R$8-X7L8 zJD+zE3W?Tl3X(hqAHq_d=!iDcw$jt$z>U8m0lv6N=qYGo?($N~csX^s`%CI(t^2w< za)t$UizASy7lFOfxQp~Y`g@tO$}9Aw;^J?4$~7*hFDTL2KXp$SNR;lqI3S$opXMFz zYMTwu>>oByz9o)~ibdL&55D02`8c3~>b?+Df0@IeyyWGyqWn~$-Zj2UVoE7)#pDeC z?iQ-E@fZ2j?z|B>*!)7MQ(0q`rQJ#D`FbCT2rBt0{o5q*UY+hEWK_6RCY*79=xwBm z(LQbJ1Q{fCCU&k!!veY8uwW7dyzNcK2I`3tBc#1kuCFkm&mY(<6f{SVthj&bbM%?X zMKc9_=NY0zgSfGggHJFL5cWx z{;|6A8QT5m1DBrDO$1N&$58k;-_-M8j@qv*$dAGg$_{=x&fe2zedka+5(;R>0ke*S zxI$@Ud(7%no9{s`qZW9bpZ<)?Cd1KrbQl-Avx)`5(!lu^y!Br?s~xcDD@deDf2r0Q zqw>%GWc0ie$LhLCcOx}IQM2-e$nIxSOpaU66S74;H`IG zA@hZW!z+4CY@Y;x$aD1D)CZcYT!oOQ&lkDUM*wCN+8BB1CTPxr;ubr18b;8q%)<)X zsRx*wS6DY9g%3z1-I!4(fC+{=nhg_oH#3|a#SSBbsILVC`107yrT?e0nolViv8Xvq z3jH_V=@;y9UxIUB1!E8@27Wp18fWE7q`d6$2H`xdh(PaqtI)7qL1bQ7-3q8;c`?x+ zKUTU!0zFwtoF03JDBu@9Mm43zG>|nrE-n)zy*Iu_Co3n&w?2cc!pX7CIQW|NgHR7P zdK354swOP)ch^rS9p*=Q$o9A9r(IngVikz$l%6Nw*5DQK4{VkS)=V0M89!}>wQdxW zW3uAH;@jLhGc@9cvLZM>&PAkm6~Xkxmmcr&1i5wBbBTH zK3(YHDyXo!@~-P5@3&_d4VSC)Xt=)42ZBo%uJ`ynwNRC7^dRlq1vCRMIjp^zGyU#{ zd_$@<9h523^Gi2YK6t9RzXqqlzId}1byXgmINX_Rjd~-pH;^hEBmbeXI6Dat=jM5` zAFJ4pyhXjIluh7^Uo(98R2_zz?{4ZBI*M6}?=!+AELN7*c;#fRbL+-Vf&N7(S*ygadj^OsIiF-3})4T}|#M!&2|yv8fu5A1=*ve_2WFH=&3i!`?lJHAkGFwu2lD@&b`As3Y!j zzo{~fvDTqW%q^$Aw{%40>qCY+{VsS2B}ybUoLpCSZHxt@5q=dgER*RSP6koqsW7z5 z2m<2v2!L3#5ItX~XcPm|az`18R*%6yGZ8%8u-w;#P6kWq-j{&fwVrxZ>PhYUOX|^i ztE&fUMA>0(%DCAP8|yan>rrOTu=&ZlY&TyG0if9~E=sm_^v)q|%? zPzwcAVDj$l(+|E!#!c@0)QG2-t3Hj-^OEn!1Nx8?RHpPvmJX?1B2W<_S7PQ6QdO7t zIUMP|mTufl+cre;rj5x6z4nKf>j8#odxfR+e{1=jl{B;NM+GaD(C!^sOL%maF%s(P zRCX6u+B&o{@lzv0oRcmJh@M7wHD8oDa(|2g$RKY-&yvlHTTG zwNbOkqFo}|z${PH^0?{2;>Fs7KO9yqN03pxl$f-b`RdJn5d{BA4Fx#=_UjuSjG7b9 zN@x)L9zBCPg;N+HT_N@rD+%m-~qH z?r{?^zY4W_;=ZEpeP!z%+g$3#kkgNWNK3?nsK{mYuO0X7S}%Us1t!*V5ppo}^1$c0 zgPEz0;s+%&J>DKK#m1?)C0aDdi3G&Ro~C5_Xb`OXCS`sKFZp&lk@=YDtmcC=%5_c( zA;S*k#9qSX^2Kv<^V^l$;fGZfNSM;?-y)``_&~DnX&TZTqN$%b;ilV!OQ$qRqx7|p zNxpawV!I3x=?QTx8oxHVcRBLbuGkMZ?}rp4P{4BXcn87##Q9jlDYsEKbU#VWJ9OBA z`yCX&*c@kZ!RcUWSa{Xqnh1yiW|P;35qpc9^Rd8F5>3nHP?G znH3*@V-htK47|CGJ}-594(G;N zAnDX1BJ=s`qQq+R8Adg)GRw|{qEEppzsjZ^>_S9UujaZt^CD5Lbh07vR_>8S)&A=@ z4kU>*m{ztE3R6!V^~SECjqi_Riuetmg2)EzE89P=fCiJ}J$2jNsQ7DLEaj*d!)41h$bFT854EfXOyD*oBq;I9?pD-G83)GeVdIDR%3PyoZ8X*-WsmPQJG| z((?1rGd*g_%wmTkv+n#6i=y!A56i%N*WyUvnO-s6uFNd<0R_eqT$ZNHZuUxO%v=~` z&{@Qf8ZoZ?Pu1Pp3f|1qLB%aSuarF!Lm6uF$~wPKq*U{-`TK*|zjxm2r98;k3#@s{ zo_JTB(cvRhZza&{^{#pNCkMev2It8+`T>p+ukP5@h6d|DiURXZ;Opr|aoJBnJ<)$+ z)ZKTVx=B*=z6%Rvu=$MIP#g|)0v4K1H}aK6Vst-waMM2CXVhEyD}-#IC0!sETr!Q~<(cec^9ikvn}K>{E2QLtK3BI~JTa))DCdk`|OJvS$}j)`N~vt3c7 zk&8u^P!}{Ejv9DazNei()$?e-hbE`FTH|-zn%X}o%M$Q1DTa^S>5cRJ^a(bY@lVnx zTLoA9IWblOoU}n21<^7Ax91=8+@CCyj&!OX&HM1&%UwW@vQY4khJ4ycSnP2^oe08d zUfCl*8LQOuHcQcYXfuDcr#(a}(T)1qv#fAO znq<8+2m*XrrpXbtZT9+<77)n98vAzmG_&H$k*)uyPg@R+PG1kDh0u?(E|&Hmt(tTc zzvw8}LY*;YOJRfzR6V^Nu0$VPCQ)O)7Zws4bn5N1v~y{&NkALv{Kzl?W25}eh+^!y zP;I?=I99M(#DGM&poulWo?A)sv+>+Y0dQrC9&TPtMx?bB-UPO;H|}^a^t5Ik#xF^T zPsO<*IM|%c#suA(A&3KzhN~t3zg#~b0c~U?w4uDKQ$UJEr03+2`@d=91o1w*F2Vma zg_Twp5+Jxo1aN(9FadBVtnz88#Hd;sPX+;L-kl4{K#E1#n%S#l_Q|8cl-F>UksHab!P}o7A<%GHB{IPBbHtrcOfBaW0CrFxgIqfpQ*sF``V+4 + +Limitations + + + + + + + + + +

Limitations

Summary
Limitations
Coordinate range limitationsAPI interface coordinates are limited to the range -2048 to 2047.
Object/primitive size limitationsObject sizes are limited to 1024x1024 pixels.
Framebuffer size limitationsThe framebuffer size is limited to 2048x2048 pixels.
Texture size limitationsTexture sizes are limited to 1024x1024 texels in general.
+ +

Coordinate range limitations

API interface coordinates are limited to the range -2048 to 2047.

This limitation is due to the usage of d2_point for coordinates on the API interface.

Furthermore, since some internal calculations also use this range inside the driver, it is important that the resulting internal axis-aligned bounding box of an object does not extends out of this range.  Such a situation will leads to rendering errors.  This can happen e.g. when specifing an end-point for a line which is still inside this range but a line width which lets the bounding box of the resulting line extend out of this range (see e.g.  d2_renderline).

+ +

Object/primitive size limitations

Object sizes are limited to 1024x1024 pixels.

This limitation refers to the resulting internal axis-aligned bounding box of an object which is finally rendered.  Since the API allows larger coordinate ranges, it is possible in general to pass objects of this size into the driver, but rendering errors may be the result.  The application must make sure to split larger objects if necessary.

+ +

Framebuffer size limitations

The framebuffer size is limited to 2048x2048 pixels.

This limitation is due to the limitation of the API interface coordinates (see above).  The framebuffer pitch however can be in the range [-32768 ..  32767].  A negative pitch means that the objects are rendered upside-down.

+ +

Texture size limitations

Texture sizes are limited to 1024x1024 texels in general.

This limitation of 1024x1024 texels is valid when arbitrary texturing (see d2_settexture) is concerned.  Blitting (see d2_setblitsrc, d2_blitcopy) allows using textures of up to 2047x1024 texels.

+ +
+ + + + + + + + + + +
short (fixedpoint)
d2_s32 d2_renderline(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w,
d2_u32 flags)
Render a wide line.
d2_s32 d2_settexture(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for texture mapping.
d2_s32 d2_setblitsrc(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for blit operation.
d2_s32 d2_blitcopy(d2_device *handle,
d2_s32 srcwidth,
d2_s32 srcheight,
d2_blitpos srcx,
d2_blitpos srcy,
d2_width dstwidth,
d2_width dstheight,
d2_point dstx,
d2_point dsty,
d2_u32 flags)
Copy rectangle part of the source into destination.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/doc/overview-txt.html b/src/drivers/dave2d/docs/files/doc/overview-txt.html new file mode 100644 index 000000000..3ce5dd30f --- /dev/null +++ b/src/drivers/dave2d/docs/files/doc/overview-txt.html @@ -0,0 +1,80 @@ + + +Driver Overview + + + + + + + + + +

Driver Overview

Overview of D/AVE 2D driver V3.14

Summary
Driver OverviewOverview of D/AVE 2D driver V3.14
Coding conventionsQuickinfo about Dave2d Driver implementation
ConceptBasic objects and principles
Sample codeSimple example of using the dave driver
+ +

Coding conventions

Quickinfo about Dave2d Driver implementation

  • interface and driver are pure ansi C
  • code is fully reentrant
  • all exports prefixed by d2_
  • all files are prefixed by dave_
  • all functions and types are entierly lowercase
  • all macros are entierly uppercase
  • all functions set an errorcode
  • only a single include is necessary from the clientside (dave_driver.h)
+ +

Concept

Basic objects and principles

The driver allows direct access to all hardware features.  Functionality not directly supported by hardware is not offered (emulated) by the driver.

  • basic object is called a device. all functions require a device pointer as first parameter (see <opendevice>)
  • devices are assigned to a hardware unit before anything is rendered through them (see <inithw>)
  • material settings like color, texture, blending etc.. are stored in a context
  • shapes are rendered by Rendering Functions using the current context(s)
  • rendering does not happen immediately but fills a renderbuffer (see Render Buffers)
  • renderbuffers can be executed totally in parallel (without any cpu interaction)
  • calling d2 functions from interrupt service routines is not recommended in general and must be done with care
+ +

Sample code

Simple example of using the dave driver

Further information and examples can be found in the Driver Tutorial (software/tutorial/driver_tutorial.doc).

To create a device, allocate and initialize the hardware (errorchecks omitted for clarity) :

#include "dave_driver.h"
+
+int main()
+{
+    void *framebuffer;
+
+    // Use the default memory management functions and register a wrapper for the normal malloc, free and msize commands of the system.
+    // Note: On some platforms a different memory manager for video and heap management may be required.
+    // A different memory manager can be chosen by calling d0_initheapmanager(..) instead of d0_initdefaultheapmanager().
+
+    d0_initdefaultheapmanager();              // initialize D/AVE driver memory management interface
+
+    d2_device *handle = d2_opendevice( 0 );   // create a device
+    d2_setdlistblocksize( handle, 25 );       // set blocksize for default displaylist
+    d2_lowlocalmemmode( handle, 20, 10 );     // systems with low local CPU memory need this mode
+    d2_inithw( handle, 0 );                   // bind the hardware

now we setup a 32bit 640x480 pixel framebuffer using the lowlevel driver

framebuffer = d1_allocvidmem(d2_level1interface(handle), d1_mem_display, 640*480*4);
+
+// define address and memory organisation of framebuffer
+d2_framebuffer( handle, framebuffer, 640, 640, 480, d2_mode_rgb888 );

using the default context we can directly start and setup our material attributes

d2_setcolor( handle, 0, 0xffffff );         // just simple white
+d2_setblendmode( handle, d2_bm_alpha, d2_bm_one_minus_alpha );
+d2_setalphamode( handle, d2_am_constant );
+d2_setalpha( handle, 0x7f );                // 50% transparency
+d2_setblur( handle, 4*16 );

the rendering happens inside an endless loop, as it is the case for most realtime animated graphics.  In order to avoid having to deal with renderbuffers manual, we use the utility functions startframe and endframe to get automatic buffer management.

d2_point x = 320*16;
+d2_point y = 240*16;
+//
+while (1)
+{
+    d2_startframe( handle );
+    d2_clear( handle, 0x000000 );               // clear the background
+
+    d2_rendercircle( handle, x, y, 64*16, 0 );  // draw our circle
+
+    d2_endframe( handle );
+
+    x += 1;
+    y += 8;
+}
+ +
+ + + + + + + + + + +
There is a rendering function for each supported geometric shape.
Renderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/inc/dave_driver-h.html b/src/drivers/dave2d/docs/files/inc/dave_driver-h.html new file mode 100644 index 000000000..6063b5303 --- /dev/null +++ b/src/drivers/dave2d/docs/files/inc/dave_driver-h.html @@ -0,0 +1,60 @@ + + +Basic Types + + + + + + + + + +

Basic Types

Note that several types represent fixedpoint numbers.  The C compiler cannot directly create these from constants.  Therefore if you want to pass an integer value of 42 to a function that expects an argument of e.g. type d2_point you would have to write :

function( 42 << 4 );    // conversion from integer to fixedpoint

see also D2_FIX4(x)

Summary
Basic TypesNote that several types represent fixedpoint numbers.
Types
d2_devicevoid
d2_contextvoid
d2_renderbuffervoid
d2_colorunsigned long
d2_alphaunsigned char
d2_widthshort (fixedpoint)
d2_pointshort (fixedpoint)
d2_bordershort
d2_patternunsigned long
d2_blitposunsigned short
+ +

Types

+ +

d2_device

void

Abstract type.  The application uses pointers of this type to hold the address of a device structure without knowing its internal layout.

see for example : d2_opendevice

+ +

d2_context

void

Abstract type.  The application uses pointers of this type to hold the address of a context structure without knowing its internal layout.

see for example : d2_newcontext

+ +

d2_renderbuffer

void

Abstract type.  The application uses pointers of this type to hold the address of a renderbuffer structure without knowing its internal layout.

see for example : d2_newrenderbuffer

+ +

d2_color

unsigned long

32bit RGB value.  Upper 8bits are ignored but should be set to zero.  All colors are passed to the driver in this format regardless of the framebuffer format.

see for example : d2_setcolor

+ +

d2_alpha

unsigned char

Alpha information is passed as 8bit values.  255 representing fully opaque and 0 totally transparent colors.

see for example : d2_setalpha

+ +

d2_width

short (fixedpoint)

Width is defined as an unsigned 10:4 fixedpoint number (4 bits fraction).  So the maximum width is 1023 and the smallest nonzero width is 1/16.

+ +

d2_point

short (fixedpoint)

Point defines a vertex component (e.g. the x coordinate of an endpoint) pixel position and is specified as a signed 1:11:4 fixedpoint number (1bit sign, 11 bits integer, 4 bits fraction).  So the integer range is 2047 to -2048 and the smallest positive value is 1/16.

Points are stored as 16bit quantities because they represent direct screen coordinates and therefor do not become larger than 2047 even for HDTV resolutions.

see for example : d2_renderline

+ +

d2_border

short

The border type is used only when setting clip borders.  In contrast to points, borders do not contain any fractional information (no subpixel clipping) and are simple 11bit signed integers.

see for example : d2_cliprect

+ +

d2_pattern

unsigned long

Patterns are Nbit bitmasks (N is 32 at most so they are passed as longs)

see for example : d2_setpattern

+ +

d2_blitpos

unsigned short

Blitpos defines an integer position in the source bitmap of a blit rendering operation.  The allowed range is 0 to 1023.

+ +
+ + + + + + + + + + +
short (fixedpoint)
Integer to n:4 fixedpoint conversion
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
d2_context * d2_newcontext(d2_device *handle)
Create new context (used to store render settings).
d2_renderbuffer * d2_newrenderbuffer(d2_device *handle,
d2_u32 initialsize,
d2_u32 stepsize)
Create a new renderbuffer.
d2_s32 d2_setcolor(d2_device *handle,
d2_s32 index,
d2_color color)
Set color registers.
d2_s32 d2_setalpha(d2_device *handle,
d2_alpha alpha)
set constant alpha value
d2_s32 d2_renderline(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w,
d2_u32 flags)
Render a wide line.
d2_s32 d2_cliprect(d2_device *handle,
d2_border xmin,
d2_border ymin,
d2_border xmax,
d2_border ymax)
Specify the clipping rectangle.
d2_s32 d2_setpattern(d2_device *handle,
d2_pattern pattern)
Specify pattern bitmask.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/inc/dave_errorcodes-h.html b/src/drivers/dave2d/docs/files/inc/dave_errorcodes-h.html new file mode 100644 index 000000000..fbcd7f7ca --- /dev/null +++ b/src/drivers/dave2d/docs/files/inc/dave_errorcodes-h.html @@ -0,0 +1,38 @@ + + +Errorcodes + + + + + + + + + +

Errorcodes

List of all dave driver errorcodes.

Every device stores the errorcode returned by the last function executed for this device.  Successfull operations reset this code to D2_OK.

Latest errorcode can be queried by d2_geterror / d2_geterrorstring functions

Errorcodes

D2_OKsuccess
D2_NOMEMORYmemory allocation failed
D2_INVALIDDEVICEinvalid device
D2_INVALIDCONTEXTinvalid rendering context
D2_INVALIDBUFFERinvalid renderbuffer context
D2_HWINUSEhardware device already in use
D2_DEVASSIGNEDdevice already assigned
D2_DEFCONTEXTcannot operate on default context
D2_INVALIDINDEXindex is out of bounds
D2_ILLEGALMODErendermode not supported
D2_INVALIDWIDTHwidth out of legal range
D2_INVALIDHEIGHTheight out of legal range
D2_NOVIDEOMEMillegal framebuffer address
D2_VALUETOOSMALLparameter too close to zero
D2_VALUENEGATIVEparameter is negative
D2_VALUETOOBIGparameter value is too large
D2_INVALIDENUMunsupported mode
D2_NULLPOINTERsource pointer may not be null
D2_DEVICEBUSYoperation cannot execute while hardware is busy
D2_DEFBUFFERcannot operate on default buffer
D2_NO_DISPLAYLISTusage of displaylists a mandatory in d2_low_localmemmode
D2_NOT_ENOUGH_DLISTBLOCKSamount of displaylist blocks as specified in d2_lowlocalmemmode is not sufficient
+ +
+ + + + + + + + + + +
d2_s32 d2_geterror(const d2_device *handle)
Query device error information.
const d2_char * d2_geterrorstring(const d2_device *handle)
Query detailed device error information.
d2_s32 d2_lowlocalmemmode(d2_device *handle,
d2_u32 dlistblockfactor,
d2_u32 dlistblocks)
Enable and configure the ‘low localmem’ mode.
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/files/inc/dave_math-h.html b/src/drivers/dave2d/docs/files/inc/dave_math-h.html new file mode 100644 index 000000000..e0a11f24c --- /dev/null +++ b/src/drivers/dave2d/docs/files/inc/dave_math-h.html @@ -0,0 +1,68 @@ + + +Math Functions + + + + + + + + + +

Math Functions

Package of useful macros and functions e.g. for fixedpoint operations.

Summary
Math FunctionsPackage of useful macros and functions e.g.
Fixedpoint Macros
D2_FIX4(x)Integer to n:4 fixedpoint conversion
D2_INT4(x)n:4 to integer conversion
D2_FLOOR4(x)n:4 fixedpoint unsigned floor (round towards -inf)
D2_CEIL4(x)n:4 fixedpoint unsigned ceil (round towards +inf)
D2_FRAC4(x)n:4 fixedpoint fractional part only
D2_FIX16(x)integer to n:16 fixedpoint conversion
D2_INT16(x)n:16 to integer conversion
D2_FLOOR16(x)n:16 fixedpoint unsigned floor (round towards -inf)
D2_CEIL16(x)n:16 fixedpoint unsigned ceil (round towards +inf)
D2_FRAC16(x)n:16 fixedpoint fractional part only
D2_EPSILONSmallest representable positive number (all fixedpoint formats)
Math Functions
d2_sqrtMinimalistic 32->16 bit integer square root (no hw divide/multiply needed) unrolled for speed.
d2_pow2maskFind next larger power of two minus 1
+ +

Fixedpoint Macros

+ +

D2_FIX4(x)

Integer to n:4 fixedpoint conversion

+ +

D2_INT4(x)

n:4 to integer conversion

+ +

D2_FLOOR4(x)

n:4 fixedpoint unsigned floor (round towards -inf)

+ +

D2_CEIL4(x)

n:4 fixedpoint unsigned ceil (round towards +inf)

+ +

D2_FRAC4(x)

n:4 fixedpoint fractional part only

+ +

D2_FIX16(x)

integer to n:16 fixedpoint conversion

+ +

D2_INT16(x)

n:16 to integer conversion

+ +

D2_FLOOR16(x)

n:16 fixedpoint unsigned floor (round towards -inf)

+ +

D2_CEIL16(x)

n:16 fixedpoint unsigned ceil (round towards +inf)

+ +

D2_FRAC16(x)

n:16 fixedpoint fractional part only

+ +

D2_EPSILON

Smallest representable positive number (all fixedpoint formats)

+ +

Math Functions

+ +

d2_sqrt

D2_EXTERN d2_s32 d2_sqrt(d2_u32 x)

Minimalistic 32->16 bit integer square root (no hw divide/multiply needed) unrolled for speed.

parameters

xfixedpoint number

returns

the square root of x

+ +

d2_pow2mask

D2_EXTERN d2_u32 d2_pow2mask(d2_u32 x)

Find next larger power of two minus 1

E.g. given number x=73 -> next larger power of two is 128, the result is 128 minus 1 = 127 (number with all bits set)

parameters

xpositive number

returns

the next larger number of two minus 1 of x

+ +
+ + + + + + + + + + +
D2_EXTERN d2_s32 d2_sqrt(d2_u32 x)
Minimalistic 32->16 bit integer square root (no hw divide/multiply needed) unrolled for speed.
D2_EXTERN d2_u32 d2_pow2mask(d2_u32 x)
Find next larger power of two minus 1
+ + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index.html b/src/drivers/dave2d/docs/index.html new file mode 100644 index 000000000..575b91325 --- /dev/null +++ b/src/drivers/dave2d/docs/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/Functions.html b/src/drivers/dave2d/docs/index/Functions.html new file mode 100644 index 000000000..430d934da --- /dev/null +++ b/src/drivers/dave2d/docs/index/Functions.html @@ -0,0 +1,53 @@ + + +Function Index + + + + + + + + + +
Function Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
A
d2_add64
d2_adddlist
B
d2_blitcopy
C
d2_cast32to64
d2_cast64to32
d2_clear
d2_cliprect
d2_closedevice
d2_commandspending
D
 D2_FIX4(x)
d2_deinithw
d2_div6432
d2_dumprenderbuffer
E
d2_endframe
d2_executedlist
d2_executerenderbuffer
F
d2_flushframe
d2_framebuffer
d2_freecontext
d2_freedumpedbuffer
d2_freerenderbuffer
+ +
void d2_add64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)
Addition of 2 64bit value
d2_s32 d2_adddlist(d2_device *handle,
void *address,
d2_s32 size,
d2_u32 flags)
Add an already prepared display list to the current render buffer.
+ + + +
d2_s32 d2_blitcopy(d2_device *handle,
d2_s32 srcwidth,
d2_s32 srcheight,
d2_blitpos srcx,
d2_blitpos srcy,
d2_width dstwidth,
d2_width dstheight,
d2_point dstx,
d2_point dsty,
d2_u32 flags)
Copy rectangle part of the source into destination.
+ + + +
void d2_cast32to64(d2_s32 par,
d2_int64 *res)
Cast an 32bit integer to 64bit variable
d2_s32 d2_cast64to32(const d2_int64 *par)
Cast an 64bit variable to a32bit variable
d2_s32 d2_clear(d2_device *handle,
d2_color color)
Render fill the entire framebuffer with a single color.
d2_s32 d2_cliprect(d2_device *handle,
d2_border xmin,
d2_border ymin,
d2_border xmax,
d2_border ymax)
Specify the clipping rectangle.
d2_s32 d2_closedevice(d2_device *handle)
Destroy a device handle.
d2_s32 d2_commandspending(d2_device *handle)
Check if there are pending commands in the current displaylist.
+ + + +
Integer to n:4 fixedpoint conversion
d2_s32 d2_deinithw(d2_device *handle)
Unlink hardware currently bound by specified device.
void d2_div6432(const d2_int64 *dividend,
d2_s32 divisor,
d2_int64 *res)
division of 64bit value by a 32bit.
d2_s32 d2_dumprenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
void **rdata,
d2_s32 *rsize)
Copy the content of a renderbuffer into user memory.
+ + + +
d2_s32 d2_endframe(d2_device *handle)
Mark the end of a scene.
d2_s32 d2_executedlist(d2_device *handle,
const void *address,
d2_u32 flags)
Execute an already prepared display list.
d2_s32 d2_executerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
d2_u32 flags)
Render the content of a renderbuffer.
+ + + +
d2_s32 d2_flushframe(d2_device *handle)
Wait for current rendering to end.
d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)
Specify the rendering target.
d2_s32 d2_freecontext(d2_device *handle,
d2_context *ctx)
Release Context.
d2_s32 d2_freedumpedbuffer(d2_device *handle,
void *data)
free a chunk of memory returned from d2_dumprenderbuffer.
d2_s32 d2_freerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)
Destroy and free a renderbuffer.
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/Functions2.html b/src/drivers/dave2d/docs/index/Functions2.html new file mode 100644 index 000000000..8c6de6a49 --- /dev/null +++ b/src/drivers/dave2d/docs/index/Functions2.html @@ -0,0 +1,61 @@ + + +Function Index + + + + + + + + + +
Function Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
G
d2_getalpha
d2_getalphablendmodedst
d2_getalphablendmodeflags
d2_getalphablendmodesrc
d2_getalphaex
d2_getalphamode
d2_getantialiasing
d2_getblendmodedst
d2_getblendmodesrc
d2_getblur
d2_getcliprect
d2_getcolor
d2_getcontext
d2_getdlistblockcount
d2_getdlistblocksize
d2_geterror
d2_geterrorstring
d2_getfillmode
d2_getframebuffer
d2_getlinecap
d2_getlinejoin
d2_getpattern
d2_getpatternalpha
d2_getpatternmode
d2_getpatternsize
d2_getperfcountvalue
d2_getrenderbuffer
d2_getrenderbuffersize
d2_getrendermode
d2_getrevisionhw
d2_getrevisionstringhw
d2_gettexopparam1
d2_gettexopparam2
d2_gettextureoperationa
d2_gettextureoperationb
d2_gettextureoperationg
d2_gettextureoperationr
d2_getversion
d2_getversionstring
I
d2_inithw
L
d2_layermerge
d2_level1interface
d2_lowlocalmemmode
M
d2_mul3232to64
d2_mul3264
N
d2_newcontext
d2_newrenderbuffer
O
d2_opendevice
d2_outlinecontext
d2_outlinewidth
P
d2_pow2mask
R
d2_relocateframe
d2_renderbox
d2_rendercircle
d2_rendercircle_no_hilimiterprecision
d2_renderline
d2_renderline2
d2_renderpolygon
d2_renderpolyline
d2_renderpolyline2
d2_renderquad
d2_rendertri
d2_rendertrifan
d2_rendertrilist
d2_rendertristrip
d2_renderwedge
+ +
d2_alpha d2_getalpha(d2_device *handle)
Query constant alpha from selected context.
d2_u32 d2_getalphablendmodedst(d2_device *handle)
Query destination blend factor for alpha channel blending from selected context.
d2_u8 d2_getalphablendmodeflags(d2_device *handle)
Query alpha blend flags from selected context.
d2_u32 d2_getalphablendmodesrc(d2_device *handle)
Query source blend factor for alpha channel blending from selected context.
d2_alpha d2_getalphaex(d2_device *handle,
d2_s32 index)
Query constant alpha from selected context.
d2_u8 d2_getalphamode(d2_device *handle)
Query alpha source from selected context.
d2_s32 d2_getantialiasing(d2_device *handle)
Query antialiasing setting from selected context.
d2_u32 d2_getblendmodedst(d2_device *handle)
Query destination blend factor from selected context.
d2_u32 d2_getblendmodesrc(d2_device *handle)
Query source blend factor from selected context.
d2_width d2_getblur(d2_device *handle)
Query blurring factor from selected context.
d2_s32 d2_getcliprect(d2_device *handle,
d2_border *xmin,
d2_border *ymin,
d2_border *xmax,
d2_border *ymax)
Get the clipping rectangle.
d2_color d2_getcolor(d2_device *handle,
d2_s32 index)
Query a color from selected context.
d2_context * d2_getcontext(
   d2_device *handle,
   d2_s32 mode
) /* PRQA S 3673 */ /* $Misra: #NOT_CONST_IN_DEBUG_BUILD $*/
Get a pointer to an currently active context.
d2_u32 d2_getdlistblockcount(d2_device *handle)
Get number of blocks of default displaylist (writelist).
d2_u32 d2_getdlistblocksize(const d2_device *handle)
Get blocksize of default displaylist.
d2_s32 d2_geterror(const d2_device *handle)
Query device error information.
const d2_char * d2_geterrorstring(const d2_device *handle)
Query detailed device error information.
d2_u8 d2_getfillmode(d2_device *handle)
Query fillmode from selected context.
d2_s32 d2_getframebuffer(d2_device *handle,
void **ptr,
d2_s32 *pitch,
d2_u32 *width,
d2_u32 *height,
d2_s32 *format)
Get information about the rendering target
d2_u8 d2_getlinecap(d2_device *handle)
Query lineend style from selected context.
d2_u8 d2_getlinejoin(d2_device *handle)
Query polyline connection style from selected context.
d2_pattern d2_getpattern(d2_device *handle)
Query pattern bitmask from selected context.
d2_alpha d2_getpatternalpha(d2_device *handle,
d2_s32 index)
Query pattern transparency from selected context.
d2_u32 d2_getpatternmode(d2_device *handle)
Query pattern addressing details.
d2_s32 d2_getpatternsize(d2_device *handle)
Query pattern bitmask size.
d2_slong d2_getperfcountvalue(d2_device *handle,
d2_u32 counter)
Get the current performance counter value.
d2_renderbuffer * d2_getrenderbuffer(d2_device *handle,
d2_s32 index)
Return internal renderbuffers.
d2_u32 d2_getrenderbuffersize(d2_device *handle,
d2_renderbuffer *rb)
Query the number of allocated display list entries.
d2_u32 d2_getrendermode(const d2_device *handle)
Get the rendering mode.
d2_u32 d2_getrevisionhw(const d2_device *handle)
Query hw revisionID.
const d2_char * d2_getrevisionstringhw(const d2_device *handle)
Query hw revisionID string.
d2_alpha d2_gettexopparam1(d2_device *handle,
d2_u32 index)
Query texture operation parameter p1.
d2_alpha d2_gettexopparam2(d2_device *handle,
d2_u32 index)
Query texture operation parameter p2.
d2_u8 d2_gettextureoperationa(d2_device *handle)
Query texture operation for alpha channel.
d2_u8 d2_gettextureoperationb(d2_device *handle)
Query texture operation for blue channel.
d2_u8 d2_gettextureoperationg(d2_device *handle)
Query texture operation for green channel.
d2_u8 d2_gettextureoperationr(d2_device *handle)
Query texture operation for red channel.
d2_s32 d2_getversion(void)
Query versionID (device independent)
const d2_char * d2_getversionstring(void)
Query versionID string (device independent)
+ + + +
d2_s32 d2_inithw(d2_device *handle,
d2_u32 flags)
Initialize hardware for working with specified device.
+ + + +
d2_s32 d2_layermerge(d2_device *handle)
Join outline and solid parts of currently selected renderbuffer.
d1_device * d2_level1interface(const d2_device *handle)
Get the lowlevel device handle currently used by the d2_device.
d2_s32 d2_lowlocalmemmode(d2_device *handle,
d2_u32 dlistblockfactor,
d2_u32 dlistblocks)
Enable and configure the ‘low localmem’ mode.
+ + + +
multiply two 32-bit variables and return a 64bit value
void d2_mul3264(d2_s32 a,
const d2_int64 *b,
d2_int64 *res)
multiply two a 32bit varibales with a 64bit one and return a 64bit result
+ + + +
d2_context * d2_newcontext(d2_device *handle)
Create new context (used to store render settings).
d2_renderbuffer * d2_newrenderbuffer(d2_device *handle,
d2_u32 initialsize,
d2_u32 stepsize)
Create a new renderbuffer.
+ + + +
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
d2_s32 d2_outlinecontext(d2_device *handle,
d2_context *ctx)
Define the outline rendering context.
d2_s32 d2_outlinewidth(d2_device *handle,
d2_width width)
Define the width of geometry outlines.
+ + + +
D2_EXTERN d2_u32 d2_pow2mask(d2_u32 x)
Find next larger power of two minus 1
+ + + +
extern d2_s32 d2_relocateframe(d2_device *handle,
const void *ptr)
Change framebuffer for render commands already issued.
d2_s32 d2_renderbox(d2_device *handle,
d2_point x1,
d2_point y1,
d2_width w,
d2_width h)
Render a rectangle.
d2_s32 d2_rendercircle(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w)
Render a circle or circle ring.
void d2_rendercircle_no_hilimiterprecision(d2_device *handle,
d2_u32 flag)
Enable or disable the high limiter precision feature of the latest D/AVE 2D renderer for drawing blurred circles with higher image quality.
d2_s32 d2_renderline(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w,
d2_u32 flags)
Render a wide line.
d2_s32 d2_renderline2(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w1,
d2_width w2,
d2_u32 flags)
Render a wide line with 2 different widths.
d2_s32 d2_renderpolygon(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_u32 flags)
Render a convex polygon
d2_s32 d2_renderpolyline(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_width w,
d2_u32 flags)
Render a polyline
d2_s32 d2_renderpolyline2(d2_device *handle,
const d2_point *data,
d2_u32 count,
const d2_width *w,
d2_u32 flags)
Render a polyline with multiple width
d2_s32 d2_renderquad(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_point x4,
d2_point y4,
d2_u32 flags)
Render a quadrangle.
d2_s32 d2_rendertri(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_u32 flags)
Render a triangle.
d2_s32 d2_rendertrifan(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle fan
d2_s32 d2_rendertrilist(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle list.
d2_s32 d2_rendertristrip(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle strip.
d2_s32 d2_renderwedge(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w,
d2_s32 nx1,
d2_s32 ny1,
d2_s32 nx2,
d2_s32 ny2,
d2_u32 flags)
Render a circle arc or circle ring arc.
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/Functions3.html b/src/drivers/dave2d/docs/index/Functions3.html new file mode 100644 index 000000000..6f905e6a1 --- /dev/null +++ b/src/drivers/dave2d/docs/index/Functions3.html @@ -0,0 +1,33 @@ + + +Function Index + + + + + + + + + +
Function Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
S
d2_selectcontext
d2_selectrenderbuffer
d2_selectrendermode
d2_setalpha
d2_setalphablendmode
d2_setalphablendmodeex
d2_setalphaex
d2_setalphagradient
d2_setalphamode
d2_setantialiasing
d2_setblendmode
d2_setblitsrc
d2_setblur
d2_setcircleextend
d2_setclipgradient
d2_setcolor
d2_setcolorkey
d2_setdlistblocksize
d2_setfillmode
d2_setlinecap
d2_setlinejoin
d2_setlinepattern
d2_setmiterlimit
d2_setpattern
d2_setpatternalpha
d2_setpatternmode
d2_setpatternparam
d2_setpatternsize
d2_setperfcountevent
d2_setperfcountvalue
d2_settexclut
d2_settexclut_format
d2_settexclut_offset
d2_settexclut_part
d2_settexelcenter
d2_settexopparam
d2_settexture
d2_settexturemapping
d2_settexturemode
d2_settextureoperation
d2_shadowoffset
d2_shiftleft64
d2_shiftright64
d2_solidcontext
d2_sqrt
d2_startframe
d2_sub64
+ +
d2_s32 d2_selectcontext(d2_device *handle,
d2_context *ctx)
Make a rendering context active (all following property set operations will use it)
d2_s32 d2_selectrenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)
Choose a renderbuffer for writing.
d2_s32 d2_selectrendermode(d2_device *handle,
d2_u32 mode)
Select a rendering mode.
d2_s32 d2_setalpha(d2_device *handle,
d2_alpha alpha)
set constant alpha value
d2_s32 d2_setalphablendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)
Choose blendmode for alpha channel.
d2_s32 d2_setalphablendmodeex(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor,
d2_u32 blendflags)
Choose blendmode for alpha channel.
d2_s32 d2_setalphaex(d2_device *handle,
d2_s32 index,
d2_alpha alpha)
set constant alpha value
d2_s32 d2_setalphagradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_point dx,
d2_point dy)
Define an alpha gradient.
d2_s32 d2_setalphamode(d2_device *handle,
d2_u32 mode)
Choose alpha source.
d2_s32 d2_setantialiasing(d2_device *handle,
d2_s32 enable)
Globally disable or enable antialiasing.
d2_s32 d2_setblendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)
Choose blendmode for RGB.
d2_s32 d2_setblitsrc(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for blit operation.
d2_s32 d2_setblur(d2_device *handle,
d2_width blur)
Set global blurring factor.
d2_s32 d2_setcircleextend(d2_device *handle,
d2_width offset)
Increase bbox of circles.
d2_s32 d2_setclipgradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_s32 nx,
d2_s32 ny,
d2_u32 flags)
Define an alpha gradient for clipping.
d2_s32 d2_setcolor(d2_device *handle,
d2_s32 index,
d2_color color)
Set color registers.
d2_s32 d2_setcolorkey(d2_device *handle,
d2_s32 enable,
d2_color color_key)
Set the color for color keying.
d2_s32 d2_setdlistblocksize(d2_device *handle,
d2_u32 size)
Set blocksize for default displaylists.
d2_s32 d2_setfillmode(d2_device *handle,
d2_u32 mode)
Select fillmode (solid,patter,texture,..)
d2_s32 d2_setlinecap(d2_device *handle,
d2_u32 mode)
Specify lineend style.
d2_s32 d2_setlinejoin(d2_device *handle,
d2_u32 mode)
Specify polyline connection style.
d2_s32 d2_setlinepattern(d2_device *handle,
d2_width scale,
d2_s32 offset)
Specify parameters for aligned patterns.
d2_s32 d2_setmiterlimit(d2_device *handle,
d2_width miter)
Clipping distance for miter polyline connections.
d2_s32 d2_setpattern(d2_device *handle,
d2_pattern pattern)
Specify pattern bitmask.
d2_s32 d2_setpatternalpha(d2_device *handle,
d2_s32 index,
d2_alpha alpha)
Specify pattern transparency.
d2_s32 d2_setpatternmode(d2_device *handle,
d2_u32 mode)
Define pattern addressing details.
d2_s32 d2_setpatternparam(d2_device *handle,
d2_point x,
d2_point y,
d2_width dx,
d2_width dy)
Define mapping of pattern to geometry.
d2_s32 d2_setpatternsize(d2_device *handle,
d2_s32 size)
Define pattern size.
d2_s32 d2_setperfcountevent(d2_device *handle,
d2_u32 counter,
d2_u32 event)
Set the event to be counted by performance counter.
d2_s32 d2_setperfcountvalue(d2_device *handle,
d2_u32 counter,
d2_slong value)
Set the current performance counter value.
d2_s32 d2_settexclut(d2_device *handle,
d2_color *clut)
Set texture colour palette pointer.
d2_s32 d2_settexclut_format(d2_device *handle,
d2_u32 format)
Set color format of texture CLUT.
d2_s32 d2_settexclut_offset(d2_device *handle,
d2_u32 offset)
Set index offset for indexed texture formats.
d2_s32 d2_settexclut_part(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)
Set a part of the color lookup table.
d2_s32 d2_settexelcenter(d2_device *handle,
d2_point x,
d2_point y)
Set texel center offset.
d2_s32 d2_settexopparam(d2_device *handle,
d2_u32 index,
d2_u32 p1,
d2_u32 p2)
Set texture operation parameter.
d2_s32 d2_settexture(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for texture mapping.
d2_s32 d2_settexturemapping(d2_device *handle,
d2_point x,
d2_point y,
d2_s32 u0,
d2_s32 v0,
d2_s32 dxu,
d2_s32 dyu,
d2_s32 dxv,
d2_s32 dyv)
Define texture mapping.
d2_s32 d2_settexturemode(d2_device *handle,
d2_u32 mode)
Define texture addressing details.
d2_s32 d2_settextureoperation(d2_device *handle,
d2_u8 amode,
d2_u8 rmode,
d2_u8 gmode,
d2_u8 bmode)
Choose texture operation for each channel.
d2_s32 d2_shadowoffset(d2_device *handle,
d2_point x,
d2_point y)
Define the offset of geometry shadows.
void d2_shiftleft64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)
Shift left a variable of type d2_int64
void d2_shiftright64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)
Shift right a variable of type d2_int64
d2_s32 d2_solidcontext(d2_device *handle,
d2_context *ctx)
Define the solid rendering context.
D2_EXTERN d2_s32 d2_sqrt(d2_u32 x)
Minimalistic 32->16 bit integer square root (no hw divide/multiply needed) unrolled for speed.
d2_s32 d2_startframe(d2_device *handle)
Mark the begin of a scene.
void d2_sub64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)
Substraction of 2 64bit value
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/Functions4.html b/src/drivers/dave2d/docs/index/Functions4.html new file mode 100644 index 000000000..173c7dc2d --- /dev/null +++ b/src/drivers/dave2d/docs/index/Functions4.html @@ -0,0 +1,37 @@ + + +Function Index + + + + + + + + + +
Function Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
U
d2_utility_fbblitcopy
d2_utility_maptriangle
d2_utility_perspectivewarp
W
d2_writetexclut_direct
+ +
d2_s32 d2_utility_fbblitcopy(d2_device *handle,
d2_u16 width,
d2_u16 height,
d2_blitpos srcx,
d2_blitpos srcy,
d2_blitpos dstx,
d2_blitpos dsty,
d2_u32 flags)
Copy a rectangular part inside the current framebuffer.
d2_s32 d2_utility_maptriangle(d2_device *handle,
const d2_f32 *points,
const d2_f32 *uvs)
This function uses d2_settexturemapping to map a texture on a triangle.
d2_s32 d2_utility_perspectivewarp(d2_device *handle,
d2_u16 srcwidth,
d2_u16 srcheight,
d2_s16 srcx,
d2_s16 srcy,
d2_s16 dstwidth,
d2_s16 dstheight,
d2_s16 dstx,
d2_s16 dsty,
d2_u16 wt)
Copies an image in perspective manner to a destination rectangle.
+ + + +
d2_s32 d2_writetexclut_direct(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)
Write a part of the color lookup table directly to the render buffer.
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/General.html b/src/drivers/dave2d/docs/index/General.html new file mode 100644 index 000000000..e2c72c49c --- /dev/null +++ b/src/drivers/dave2d/docs/index/General.html @@ -0,0 +1,53 @@ + + +Index + + + + + + + + + +
Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
A
d2_add64
d2_adddlist
B
 Basic Functions
 Basic Types
 BLIT Attributes Writes
 Blit Functions
 BLIT Rendering Functions
d2_blitcopy
 Buffer Rendering
C
d2_cast32to64
d2_cast64to32
d2_clear
 Clipping
d2_cliprect
d2_closedevice
 Coding conventions
d2_commandspending
 Concept
 Context Attribute Queries
 Context Attribute Writes
 Context Functions
 Context Management
 Coordinate range limitations
D
 d2_alpha
 d2_blitpos
 d2_border
 D2_CEIL16(x)
 D2_CEIL4(x)
 d2_color
 d2_context
 d2_device
 D2_EPSILON
 D2_FIX16(x)
 D2_FIX4(x)
 D2_FLOOR16(x)
 D2_FLOOR4(x)
 D2_FRAC16(x)
 D2_FRAC4(x)
 D2_INT16(x)
 D2_INT4(x)
 d2_pattern
 d2_point
 d2_renderbuffer
 d2_width
d2_deinithw
 Device management
 Direct Rendering
d2_div6432
 Dlist Functions
 Driver Overview
d2_dumprenderbuffer
E
d2_endframe
 Errorcodes
d2_executedlist
d2_executerenderbuffer
F
 Fixedpoint Macros
d2_flushframe
d2_framebuffer
 Framebuffer management
 Framebuffer size limitations
d2_freecontext
d2_freedumpedbuffer
d2_freerenderbuffer
 Functions
 functions for 64bit operations
+ +
void d2_add64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)
Addition of 2 64bit value
d2_s32 d2_adddlist(d2_device *handle,
void *address,
d2_s32 size,
d2_u32 flags)
Add an already prepared display list to the current render buffer.
+ + + +
Driver device management and hardware initialization / shutdown.
Note that several types represent fixedpoint numbers.
BLock Image Transfer operations
d2_s32 d2_blitcopy(d2_device *handle,
d2_s32 srcwidth,
d2_s32 srcheight,
d2_blitpos srcx,
d2_blitpos srcy,
d2_width dstwidth,
d2_width dstheight,
d2_point dstx,
d2_point dsty,
d2_u32 flags)
Copy rectangle part of the source into destination.
+ + + +
void d2_cast32to64(d2_s32 par,
d2_int64 *res)
Cast an 32bit integer to 64bit variable
d2_s32 d2_cast64to32(const d2_int64 *par)
Cast an 64bit variable to a32bit variable
d2_s32 d2_clear(d2_device *handle,
d2_color color)
Render fill the entire framebuffer with a single color.
d2_s32 d2_cliprect(d2_device *handle,
d2_border xmin,
d2_border ymin,
d2_border xmax,
d2_border ymax)
Specify the clipping rectangle.
d2_s32 d2_closedevice(d2_device *handle)
Destroy a device handle.
Quickinfo about Dave2d Driver implementation
d2_s32 d2_commandspending(d2_device *handle)
Check if there are pending commands in the current displaylist.
Basic objects and principles
Modify material settings
API interface coordinates are limited to the range -2048 to 2047.
+ + + +
unsigned char
unsigned short
short
n:16 fixedpoint unsigned ceil (round towards +inf)
n:4 fixedpoint unsigned ceil (round towards +inf)
unsigned long
void
void
Smallest representable positive number (all fixedpoint formats)
integer to n:16 fixedpoint conversion
Integer to n:4 fixedpoint conversion
n:16 fixedpoint unsigned floor (round towards -inf)
n:4 fixedpoint unsigned floor (round towards -inf)
n:16 fixedpoint fractional part only
n:4 fixedpoint fractional part only
n:16 to integer conversion
n:4 to integer conversion
unsigned long
short (fixedpoint)
void
short (fixedpoint)
d2_s32 d2_deinithw(d2_device *handle)
Unlink hardware currently bound by specified device.
void d2_div6432(const d2_int64 *dividend,
d2_s32 divisor,
d2_int64 *res)
division of 64bit value by a 32bit.
Overview of D/AVE 2D driver V3.14
d2_s32 d2_dumprenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
void **rdata,
d2_s32 *rsize)
Copy the content of a renderbuffer into user memory.
+ + + +
d2_s32 d2_endframe(d2_device *handle)
Mark the end of a scene.
List of all dave driver errorcodes.
d2_s32 d2_executedlist(d2_device *handle,
const void *address,
d2_u32 flags)
Execute an already prepared display list.
d2_s32 d2_executerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer,
d2_u32 flags)
Render the content of a renderbuffer.
+ + + +
d2_s32 d2_flushframe(d2_device *handle)
Wait for current rendering to end.
d2_s32 d2_framebuffer(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_u32 width,
d2_u32 height,
d2_s32 format)
Specify the rendering target.
The framebuffer size is limited to 2048x2048 pixels.
d2_s32 d2_freecontext(d2_device *handle,
d2_context *ctx)
Release Context.
d2_s32 d2_freedumpedbuffer(d2_device *handle,
void *data)
free a chunk of memory returned from d2_dumprenderbuffer.
d2_s32 d2_freerenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)
Destroy and free a renderbuffer.
This module contains all the necessary function for 64bit operation in case the chosen compiler does not support long long.
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/General2.html b/src/drivers/dave2d/docs/index/General2.html new file mode 100644 index 000000000..7521d54cd --- /dev/null +++ b/src/drivers/dave2d/docs/index/General2.html @@ -0,0 +1,61 @@ + + +Index + + + + + + + + + +
Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
G
d2_getalpha
d2_getalphablendmodedst
d2_getalphablendmodeflags
d2_getalphablendmodesrc
d2_getalphaex
d2_getalphamode
d2_getantialiasing
d2_getblendmodedst
d2_getblendmodesrc
d2_getblur
d2_getcliprect
d2_getcolor
d2_getcontext
d2_getdlistblockcount
d2_getdlistblocksize
d2_geterror
d2_geterrorstring
d2_getfillmode
d2_getframebuffer
d2_getlinecap
d2_getlinejoin
d2_getpattern
d2_getpatternalpha
d2_getpatternmode
d2_getpatternsize
d2_getperfcountvalue
d2_getrenderbuffer
d2_getrenderbuffersize
d2_getrendermode
d2_getrevisionhw
d2_getrevisionstringhw
d2_gettexopparam1
d2_gettexopparam2
d2_gettextureoperationa
d2_gettextureoperationb
d2_gettextureoperationg
d2_gettextureoperationr
d2_getversion
d2_getversionstring
I
d2_inithw
L
d2_layermerge
d2_level1interface
 Limitations
d2_lowlocalmemmode
M
 Math Functions
d2_mul3232to64
d2_mul3264
N
d2_newcontext
d2_newrenderbuffer
O
 Object/primitive size limitations
d2_opendevice
d2_outlinecontext
d2_outlinewidth
P
 Performance counting
d2_pow2mask
 Profiling
R
d2_relocateframe
 Render Buffers
d2_renderbox
 Renderbuffer Management
d2_rendercircle
d2_rendercircle_no_hilimiterprecision
 Rendering Functions
 Rendering Mode
d2_renderline
d2_renderline2
d2_renderpolygon
d2_renderpolyline
d2_renderpolyline2
d2_renderquad
d2_rendertri
d2_rendertrifan
d2_rendertrilist
d2_rendertristrip
d2_renderwedge
+ +
d2_alpha d2_getalpha(d2_device *handle)
Query constant alpha from selected context.
d2_u32 d2_getalphablendmodedst(d2_device *handle)
Query destination blend factor for alpha channel blending from selected context.
d2_u8 d2_getalphablendmodeflags(d2_device *handle)
Query alpha blend flags from selected context.
d2_u32 d2_getalphablendmodesrc(d2_device *handle)
Query source blend factor for alpha channel blending from selected context.
d2_alpha d2_getalphaex(d2_device *handle,
d2_s32 index)
Query constant alpha from selected context.
d2_u8 d2_getalphamode(d2_device *handle)
Query alpha source from selected context.
d2_s32 d2_getantialiasing(d2_device *handle)
Query antialiasing setting from selected context.
d2_u32 d2_getblendmodedst(d2_device *handle)
Query destination blend factor from selected context.
d2_u32 d2_getblendmodesrc(d2_device *handle)
Query source blend factor from selected context.
d2_width d2_getblur(d2_device *handle)
Query blurring factor from selected context.
d2_s32 d2_getcliprect(d2_device *handle,
d2_border *xmin,
d2_border *ymin,
d2_border *xmax,
d2_border *ymax)
Get the clipping rectangle.
d2_color d2_getcolor(d2_device *handle,
d2_s32 index)
Query a color from selected context.
d2_context * d2_getcontext(
   d2_device *handle,
   d2_s32 mode
) /* PRQA S 3673 */ /* $Misra: #NOT_CONST_IN_DEBUG_BUILD $*/
Get a pointer to an currently active context.
d2_u32 d2_getdlistblockcount(d2_device *handle)
Get number of blocks of default displaylist (writelist).
d2_u32 d2_getdlistblocksize(const d2_device *handle)
Get blocksize of default displaylist.
d2_s32 d2_geterror(const d2_device *handle)
Query device error information.
const d2_char * d2_geterrorstring(const d2_device *handle)
Query detailed device error information.
d2_u8 d2_getfillmode(d2_device *handle)
Query fillmode from selected context.
d2_s32 d2_getframebuffer(d2_device *handle,
void **ptr,
d2_s32 *pitch,
d2_u32 *width,
d2_u32 *height,
d2_s32 *format)
Get information about the rendering target
d2_u8 d2_getlinecap(d2_device *handle)
Query lineend style from selected context.
d2_u8 d2_getlinejoin(d2_device *handle)
Query polyline connection style from selected context.
d2_pattern d2_getpattern(d2_device *handle)
Query pattern bitmask from selected context.
d2_alpha d2_getpatternalpha(d2_device *handle,
d2_s32 index)
Query pattern transparency from selected context.
d2_u32 d2_getpatternmode(d2_device *handle)
Query pattern addressing details.
d2_s32 d2_getpatternsize(d2_device *handle)
Query pattern bitmask size.
d2_slong d2_getperfcountvalue(d2_device *handle,
d2_u32 counter)
Get the current performance counter value.
d2_renderbuffer * d2_getrenderbuffer(d2_device *handle,
d2_s32 index)
Return internal renderbuffers.
d2_u32 d2_getrenderbuffersize(d2_device *handle,
d2_renderbuffer *rb)
Query the number of allocated display list entries.
d2_u32 d2_getrendermode(const d2_device *handle)
Get the rendering mode.
d2_u32 d2_getrevisionhw(const d2_device *handle)
Query hw revisionID.
const d2_char * d2_getrevisionstringhw(const d2_device *handle)
Query hw revisionID string.
d2_alpha d2_gettexopparam1(d2_device *handle,
d2_u32 index)
Query texture operation parameter p1.
d2_alpha d2_gettexopparam2(d2_device *handle,
d2_u32 index)
Query texture operation parameter p2.
d2_u8 d2_gettextureoperationa(d2_device *handle)
Query texture operation for alpha channel.
d2_u8 d2_gettextureoperationb(d2_device *handle)
Query texture operation for blue channel.
d2_u8 d2_gettextureoperationg(d2_device *handle)
Query texture operation for green channel.
d2_u8 d2_gettextureoperationr(d2_device *handle)
Query texture operation for red channel.
d2_s32 d2_getversion(void)
Query versionID (device independent)
const d2_char * d2_getversionstring(void)
Query versionID string (device independent)
+ + + +
d2_s32 d2_inithw(d2_device *handle,
d2_u32 flags)
Initialize hardware for working with specified device.
+ + + +
d2_s32 d2_layermerge(d2_device *handle)
Join outline and solid parts of currently selected renderbuffer.
d1_device * d2_level1interface(const d2_device *handle)
Get the lowlevel device handle currently used by the d2_device.
d2_s32 d2_lowlocalmemmode(d2_device *handle,
d2_u32 dlistblockfactor,
d2_u32 dlistblocks)
Enable and configure the ‘low localmem’ mode.
+ + + +
Package of useful macros and functions e.g.
multiply two 32-bit variables and return a 64bit value
void d2_mul3264(d2_s32 a,
const d2_int64 *b,
d2_int64 *res)
multiply two a 32bit varibales with a 64bit one and return a 64bit result
+ + + +
d2_context * d2_newcontext(d2_device *handle)
Create new context (used to store render settings).
d2_renderbuffer * d2_newrenderbuffer(d2_device *handle,
d2_u32 initialsize,
d2_u32 stepsize)
Create a new renderbuffer.
+ + + +
Object sizes are limited to 1024x1024 pixels.
d2_device * d2_opendevice(d2_u32 flags)
Create a new device handle.
d2_s32 d2_outlinecontext(d2_device *handle,
d2_context *ctx)
Define the outline rendering context.
d2_s32 d2_outlinewidth(d2_device *handle,
d2_width width)
Define the width of geometry outlines.
+ + + +
D2_EXTERN d2_u32 d2_pow2mask(d2_u32 x)
Find next larger power of two minus 1
Performance measurement counter functions
+ + + +
extern d2_s32 d2_relocateframe(d2_device *handle,
const void *ptr)
Change framebuffer for render commands already issued.
Renderbuffers (similar in concept to OpenGL display lists) are the main interface between driver and hardware.
d2_s32 d2_renderbox(d2_device *handle,
d2_point x1,
d2_point y1,
d2_width w,
d2_width h)
Render a rectangle.
d2_s32 d2_rendercircle(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w)
Render a circle or circle ring.
void d2_rendercircle_no_hilimiterprecision(d2_device *handle,
d2_u32 flag)
Enable or disable the high limiter precision feature of the latest D/AVE 2D renderer for drawing blurred circles with higher image quality.
There is a rendering function for each supported geometric shape.
d2_s32 d2_renderline(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w,
d2_u32 flags)
Render a wide line.
d2_s32 d2_renderline2(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_width w1,
d2_width w2,
d2_u32 flags)
Render a wide line with 2 different widths.
d2_s32 d2_renderpolygon(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_u32 flags)
Render a convex polygon
d2_s32 d2_renderpolyline(d2_device *handle,
const d2_point *data,
d2_u32 count,
d2_width w,
d2_u32 flags)
Render a polyline
d2_s32 d2_renderpolyline2(d2_device *handle,
const d2_point *data,
d2_u32 count,
const d2_width *w,
d2_u32 flags)
Render a polyline with multiple width
d2_s32 d2_renderquad(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_point x4,
d2_point y4,
d2_u32 flags)
Render a quadrangle.
d2_s32 d2_rendertri(d2_device *handle,
d2_point x1,
d2_point y1,
d2_point x2,
d2_point y2,
d2_point x3,
d2_point y3,
d2_u32 flags)
Render a triangle.
d2_s32 d2_rendertrifan(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle fan
d2_s32 d2_rendertrilist(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle list.
d2_s32 d2_rendertristrip(d2_device *handle,
const d2_point *data,
const d2_u32 *flags,
d2_u32 count)
Render a polygon from a triangle strip.
d2_s32 d2_renderwedge(d2_device *handle,
d2_point x,
d2_point y,
d2_width r,
d2_width w,
d2_s32 nx1,
d2_s32 ny1,
d2_s32 nx2,
d2_s32 ny2,
d2_u32 flags)
Render a circle arc or circle ring arc.
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/General3.html b/src/drivers/dave2d/docs/index/General3.html new file mode 100644 index 000000000..33e4df74c --- /dev/null +++ b/src/drivers/dave2d/docs/index/General3.html @@ -0,0 +1,33 @@ + + +Index + + + + + + + + + +
Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
S
 Sample code
d2_selectcontext
d2_selectrenderbuffer
d2_selectrendermode
d2_setalpha
d2_setalphablendmode
d2_setalphablendmodeex
d2_setalphaex
d2_setalphagradient
d2_setalphamode
d2_setantialiasing
d2_setblendmode
d2_setblitsrc
d2_setblur
d2_setcircleextend
d2_setclipgradient
d2_setcolor
d2_setcolorkey
d2_setdlistblocksize
d2_setfillmode
d2_setlinecap
d2_setlinejoin
d2_setlinepattern
d2_setmiterlimit
d2_setpattern
d2_setpatternalpha
d2_setpatternmode
d2_setpatternparam
d2_setpatternsize
d2_setperfcountevent
d2_setperfcountvalue
d2_settexclut
d2_settexclut_format
d2_settexclut_offset
d2_settexclut_part
d2_settexelcenter
d2_settexopparam
d2_settexture
d2_settexturemapping
d2_settexturemode
d2_settextureoperation
d2_shadowoffset
d2_shiftleft64
d2_shiftright64
d2_solidcontext
d2_sqrt
d2_startframe
 Static functions
d2_sub64
+ +
Simple example of using the dave driver
d2_s32 d2_selectcontext(d2_device *handle,
d2_context *ctx)
Make a rendering context active (all following property set operations will use it)
d2_s32 d2_selectrenderbuffer(d2_device *handle,
d2_renderbuffer *buffer)
Choose a renderbuffer for writing.
d2_s32 d2_selectrendermode(d2_device *handle,
d2_u32 mode)
Select a rendering mode.
d2_s32 d2_setalpha(d2_device *handle,
d2_alpha alpha)
set constant alpha value
d2_s32 d2_setalphablendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)
Choose blendmode for alpha channel.
d2_s32 d2_setalphablendmodeex(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor,
d2_u32 blendflags)
Choose blendmode for alpha channel.
d2_s32 d2_setalphaex(d2_device *handle,
d2_s32 index,
d2_alpha alpha)
set constant alpha value
d2_s32 d2_setalphagradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_point dx,
d2_point dy)
Define an alpha gradient.
d2_s32 d2_setalphamode(d2_device *handle,
d2_u32 mode)
Choose alpha source.
d2_s32 d2_setantialiasing(d2_device *handle,
d2_s32 enable)
Globally disable or enable antialiasing.
d2_s32 d2_setblendmode(d2_device *handle,
d2_u32 srcfactor,
d2_u32 dstfactor)
Choose blendmode for RGB.
d2_s32 d2_setblitsrc(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for blit operation.
d2_s32 d2_setblur(d2_device *handle,
d2_width blur)
Set global blurring factor.
d2_s32 d2_setcircleextend(d2_device *handle,
d2_width offset)
Increase bbox of circles.
d2_s32 d2_setclipgradient(d2_device *handle,
d2_s32 index,
d2_point x,
d2_point y,
d2_s32 nx,
d2_s32 ny,
d2_u32 flags)
Define an alpha gradient for clipping.
d2_s32 d2_setcolor(d2_device *handle,
d2_s32 index,
d2_color color)
Set color registers.
d2_s32 d2_setcolorkey(d2_device *handle,
d2_s32 enable,
d2_color color_key)
Set the color for color keying.
d2_s32 d2_setdlistblocksize(d2_device *handle,
d2_u32 size)
Set blocksize for default displaylists.
d2_s32 d2_setfillmode(d2_device *handle,
d2_u32 mode)
Select fillmode (solid,patter,texture,..)
d2_s32 d2_setlinecap(d2_device *handle,
d2_u32 mode)
Specify lineend style.
d2_s32 d2_setlinejoin(d2_device *handle,
d2_u32 mode)
Specify polyline connection style.
d2_s32 d2_setlinepattern(d2_device *handle,
d2_width scale,
d2_s32 offset)
Specify parameters for aligned patterns.
d2_s32 d2_setmiterlimit(d2_device *handle,
d2_width miter)
Clipping distance for miter polyline connections.
d2_s32 d2_setpattern(d2_device *handle,
d2_pattern pattern)
Specify pattern bitmask.
d2_s32 d2_setpatternalpha(d2_device *handle,
d2_s32 index,
d2_alpha alpha)
Specify pattern transparency.
d2_s32 d2_setpatternmode(d2_device *handle,
d2_u32 mode)
Define pattern addressing details.
d2_s32 d2_setpatternparam(d2_device *handle,
d2_point x,
d2_point y,
d2_width dx,
d2_width dy)
Define mapping of pattern to geometry.
d2_s32 d2_setpatternsize(d2_device *handle,
d2_s32 size)
Define pattern size.
d2_s32 d2_setperfcountevent(d2_device *handle,
d2_u32 counter,
d2_u32 event)
Set the event to be counted by performance counter.
d2_s32 d2_setperfcountvalue(d2_device *handle,
d2_u32 counter,
d2_slong value)
Set the current performance counter value.
d2_s32 d2_settexclut(d2_device *handle,
d2_color *clut)
Set texture colour palette pointer.
d2_s32 d2_settexclut_format(d2_device *handle,
d2_u32 format)
Set color format of texture CLUT.
d2_s32 d2_settexclut_offset(d2_device *handle,
d2_u32 offset)
Set index offset for indexed texture formats.
d2_s32 d2_settexclut_part(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)
Set a part of the color lookup table.
d2_s32 d2_settexelcenter(d2_device *handle,
d2_point x,
d2_point y)
Set texel center offset.
d2_s32 d2_settexopparam(d2_device *handle,
d2_u32 index,
d2_u32 p1,
d2_u32 p2)
Set texture operation parameter.
d2_s32 d2_settexture(d2_device *handle,
void *ptr,
d2_s32 pitch,
d2_s32 width,
d2_s32 height,
d2_u32 format)
Specify the source for texture mapping.
d2_s32 d2_settexturemapping(d2_device *handle,
d2_point x,
d2_point y,
d2_s32 u0,
d2_s32 v0,
d2_s32 dxu,
d2_s32 dyu,
d2_s32 dxv,
d2_s32 dyv)
Define texture mapping.
d2_s32 d2_settexturemode(d2_device *handle,
d2_u32 mode)
Define texture addressing details.
d2_s32 d2_settextureoperation(d2_device *handle,
d2_u8 amode,
d2_u8 rmode,
d2_u8 gmode,
d2_u8 bmode)
Choose texture operation for each channel.
d2_s32 d2_shadowoffset(d2_device *handle,
d2_point x,
d2_point y)
Define the offset of geometry shadows.
void d2_shiftleft64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)
Shift left a variable of type d2_int64
void d2_shiftright64(const d2_int64 *var,
d2_s32 index,
d2_int64 *res)
Shift right a variable of type d2_int64
d2_s32 d2_solidcontext(d2_device *handle,
d2_context *ctx)
Define the solid rendering context.
D2_EXTERN d2_s32 d2_sqrt(d2_u32 x)
Minimalistic 32->16 bit integer square root (no hw divide/multiply needed) unrolled for speed.
d2_s32 d2_startframe(d2_device *handle)
Mark the begin of a scene.
void d2_sub64(const d2_int64 *a,
const d2_int64 *b,
d2_int64 *res)
Substraction of 2 64bit value
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/General4.html b/src/drivers/dave2d/docs/index/General4.html new file mode 100644 index 000000000..6bde5d2a4 --- /dev/null +++ b/src/drivers/dave2d/docs/index/General4.html @@ -0,0 +1,45 @@ + + +Index + + + + + + + + + +
Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
T
 Texture Attribute Queries
 Texture Attribute Writes
 Texture Functions
 Texture size limitations
 Types
U
 Utility Functions
d2_utility_fbblitcopy
d2_utility_maptriangle
d2_utility_perspectivewarp
V
 Viewport Functions
W
d2_writetexclut_direct
+ +
Modify texture mapping settings
Texture sizes are limited to 1024x1024 texels in general.
+ + + +
Triangle mapping and perspective warp operations
d2_s32 d2_utility_fbblitcopy(d2_device *handle,
d2_u16 width,
d2_u16 height,
d2_blitpos srcx,
d2_blitpos srcy,
d2_blitpos dstx,
d2_blitpos dsty,
d2_u32 flags)
Copy a rectangular part inside the current framebuffer.
d2_s32 d2_utility_maptriangle(d2_device *handle,
const d2_f32 *points,
const d2_f32 *uvs)
This function uses d2_settexturemapping to map a texture on a triangle.
d2_s32 d2_utility_perspectivewarp(d2_device *handle,
d2_u16 srcwidth,
d2_u16 srcheight,
d2_s16 srcx,
d2_s16 srcy,
d2_s16 dstwidth,
d2_s16 dstheight,
d2_s16 dstx,
d2_s16 dsty,
d2_u16 wt)
Copies an image in perspective manner to a destination rectangle.
+ + + +
Framebuffer and view specific functions.
+ + + +
d2_s32 d2_writetexclut_direct(d2_device *handle,
const d2_color *clut_part,
d2_u32 start_index,
d2_u32 length)
Write a part of the color lookup table directly to the render buffer.
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/index/Types.html b/src/drivers/dave2d/docs/index/Types.html new file mode 100644 index 000000000..2ba6b88a0 --- /dev/null +++ b/src/drivers/dave2d/docs/index/Types.html @@ -0,0 +1,33 @@ + + +Type Index + + + + + + + + + +
Type Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
D
 d2_alpha
 d2_blitpos
 d2_border
 d2_color
 d2_context
 d2_device
 d2_pattern
 d2_point
 d2_renderbuffer
 d2_width
+ +
unsigned char
unsigned short
short
unsigned long
void
void
unsigned long
short (fixedpoint)
void
short (fixedpoint)
+ +
+ + + + + + + + + + + + \ No newline at end of file diff --git a/src/drivers/dave2d/docs/javascript/main.js b/src/drivers/dave2d/docs/javascript/main.js new file mode 100644 index 000000000..b008be99f --- /dev/null +++ b/src/drivers/dave2d/docs/javascript/main.js @@ -0,0 +1,841 @@ +// This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure +// Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL) +// Refer to License.txt for the complete details + +// This file may be distributed with documentation files generated by Natural Docs. +// Such documentation is not covered by Natural Docs' copyright and licensing, +// and may have its own copyright and distribution terms as decided by its author. + + +// +// Browser Styles +// ____________________________________________________________________________ + +var agt=navigator.userAgent.toLowerCase(); +var browserType; +var browserVer; + +if (agt.indexOf("opera") != -1) + { + browserType = "Opera"; + + if (agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1) + { browserVer = "Opera7"; } + else if (agt.indexOf("opera 8") != -1 || agt.indexOf("opera/8") != -1) + { browserVer = "Opera8"; } + else if (agt.indexOf("opera 9") != -1 || agt.indexOf("opera/9") != -1) + { browserVer = "Opera9"; } + } + +else if (agt.indexOf("applewebkit") != -1) + { + browserType = "Safari"; + + if (agt.indexOf("version/3") != -1) + { browserVer = "Safari3"; } + else if (agt.indexOf("safari/4") != -1) + { browserVer = "Safari2"; } + } + +else if (agt.indexOf("khtml") != -1) + { + browserType = "Konqueror"; + } + +else if (agt.indexOf("msie") != -1) + { + browserType = "IE"; + + if (agt.indexOf("msie 6") != -1) + { browserVer = "IE6"; } + else if (agt.indexOf("msie 7") != -1) + { browserVer = "IE7"; } + } + +else if (agt.indexOf("gecko") != -1) + { + browserType = "Firefox"; + + if (agt.indexOf("rv:1.7") != -1) + { browserVer = "Firefox1"; } + else if (agt.indexOf("rv:1.8)") != -1 || agt.indexOf("rv:1.8.0") != -1) + { browserVer = "Firefox15"; } + else if (agt.indexOf("rv:1.8.1") != -1) + { browserVer = "Firefox2"; } + } + + +// +// Support Functions +// ____________________________________________________________________________ + + +function GetXPosition(item) + { + var position = 0; + + if (item.offsetWidth != null) + { + while (item != document.body && item != null) + { + position += item.offsetLeft; + item = item.offsetParent; + }; + }; + + return position; + }; + + +function GetYPosition(item) + { + var position = 0; + + if (item.offsetWidth != null) + { + while (item != document.body && item != null) + { + position += item.offsetTop; + item = item.offsetParent; + }; + }; + + return position; + }; + + +function MoveToPosition(item, x, y) + { + // Opera 5 chokes on the px extension, so it can use the Microsoft one instead. + + if (item.style.left != null) + { + item.style.left = x + "px"; + item.style.top = y + "px"; + } + else if (item.style.pixelLeft != null) + { + item.style.pixelLeft = x; + item.style.pixelTop = y; + }; + }; + + +// +// Menu +// ____________________________________________________________________________ + + +function ToggleMenu(id) + { + if (!window.document.getElementById) + { return; }; + + var display = window.document.getElementById(id).style.display; + + if (display == "none") + { display = "block"; } + else + { display = "none"; } + + window.document.getElementById(id).style.display = display; + } + +function HideAllBut(ids, max) + { + if (document.getElementById) + { + ids.sort( function(a,b) { return a - b; } ); + var number = 1; + + while (number < max) + { + if (ids.length > 0 && number == ids[0]) + { ids.shift(); } + else + { + document.getElementById("MGroupContent" + number).style.display = "none"; + }; + + number++; + }; + }; + } + + +// +// Tooltips +// ____________________________________________________________________________ + + +var tooltipTimer = 0; + +function ShowTip(event, tooltipID, linkID) + { + if (tooltipTimer) + { clearTimeout(tooltipTimer); }; + + var docX = event.clientX + window.pageXOffset; + var docY = event.clientY + window.pageYOffset; + + var showCommand = "ReallyShowTip('" + tooltipID + "', '" + linkID + "', " + docX + ", " + docY + ")"; + + tooltipTimer = setTimeout(showCommand, 1000); + } + +function ReallyShowTip(tooltipID, linkID, docX, docY) + { + tooltipTimer = 0; + + var tooltip; + var link; + + if (document.getElementById) + { + tooltip = document.getElementById(tooltipID); + link = document.getElementById(linkID); + } +/* else if (document.all) + { + tooltip = eval("document.all['" + tooltipID + "']"); + link = eval("document.all['" + linkID + "']"); + } +*/ + if (tooltip) + { + var left = GetXPosition(link); + var top = GetYPosition(link); + top += link.offsetHeight; + + + // The fallback method is to use the mouse X and Y relative to the document. We use a separate if and test if its a number + // in case some browser snuck through the above if statement but didn't support everything. + + if (!isFinite(top) || top == 0) + { + left = docX; + top = docY; + } + + // Some spacing to get it out from under the cursor. + + top += 10; + + // Make sure the tooltip doesnt get smushed by being too close to the edge, or in some browsers, go off the edge of the + // page. We do it here because Konqueror does get offsetWidth right even if it doesnt get the positioning right. + + if (tooltip.offsetWidth != null) + { + var width = tooltip.offsetWidth; + var docWidth = document.body.clientWidth; + + if (left + width > docWidth) + { left = docWidth - width - 1; } + + // If there's a horizontal scroll bar we could go past zero because it's using the page width, not the window width. + if (left < 0) + { left = 0; }; + } + + MoveToPosition(tooltip, left, top); + tooltip.style.visibility = "visible"; + } + } + +function HideTip(tooltipID) + { + if (tooltipTimer) + { + clearTimeout(tooltipTimer); + tooltipTimer = 0; + } + + var tooltip; + + if (document.getElementById) + { tooltip = document.getElementById(tooltipID); } + else if (document.all) + { tooltip = eval("document.all['" + tooltipID + "']"); } + + if (tooltip) + { tooltip.style.visibility = "hidden"; } + } + + +// +// Blockquote fix for IE +// ____________________________________________________________________________ + + +function NDOnLoad() + { + if (browserVer == "IE6") + { + var scrollboxes = document.getElementsByTagName('blockquote'); + + if (scrollboxes.item(0)) + { + NDDoResize(); + window.onresize=NDOnResize; + }; + }; + }; + + +var resizeTimer = 0; + +function NDOnResize() + { + if (resizeTimer != 0) + { clearTimeout(resizeTimer); }; + + resizeTimer = setTimeout(NDDoResize, 250); + }; + + +function NDDoResize() + { + var scrollboxes = document.getElementsByTagName('blockquote'); + + var i; + var item; + + i = 0; + while (item = scrollboxes.item(i)) + { + item.style.width = 100; + i++; + }; + + i = 0; + while (item = scrollboxes.item(i)) + { + item.style.width = item.parentNode.offsetWidth; + i++; + }; + + clearTimeout(resizeTimer); + resizeTimer = 0; + } + + + +/* ________________________________________________________________________________________________________ + + Class: SearchPanel + ________________________________________________________________________________________________________ + + A class handling everything associated with the search panel. + + Parameters: + + name - The name of the global variable that will be storing this instance. Is needed to be able to set timeouts. + mode - The mode the search is going to work in. Pass CommandLineOption()>, so the + value will be something like "HTML" or "FramedHTML". + + ________________________________________________________________________________________________________ +*/ + + +function SearchPanel(name, mode, resultsPath) + { + if (!name || !mode || !resultsPath) + { alert("Incorrect parameters to SearchPanel."); }; + + + // Group: Variables + // ________________________________________________________________________ + + /* + var: name + The name of the global variable that will be storing this instance of the class. + */ + this.name = name; + + /* + var: mode + The mode the search is going to work in, such as "HTML" or "FramedHTML". + */ + this.mode = mode; + + /* + var: resultsPath + The relative path from the current HTML page to the results page directory. + */ + this.resultsPath = resultsPath; + + /* + var: keyTimeout + The timeout used between a keystroke and when a search is performed. + */ + this.keyTimeout = 0; + + /* + var: keyTimeoutLength + The length of in thousandths of a second. + */ + this.keyTimeoutLength = 500; + + /* + var: lastSearchValue + The last search string executed, or an empty string if none. + */ + this.lastSearchValue = ""; + + /* + var: lastResultsPage + The last results page. The value is only relevant if is set. + */ + this.lastResultsPage = ""; + + /* + var: deactivateTimeout + + The timeout used between when a control is deactivated and when the entire panel is deactivated. Is necessary + because a control may be deactivated in favor of another control in the same panel, in which case it should stay + active. + */ + this.deactivateTimout = 0; + + /* + var: deactivateTimeoutLength + The length of in thousandths of a second. + */ + this.deactivateTimeoutLength = 200; + + + + + // Group: DOM Elements + // ________________________________________________________________________ + + + // Function: DOMSearchField + this.DOMSearchField = function() + { return document.getElementById("MSearchField"); }; + + // Function: DOMSearchType + this.DOMSearchType = function() + { return document.getElementById("MSearchType"); }; + + // Function: DOMPopupSearchResults + this.DOMPopupSearchResults = function() + { return document.getElementById("MSearchResults"); }; + + // Function: DOMPopupSearchResultsWindow + this.DOMPopupSearchResultsWindow = function() + { return document.getElementById("MSearchResultsWindow"); }; + + // Function: DOMSearchPanel + this.DOMSearchPanel = function() + { return document.getElementById("MSearchPanel"); }; + + + + + // Group: Event Handlers + // ________________________________________________________________________ + + + /* + Function: OnSearchFieldFocus + Called when focus is added or removed from the search field. + */ + this.OnSearchFieldFocus = function(isActive) + { + this.Activate(isActive); + }; + + + /* + Function: OnSearchFieldChange + Called when the content of the search field is changed. + */ + this.OnSearchFieldChange = function() + { + if (this.keyTimeout) + { + clearTimeout(this.keyTimeout); + this.keyTimeout = 0; + }; + + var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); + + if (searchValue != this.lastSearchValue) + { + if (searchValue != "") + { + this.keyTimeout = setTimeout(this.name + ".Search()", this.keyTimeoutLength); + } + else + { + if (this.mode == "HTML") + { this.DOMPopupSearchResultsWindow().style.display = "none"; }; + this.lastSearchValue = ""; + }; + }; + }; + + + /* + Function: OnSearchTypeFocus + Called when focus is added or removed from the search type. + */ + this.OnSearchTypeFocus = function(isActive) + { + this.Activate(isActive); + }; + + + /* + Function: OnSearchTypeChange + Called when the search type is changed. + */ + this.OnSearchTypeChange = function() + { + var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); + + if (searchValue != "") + { + this.Search(); + }; + }; + + + + // Group: Action Functions + // ________________________________________________________________________ + + + /* + Function: CloseResultsWindow + Closes the results window. + */ + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = "none"; + this.Activate(false, true); + }; + + + /* + Function: Search + Performs a search. + */ + this.Search = function() + { + this.keyTimeout = 0; + + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + var searchTopic = this.DOMSearchType().value; + + var pageExtension = searchValue.substr(0,1); + + if (pageExtension.match(/^[a-z]/i)) + { pageExtension = pageExtension.toUpperCase(); } + else if (pageExtension.match(/^[0-9]/)) + { pageExtension = 'Numbers'; } + else + { pageExtension = "Symbols"; }; + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + // indexSectionsWithContent is defined in searchdata.js + if (indexSectionsWithContent[searchTopic][pageExtension] == true) + { + resultsPage = this.resultsPath + '/' + searchTopic + pageExtension + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else + { + resultsPage = this.resultsPath + '/NoResults.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + }; + + var resultsFrame; + if (this.mode == "HTML") + { resultsFrame = window.frames.MSearchResults; } + else if (this.mode == "FramedHTML") + { resultsFrame = window.top.frames['Content']; }; + + + if (resultsPage != this.lastResultsPage || + + // Bug in IE. If everything becomes hidden in a run, none of them will be able to be reshown in the next for some + // reason. It counts the right number of results, and you can even read the display as "block" after setting it, but it + // just doesn't work in IE 6 or IE 7. So if we're on the right page but the previous search had no results, reload the + // page anyway to get around the bug. + (browserType == "IE" && hasResultsPage && + (!resultsFrame.searchResults || resultsFrame.searchResults.lastMatchCount == 0)) ) + + { + resultsFrame.location.href = resultsPageWithSearch; + } + + // So if the results page is right and there's no IE bug, reperform the search on the existing page. We have to check if there + // are results because NoResults.html doesn't have any JavaScript, and it would be useless to do anything on that page even + // if it did. + else if (hasResultsPage) + { + // We need to check if this exists in case the frame is present but didn't finish loading. + if (resultsFrame.searchResults) + { resultsFrame.searchResults.Search(searchValue); } + + // Otherwise just reload instead of waiting. + else + { resultsFrame.location.href = resultsPageWithSearch; }; + }; + + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (this.mode == "HTML" && domPopupSearchResultsWindow.style.display != "block") + { + var domSearchType = this.DOMSearchType(); + + var left = GetXPosition(domSearchType); + var top = GetYPosition(domSearchType) + domSearchType.offsetHeight; + + MoveToPosition(domPopupSearchResultsWindow, left, top); + domPopupSearchResultsWindow.style.display = 'block'; + }; + + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + }; + + + + // Group: Activation Functions + // Functions that handle whether the entire panel is active or not. + // ________________________________________________________________________ + + + /* + Function: Activate + + Activates or deactivates the search panel, resetting things to their default values if necessary. You can call this on every + control's OnBlur() and it will handle not deactivating the entire panel when focus is just switching between them transparently. + + Parameters: + + isActive - Whether you're activating or deactivating the panel. + ignoreDeactivateDelay - Set if you're positive the action will deactivate the panel and thus want to skip the delay. + */ + this.Activate = function(isActive, ignoreDeactivateDelay) + { + // We want to ignore isActive being false while the results window is open. + if (isActive || (this.mode == "HTML" && this.DOMPopupSearchResultsWindow().style.display == "block")) + { + if (this.inactivateTimeout) + { + clearTimeout(this.inactivateTimeout); + this.inactivateTimeout = 0; + }; + + this.DOMSearchPanel().className = 'MSearchPanelActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == 'Search') + { searchField.value = ""; } + } + else if (!ignoreDeactivateDelay) + { + this.inactivateTimeout = setTimeout(this.name + ".InactivateAfterTimeout()", this.inactivateTimeoutLength); + } + else + { + this.InactivateAfterTimeout(); + }; + }; + + + /* + Function: InactivateAfterTimeout + + Called by , which is set by . Inactivation occurs on a timeout because a control may + receive OnBlur() when focus is really transferring to another control in the search panel. In this case we don't want to + actually deactivate the panel because not only would that cause a visible flicker but it could also reset the search value. + So by doing it on a timeout instead, there's a short period where the second control's OnFocus() can cancel the deactivation. + */ + this.InactivateAfterTimeout = function() + { + this.inactivateTimeout = 0; + + this.DOMSearchPanel().className = 'MSearchPanelInactive'; + this.DOMSearchField().value = "Search"; + + this.lastSearchValue = ""; + this.lastResultsPage = ""; + }; + }; + + + + +/* ________________________________________________________________________________________________________ + + Class: SearchResults + _________________________________________________________________________________________________________ + + The class that handles everything on the search results page. + _________________________________________________________________________________________________________ +*/ + + +function SearchResults(name, mode) + { + /* + var: mode + The mode the search is going to work in, such as "HTML" or "FramedHTML". + */ + this.mode = mode; + + /* + var: lastMatchCount + The number of matches from the last run of . + */ + this.lastMatchCount = 0; + + + /* + Function: Toggle + Toggles the visibility of the passed element ID. + */ + this.Toggle = function(id) + { + if (this.mode == "FramedHTML") + { return; }; + + var parentElement = document.getElementById(id); + + var element = parentElement.firstChild; + + while (element && element != parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'ISubIndex') + { + if (element.style.display == 'block') + { element.style.display = "none"; } + else + { element.style.display = 'block'; } + }; + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { element = element.firstChild; } + else if (element.nextSibling) + { element = element.nextSibling; } + else + { + do + { + element = element.parentNode; + } + while (element && element != parentElement && !element.nextSibling); + + if (element && element != parentElement) + { element = element.nextSibling; }; + }; + }; + }; + + + /* + Function: Search + + Searches for the passed string. If there is no parameter, it takes it from the URL query. + + Always returns true, since other documents may try to call it and that may or may not be possible. + */ + this.Search = function(search) + { + if (!search) + { + search = window.location.search; + search = search.substring(1); // Remove the leading ? + search = unescape(search); + }; + + search = search.replace(/^ +/, ""); + search = search.replace(/ +$/, ""); + search = search.toLowerCase(); + + if (search.match(/[^a-z0-9]/)) // Just a little speedup so it doesn't have to go through the below unnecessarily. + { + search = search.replace(/\_/g, "_und"); + search = search.replace(/\ +/gi, "_spc"); + search = search.replace(/\~/g, "_til"); + search = search.replace(/\!/g, "_exc"); + search = search.replace(/\@/g, "_att"); + search = search.replace(/\#/g, "_num"); + search = search.replace(/\$/g, "_dol"); + search = search.replace(/\%/g, "_pct"); + search = search.replace(/\^/g, "_car"); + search = search.replace(/\&/g, "_amp"); + search = search.replace(/\*/g, "_ast"); + search = search.replace(/\(/g, "_lpa"); + search = search.replace(/\)/g, "_rpa"); + search = search.replace(/\-/g, "_min"); + search = search.replace(/\+/g, "_plu"); + search = search.replace(/\=/g, "_equ"); + search = search.replace(/\{/g, "_lbc"); + search = search.replace(/\}/g, "_rbc"); + search = search.replace(/\[/g, "_lbk"); + search = search.replace(/\]/g, "_rbk"); + search = search.replace(/\:/g, "_col"); + search = search.replace(/\;/g, "_sco"); + search = search.replace(/\"/g, "_quo"); + search = search.replace(/\'/g, "_apo"); + search = search.replace(/\/g, "_ran"); + search = search.replace(/\,/g, "_com"); + search = search.replace(/\./g, "_per"); + search = search.replace(/\?/g, "_que"); + search = search.replace(/\//g, "_sla"); + search = search.replace(/[^a-z0-9\_]i/gi, "_zzz"); + }; + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); + + if (search.length <= rowMatchName.length && rowMatchName.substr(0, search.length) == search) + { + row.style.display = "block"; + matches++; + } + else + { row.style.display = "none"; }; + }; + + i++; + }; + + document.getElementById("Searching").style.display="none"; + + if (matches == 0) + { document.getElementById("NoMatches").style.display="block"; } + else + { document.getElementById("NoMatches").style.display="none"; } + + this.lastMatchCount = matches; + + return true; + }; + }; + diff --git a/src/drivers/dave2d/docs/javascript/prettify.js b/src/drivers/dave2d/docs/javascript/prettify.js new file mode 100644 index 000000000..fda4bf1ed --- /dev/null +++ b/src/drivers/dave2d/docs/javascript/prettify.js @@ -0,0 +1,1526 @@ + +// This code comes from the December 2009 release of Google Prettify, which is Copyright © 2006 Google Inc. +// Minor modifications are marked with "ND Change" comments. +// As part of Natural Docs, this code is licensed under version 3 of the GNU Affero General Public License (AGPL.) +// However, it may also be obtained separately under version 2.0 of the Apache License. +// Refer to License.txt for the complete details + + +// Main code +// ____________________________________________________________________________ + +// Copyright (C) 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * @fileoverview + * some functions for browser-side pretty printing of code contained in html. + *

+ * + * For a fairly comprehensive set of languages see the + * README + * file that came with this source. At a minimum, the lexer should work on a + * number of languages including C and friends, Java, Python, Bash, SQL, HTML, + * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk + * and a subset of Perl, but, because of commenting conventions, doesn't work on + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. + *

+ * Usage:

    + *
  1. include this source file in an html page via + * {@code } + *
  2. define style rules. See the example page for examples. + *
  3. mark the {@code
    } and {@code } tags in your source with
    + *    {@code class=prettyprint.}
    + *    You can also use the (html deprecated) {@code } tag, but the pretty
    + *    printer needs to do more substantial DOM manipulations to support that, so
    + *    some css styles may not be preserved.
    + * </ol>
    + * That's it.  I wanted to keep the API as simple as possible, so there's no
    + * need to specify which language the code is in, but if you wish, you can add
    + * another class to the {@code <pre>} or {@code <code>} element to specify the
    + * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    + * starts with "lang-" followed by a file extension, specifies the file type.
    + * See the "lang-*.js" files in this directory for code that implements
    + * per-language file handlers.
    + * <p>
    + * Change log:<br>
    + * cbeust, 2006/08/22
    + * <blockquote>
    + *   Java annotations (start with "@") are now captured as literals ("lit")
    + * </blockquote>
    + * @requires console
    + * @overrides window
    + */
    +
    +// JSLint declarations
    +/*global console, document, navigator, setTimeout, window */
    +
    +/**
    + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    + * UI events.
    + * If set to {@code false}, {@code prettyPrint()} is synchronous.
    + */
    +window['PR_SHOULD_USE_CONTINUATION'] = true;
    +
    +/** the number of characters between tab columns */
    +window['PR_TAB_WIDTH'] = 8;
    +
    +/** Walks the DOM returning a properly escaped version of innerHTML.
    +  * @param {Node} node
    +  * @param {Array.<string>} out output buffer that receives chunks of HTML.
    +  */
    +window['PR_normalizedHtml']
    +
    +/** Contains functions for creating and registering new language handlers.
    +  * @type {Object}
    +  */
    +  = window['PR']
    +
    +/** Pretty print a chunk of code.
    +  *
    +  * @param {string} sourceCodeHtml code as html
    +  * @return {string} code as html, but prettier
    +  */
    +  = window['prettyPrintOne']
    +/** Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    +  * {@code class=prettyprint} and prettify them.
    +  * @param {Function?} opt_whenDone if specified, called when the last entry
    +  *     has been finished.
    +  */
    +  = window['prettyPrint'] = void 0;
    +
    +/** browser detection. @extern @returns false if not IE, otherwise the major version. */
    +window['_pr_isIE6'] = function () {
    +  var ieVersion = navigator && navigator.userAgent &&
    +      navigator.userAgent.match(/\bMSIE ([678])\./);
    +  ieVersion = ieVersion ? +ieVersion[1] : false;
    +  window['_pr_isIE6'] = function () { return ieVersion; };
    +  return ieVersion;
    +};
    +
    +
    +(function () {
    +  // Keyword lists for various languages.
    +  var FLOW_CONTROL_KEYWORDS =
    +      "break continue do else for if return while ";
    +  var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
    +      "double enum extern float goto int long register short signed sizeof " +
    +      "static struct switch typedef union unsigned void volatile ";
    +  var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
    +      "new operator private protected public this throw true try typeof ";
    +  var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
    +      "concept concept_map const_cast constexpr decltype " +
    +      "dynamic_cast explicit export friend inline late_check " +
    +      "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
    +      "template typeid typename using virtual wchar_t where ";
    +  var JAVA_KEYWORDS = COMMON_KEYWORDS +
    +      "abstract boolean byte extends final finally implements import " +
    +      "instanceof null native package strictfp super synchronized throws " +
    +      "transient ";
    +  var CSHARP_KEYWORDS = JAVA_KEYWORDS +
    +      "as base by checked decimal delegate descending event " +
    +      "fixed foreach from group implicit in interface internal into is lock " +
    +      "object out override orderby params partial readonly ref sbyte sealed " +
    +      "stackalloc string select uint ulong unchecked unsafe ushort var ";
    +  var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
    +      "debugger eval export function get null set undefined var with " +
    +      "Infinity NaN ";
    +  var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
    +      "goto if import last local my next no our print package redo require " +
    +      "sub undef unless until use wantarray while BEGIN END ";
    +  var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
    +      "elif except exec finally from global import in is lambda " +
    +      "nonlocal not or pass print raise try with yield " +
    +      "False True None ";
    +  var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
    +      " defined elsif end ensure false in module next nil not or redo rescue " +
    +      "retry self super then true undef unless until when yield BEGIN END ";
    +  var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
    +      "function in local set then until ";
    +  var ALL_KEYWORDS = (
    +      CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
    +      PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
    +
    +  // token style names.  correspond to css classes
    +  /** token style for a string literal */
    +  var PR_STRING = 'str';
    +  /** token style for a keyword */
    +  var PR_KEYWORD = 'kwd';
    +  /** token style for a comment */
    +  var PR_COMMENT = 'com';
    +  /** token style for a type */
    +  var PR_TYPE = 'typ';
    +  /** token style for a literal value.  e.g. 1, null, true. */
    +  var PR_LITERAL = 'lit';
    +  /** token style for a punctuation string. */
    +  var PR_PUNCTUATION = 'pun';
    +  /** token style for a punctuation string. */
    +  var PR_PLAIN = 'pln';
    +
    +  /** token style for an sgml tag. */
    +  var PR_TAG = 'tag';
    +  /** token style for a markup declaration such as a DOCTYPE. */
    +  var PR_DECLARATION = 'dec';
    +  /** token style for embedded source. */
    +  var PR_SOURCE = 'src';
    +  /** token style for an sgml attribute name. */
    +  var PR_ATTRIB_NAME = 'atn';
    +  /** token style for an sgml attribute value. */
    +  var PR_ATTRIB_VALUE = 'atv';
    +
    +  /**
    +   * A class that indicates a section of markup that is not code, e.g. to allow
    +   * embedding of line numbers within code listings.
    +   */
    +  var PR_NOCODE = 'nocode';
    +
    +  /** A set of tokens that can precede a regular expression literal in
    +    * javascript.
    +    * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
    +    * list, but I've removed ones that might be problematic when seen in
    +    * languages that don't support regular expression literals.
    +    *
    +    * <p>Specifically, I've removed any keywords that can't precede a regexp
    +    * literal in a syntactically legal javascript program, and I've removed the
    +    * "in" keyword since it's not a keyword in many languages, and might be used
    +    * as a count of inches.
    +    *
    +    * <p>The link a above does not accurately describe EcmaScript rules since
    +    * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    +    * very well in practice.
    +    *
    +    * @private
    +    */
    +  var REGEXP_PRECEDER_PATTERN = function () {
    +      var preceders = [
    +          "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
    +          "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
    +          "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
    +          "<", "<<", "<<=", "<=", "=", "==", "===", ">",
    +          ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
    +          "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
    +          "||=", "~" /* handles =~ and !~ */,
    +          "break", "case", "continue", "delete",
    +          "do", "else", "finally", "instanceof",
    +          "return", "throw", "try", "typeof"
    +          ];
    +      var pattern = '(?:^^|[+-]';
    +      for (var i = 0; i < preceders.length; ++i) {
    +        pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
    +      }
    +      pattern += ')\\s*';  // matches at end, and matches empty string
    +      return pattern;
    +      // CAVEAT: this does not properly handle the case where a regular
    +      // expression immediately follows another since a regular expression may
    +      // have flags for case-sensitivity and the like.  Having regexp tokens
    +      // adjacent is not valid in any language I'm aware of, so I'm punting.
    +      // TODO: maybe style special characters inside a regexp as punctuation.
    +    }();
    +
    +  // Define regexps here so that the interpreter doesn't have to create an
    +  // object each time the function containing them is called.
    +  // The language spec requires a new object created even if you don't access
    +  // the $1 members.
    +  var pr_amp = /&/g;
    +  var pr_lt = /</g;
    +  var pr_gt = />/g;
    +  var pr_quot = /\"/g;
    +  /** like textToHtml but escapes double quotes to be attribute safe. */
    +  function attribToHtml(str) {
    +    return str.replace(pr_amp, '&amp;')
    +        .replace(pr_lt, '&lt;')
    +        .replace(pr_gt, '&gt;')
    +        .replace(pr_quot, '&quot;');
    +  }
    +
    +  /** escapest html special characters to html. */
    +  function textToHtml(str) {
    +    return str.replace(pr_amp, '&amp;')
    +        .replace(pr_lt, '&lt;')
    +        .replace(pr_gt, '&gt;');
    +  }
    +
    +
    +  var pr_ltEnt = /&lt;/g;
    +  var pr_gtEnt = /&gt;/g;
    +  var pr_aposEnt = /&apos;/g;
    +  var pr_quotEnt = /&quot;/g;
    +  var pr_ampEnt = /&amp;/g;
    +  var pr_nbspEnt = /&nbsp;/g;
    +  /** unescapes html to plain text. */
    +  function htmlToText(html) {
    +    var pos = html.indexOf('&');
    +    if (pos < 0) { return html; }
    +    // Handle numeric entities specially.  We can't use functional substitution
    +    // since that doesn't work in older versions of Safari.
    +    // These should be rare since most browsers convert them to normal chars.
    +    for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) {
    +      var end = html.indexOf(';', pos);
    +      if (end >= 0) {
    +        var num = html.substring(pos + 3, end);
    +        var radix = 10;
    +        if (num && num.charAt(0) === 'x') {
    +          num = num.substring(1);
    +          radix = 16;
    +        }
    +        var codePoint = parseInt(num, radix);
    +        if (!isNaN(codePoint)) {
    +          html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
    +                  html.substring(end + 1));
    +        }
    +      }
    +    }
    +
    +    return html.replace(pr_ltEnt, '<')
    +        .replace(pr_gtEnt, '>')
    +        .replace(pr_aposEnt, "'")
    +        .replace(pr_quotEnt, '"')
    +        .replace(pr_nbspEnt, ' ')
    +        .replace(pr_ampEnt, '&');
    +  }
    +
    +  /** is the given node's innerHTML normally unescaped? */
    +  function isRawContent(node) {
    +    return 'XMP' === node.tagName;
    +  }
    +
    +  var newlineRe = /[\r\n]/g;
    +  /**
    +   * Are newlines and adjacent spaces significant in the given node's innerHTML?
    +   */
    +  function isPreformatted(node, content) {
    +    // PRE means preformatted, and is a very common case, so don't create
    +    // unnecessary computed style objects.
    +    if ('PRE' === node.tagName) { return true; }
    +    if (!newlineRe.test(content)) { return true; }  // Don't care
    +    var whitespace = '';
    +    // For disconnected nodes, IE has no currentStyle.
    +    if (node.currentStyle) {
    +      whitespace = node.currentStyle.whiteSpace;
    +    } else if (window.getComputedStyle) {
    +      // Firefox makes a best guess if node is disconnected whereas Safari
    +      // returns the empty string.
    +      whitespace = window.getComputedStyle(node, null).whiteSpace;
    +    }
    +    return !whitespace || whitespace === 'pre';
    +  }
    +
    +  function normalizedHtml(node, out) {
    +    switch (node.nodeType) {
    +      case 1:  // an element
    +        var name = node.tagName.toLowerCase();
    +        out.push('<', name);
    +        for (var i = 0; i < node.attributes.length; ++i) {
    +          var attr = node.attributes[i];
    +          if (!attr.specified) { continue; }
    +          out.push(' ');
    +          normalizedHtml(attr, out);
    +        }
    +        out.push('>');
    +        for (var child = node.firstChild; child; child = child.nextSibling) {
    +          normalizedHtml(child, out);
    +        }
    +        if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
    +          out.push('<\/', name, '>');
    +        }
    +        break;
    +      case 2: // an attribute
    +        out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"');
    +        break;
    +      case 3: case 4: // text
    +        out.push(textToHtml(node.nodeValue));
    +        break;
    +    }
    +  }
    +
    +  /**
    +   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    +   * matches the union o the sets o strings matched d by the input RegExp.
    +   * Since it matches globally, if the input strings have a start-of-input
    +   * anchor (/^.../), it is ignored for the purposes of unioning.
    +   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    +   * @return {RegExp} a global regex.
    +   */
    +  function combinePrefixPatterns(regexs) {
    +    var capturedGroupIndex = 0;
    +
    +    var needToFoldCase = false;
    +    var ignoreCase = false;
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.ignoreCase) {
    +        ignoreCase = true;
    +      } else if (/[a-z]/i.test(regex.source.replace(
    +                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    +        needToFoldCase = true;
    +        ignoreCase = false;
    +        break;
    +      }
    +    }
    +
    +    function decodeEscape(charsetPart) {
    +      if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
    +      switch (charsetPart.charAt(1)) {
    +        case 'b': return 8;
    +        case 't': return 9;
    +        case 'n': return 0xa;
    +        case 'v': return 0xb;
    +        case 'f': return 0xc;
    +        case 'r': return 0xd;
    +        case 'u': case 'x':
    +          return parseInt(charsetPart.substring(2), 16)
    +              || charsetPart.charCodeAt(1);
    +        case '0': case '1': case '2': case '3': case '4':
    +        case '5': case '6': case '7':
    +          return parseInt(charsetPart.substring(1), 8);
    +        default: return charsetPart.charCodeAt(1);
    +      }
    +    }
    +
    +    function encodeEscape(charCode) {
    +      if (charCode < 0x20) {
    +        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    +      }
    +      var ch = String.fromCharCode(charCode);
    +      if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
    +        ch = '\\' + ch;
    +      }
    +      return ch;
    +    }
    +
    +    function caseFoldCharset(charSet) {
    +      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    +          new RegExp(
    +              '\\\\u[0-9A-Fa-f]{4}'
    +              + '|\\\\x[0-9A-Fa-f]{2}'
    +              + '|\\\\[0-3][0-7]{0,2}'
    +              + '|\\\\[0-7]{1,2}'
    +              + '|\\\\[\\s\\S]'
    +              + '|-'
    +              + '|[^-\\\\]',
    +              'g'));
    +      var groups = [];
    +      var ranges = [];
    +      var inverse = charsetParts[0] === '^';
    +      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    +        var p = charsetParts[i];
    +        switch (p) {
    +          case '\\B': case '\\b':
    +          case '\\D': case '\\d':
    +          case '\\S': case '\\s':
    +          case '\\W': case '\\w':
    +            groups.push(p);
    +            continue;
    +        }
    +        var start = decodeEscape(p);
    +        var end;
    +        if (i + 2 < n && '-' === charsetParts[i + 1]) {
    +          end = decodeEscape(charsetParts[i + 2]);
    +          i += 2;
    +        } else {
    +          end = start;
    +        }
    +        ranges.push([start, end]);
    +        // If the range might intersect letters, then expand it.
    +        if (!(end < 65 || start > 122)) {
    +          if (!(end < 65 || start > 90)) {
    +            ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    +          }
    +          if (!(end < 97 || start > 122)) {
    +            ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    +          }
    +        }
    +      }
    +
    +      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    +      // -> [[1, 12], [14, 14], [16, 17]]
    +      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    +      var consolidatedRanges = [];
    +      var lastRange = [NaN, NaN];
    +      for (var i = 0; i < ranges.length; ++i) {
    +        var range = ranges[i];
    +        if (range[0] <= lastRange[1] + 1) {
    +          lastRange[1] = Math.max(lastRange[1], range[1]);
    +        } else {
    +          consolidatedRanges.push(lastRange = range);
    +        }
    +      }
    +
    +      var out = ['['];
    +      if (inverse) { out.push('^'); }
    +      out.push.apply(out, groups);
    +      for (var i = 0; i < consolidatedRanges.length; ++i) {
    +        var range = consolidatedRanges[i];
    +        out.push(encodeEscape(range[0]));
    +        if (range[1] > range[0]) {
    +          if (range[1] + 1 > range[0]) { out.push('-'); }
    +          out.push(encodeEscape(range[1]));
    +        }
    +      }
    +      out.push(']');
    +      return out.join('');
    +    }
    +
    +    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    +      // Split into character sets, escape sequences, punctuation strings
    +      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    +      // include any of the above.
    +      var parts = regex.source.match(
    +          new RegExp(
    +              '(?:'
    +              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    +              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    +              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    +              + '|\\\\[0-9]+'  // a back-reference or octal escape
    +              + '|\\\\[^ux0-9]'  // other escape sequence
    +              + '|\\(\\?[:!=]'  // start of a non-capturing group
    +              + '|[\\(\\)\\^]'  // start/emd of a group, or line start
    +              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    +              + ')',
    +              'g'));
    +      var n = parts.length;
    +
    +      // Maps captured group numbers to the number they will occupy in
    +      // the output or to -1 if that has not been determined, or to
    +      // undefined if they need not be capturing in the output.
    +      var capturedGroups = [];
    +
    +      // Walk over and identify back references to build the capturedGroups
    +      // mapping.
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          // groups are 1-indexed, so max group index is count of '('
    +          ++groupIndex;
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue && decimalValue <= groupIndex) {
    +            capturedGroups[decimalValue] = -1;
    +          }
    +        }
    +      }
    +
    +      // Renumber groups and reduce capturing groups to non-capturing groups
    +      // where possible.
    +      for (var i = 1; i < capturedGroups.length; ++i) {
    +        if (-1 === capturedGroups[i]) {
    +          capturedGroups[i] = ++capturedGroupIndex;
    +        }
    +      }
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          ++groupIndex;
    +          if (capturedGroups[groupIndex] === undefined) {
    +            parts[i] = '(?:';
    +          }
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue && decimalValue <= groupIndex) {
    +            parts[i] = '\\' + capturedGroups[groupIndex];
    +          }
    +        }
    +      }
    +
    +      // Remove any prefix anchors so that the output will match anywhere.
    +      // ^^ really does mean an anchored match though.
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    +      }
    +
    +      // Expand letters to groupts to handle mixing of case-sensitive and
    +      // case-insensitive patterns if necessary.
    +      if (regex.ignoreCase && needToFoldCase) {
    +        for (var i = 0; i < n; ++i) {
    +          var p = parts[i];
    +          var ch0 = p.charAt(0);
    +          if (p.length >= 2 && ch0 === '[') {
    +            parts[i] = caseFoldCharset(p);
    +          } else if (ch0 !== '\\') {
    +            // TODO: handle letters in numeric escapes.
    +            parts[i] = p.replace(
    +                /[a-zA-Z]/g,
    +                function (ch) {
    +                  var cc = ch.charCodeAt(0);
    +                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    +                });
    +          }
    +        }
    +      }
    +
    +      return parts.join('');
    +    }
    +
    +    var rewritten = [];
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    +      rewritten.push(
    +          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    +    }
    +
    +    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    +  }
    +
    +  var PR_innerHtmlWorks = null;
    +  function getInnerHtml(node) {
    +    // inner html is hopelessly broken in Safari 2.0.4 when the content is
    +    // an html description of well formed XML and the containing tag is a PRE
    +    // tag, so we detect that case and emulate innerHTML.
    +    if (null === PR_innerHtmlWorks) {
    +      var testNode = document.createElement('PRE');
    +      testNode.appendChild(
    +          document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));
    +      PR_innerHtmlWorks = !/</.test(testNode.innerHTML);
    +    }
    +
    +    if (PR_innerHtmlWorks) {
    +      var content = node.innerHTML;
    +      // XMP tags contain unescaped entities so require special handling.
    +      if (isRawContent(node)) {
    +        content = textToHtml(content);
    +      } else if (!isPreformatted(node, content)) {
    +        content = content.replace(/(<br\s*\/?>)[\r\n]+/g, '$1')
    +            .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
    +      }
    +      return content;
    +    }
    +
    +    var out = [];
    +    for (var child = node.firstChild; child; child = child.nextSibling) {
    +      normalizedHtml(child, out);
    +    }
    +    return out.join('');
    +  }
    +
    +  /** returns a function that expand tabs to spaces.  This function can be fed
    +    * successive chunks of text, and will maintain its own internal state to
    +    * keep track of how tabs are expanded.
    +    * @return {function (string) : string} a function that takes
    +    *   plain text and return the text with tabs expanded.
    +    * @private
    +    */
    +  function makeTabExpander(tabWidth) {
    +    var SPACES = '                ';
    +    var charInLine = 0;
    +
    +    return function (plainText) {
    +      // walk over each character looking for tabs and newlines.
    +      // On tabs, expand them.  On newlines, reset charInLine.
    +      // Otherwise increment charInLine
    +      var out = null;
    +      var pos = 0;
    +      for (var i = 0, n = plainText.length; i < n; ++i) {
    +        var ch = plainText.charAt(i);
    +
    +        switch (ch) {
    +          case '\t':
    +            if (!out) { out = []; }
    +            out.push(plainText.substring(pos, i));
    +            // calculate how much space we need in front of this part
    +            // nSpaces is the amount of padding -- the number of spaces needed
    +            // to move us to the next column, where columns occur at factors of
    +            // tabWidth.
    +            var nSpaces = tabWidth - (charInLine % tabWidth);
    +            charInLine += nSpaces;
    +            for (; nSpaces >= 0; nSpaces -= SPACES.length) {
    +              out.push(SPACES.substring(0, nSpaces));
    +            }
    +            pos = i + 1;
    +            break;
    +          case '\n':
    +            charInLine = 0;
    +            break;
    +          default:
    +            ++charInLine;
    +        }
    +      }
    +      if (!out) { return plainText; }
    +      out.push(plainText.substring(pos));
    +      return out.join('');
    +    };
    +  }
    +
    +  var pr_chunkPattern = new RegExp(
    +      '[^<]+'  // A run of characters other than '<'
    +      + '|<\!--[\\s\\S]*?--\>'  // an HTML comment
    +      + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>'  // a CDATA section
    +      // a probable tag that should not be highlighted
    +      + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
    +      + '|<',  // A '<' that does not begin a larger chunk
    +      'g');
    +  var pr_commentPrefix = /^<\!--/;
    +  var pr_cdataPrefix = /^<!\[CDATA\[/;
    +  var pr_brPrefix = /^<br\b/i;
    +  var pr_tagNameRe = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/;
    +
    +  /** split markup into chunks of html tags (style null) and
    +    * plain text (style {@link #PR_PLAIN}), converting tags which are
    +    * significant for tokenization (<br>) into their textual equivalent.
    +    *
    +    * @param {string} s html where whitespace is considered significant.
    +    * @return {Object} source code and extracted tags.
    +    * @private
    +    */
    +  function extractTags(s) {
    +    // since the pattern has the 'g' modifier and defines no capturing groups,
    +    // this will return a list of all chunks which we then classify and wrap as
    +    // PR_Tokens
    +    var matches = s.match(pr_chunkPattern);
    +    var sourceBuf = [];
    +    var sourceBufLen = 0;
    +    var extractedTags = [];
    +    if (matches) {
    +      for (var i = 0, n = matches.length; i < n; ++i) {
    +        var match = matches[i];
    +        if (match.length > 1 && match.charAt(0) === '<') {
    +          if (pr_commentPrefix.test(match)) { continue; }
    +          if (pr_cdataPrefix.test(match)) {
    +            // strip CDATA prefix and suffix.  Don't unescape since it's CDATA
    +            sourceBuf.push(match.substring(9, match.length - 3));
    +            sourceBufLen += match.length - 12;
    +          } else if (pr_brPrefix.test(match)) {
    +            // <br> tags are lexically significant so convert them to text.
    +            // This is undone later.
    +            sourceBuf.push('\n');
    +            ++sourceBufLen;
    +          } else {
    +            if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
    +              // A <span class="nocode"> will start a section that should be
    +              // ignored.  Continue walking the list until we see a matching end
    +              // tag.
    +              var name = match.match(pr_tagNameRe)[2];
    +              var depth = 1;
    +              var j;
    +              end_tag_loop:
    +              for (j = i + 1; j < n; ++j) {
    +                var name2 = matches[j].match(pr_tagNameRe);
    +                if (name2 && name2[2] === name) {
    +                  if (name2[1] === '/') {
    +                    if (--depth === 0) { break end_tag_loop; }
    +                  } else {
    +                    ++depth;
    +                  }
    +                }
    +              }
    +              if (j < n) {
    +                extractedTags.push(
    +                    sourceBufLen, matches.slice(i, j + 1).join(''));
    +                i = j;
    +              } else {  // Ignore unclosed sections.
    +                extractedTags.push(sourceBufLen, match);
    +              }
    +            } else {
    +              extractedTags.push(sourceBufLen, match);
    +            }
    +          }
    +        } else {
    +          var literalText = htmlToText(match);
    +          sourceBuf.push(literalText);
    +          sourceBufLen += literalText.length;
    +        }
    +      }
    +    }
    +    return { source: sourceBuf.join(''), tags: extractedTags };
    +  }
    +
    +  /** True if the given tag contains a class attribute with the nocode class. */
    +  function isNoCodeTag(tag) {
    +    return !!tag
    +        // First canonicalize the representation of attributes
    +        .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
    +                 ' $1="$2$3$4"')
    +        // Then look for the attribute we want.
    +        .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
    +  }
    +
    +  /**
    +   * Apply the given language handler to sourceCode and add the resulting
    +   * decorations to out.
    +   * @param {number} basePos the index of sourceCode within the chunk of source
    +   *    whose decorations are already present on out.
    +   */
    +  function appendDecorations(basePos, sourceCode, langHandler, out) {
    +    if (!sourceCode) { return; }
    +    var job = {
    +      source: sourceCode,
    +      basePos: basePos
    +    };
    +    langHandler(job);
    +    out.push.apply(out, job.decorations);
    +  }
    +
    +  /** Given triples of [style, pattern, context] returns a lexing function,
    +    * The lexing function interprets the patterns to find token boundaries and
    +    * returns a decoration list of the form
    +    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    +    * where index_n is an index into the sourceCode, and style_n is a style
    +    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    +    * all characters in sourceCode[index_n-1:index_n].
    +    *
    +    * The stylePatterns is a list whose elements have the form
    +    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    +    *
    +    * Style is a style constant like PR_PLAIN, or can be a string of the
    +    * form 'lang-FOO', where FOO is a language extension describing the
    +    * language of the portion of the token in $1 after pattern executes.
    +    * E.g., if style is 'lang-lisp', and group 1 contains the text
    +    * '(hello (world))', then that portion of the token will be passed to the
    +    * registered lisp handler for formatting.
    +    * The text before and after group 1 will be restyled using this decorator
    +    * so decorators should take care that this doesn't result in infinite
    +    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    +    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    +    * '<script>foo()<\/script>', which would cause the current decorator to
    +    * be called with '<script>' which would not match the same rule since
    +    * group 1 must not be empty, so it would be instead styled as PR_TAG by
    +    * the generic tag rule.  The handler registered for the 'js' extension would
    +    * then be called with 'foo()', and finally, the current decorator would
    +    * be called with '<\/script>' which would not match the original rule and
    +    * so the generic tag rule would identify it as a tag.
    +    *
    +    * Pattern must only match prefixes, and if it matches a prefix, then that
    +    * match is considered a token with the same style.
    +    *
    +    * Context is applied to the last non-whitespace, non-comment token
    +    * recognized.
    +    *
    +    * Shortcut is an optional string of characters, any of which, if the first
    +    * character, gurantee that this pattern and only this pattern matches.
    +    *
    +    * @param {Array} shortcutStylePatterns patterns that always start with
    +    *   a known character.  Must have a shortcut string.
    +    * @param {Array} fallthroughStylePatterns patterns that will be tried in
    +    *   order if the shortcut ones fail.  May have shortcuts.
    +    *
    +    * @return {function (Object)} a
    +    *   function that takes source code and returns a list of decorations.
    +    */
    +  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    +    var shortcuts = {};
    +    var tokenizer;
    +    (function () {
    +      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    +      var allRegexs = [];
    +      var regexKeys = {};
    +      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    +        var patternParts = allPatterns[i];
    +        var shortcutChars = patternParts[3];
    +        if (shortcutChars) {
    +          for (var c = shortcutChars.length; --c >= 0;) {
    +            shortcuts[shortcutChars.charAt(c)] = patternParts;
    +          }
    +        }
    +        var regex = patternParts[1];
    +        var k = '' + regex;
    +        if (!regexKeys.hasOwnProperty(k)) {
    +          allRegexs.push(regex);
    +          regexKeys[k] = null;
    +        }
    +      }
    +      allRegexs.push(/[\0-\uffff]/);
    +      tokenizer = combinePrefixPatterns(allRegexs);
    +    })();
    +
    +    var nPatterns = fallthroughStylePatterns.length;
    +    var notWs = /\S/;
    +
    +    /**
    +     * Lexes job.source and produces an output array job.decorations of style
    +     * classes preceded by the position at which they start in job.source in
    +     * order.
    +     *
    +     * @param {Object} job an object like {@code
    +     *    source: {string} sourceText plain text,
    +     *    basePos: {int} position of job.source in the larger chunk of
    +     *        sourceCode.
    +     * }
    +     */
    +    var decorate = function (job) {
    +      var sourceCode = job.source, basePos = job.basePos;
    +      /** Even entries are positions in source in ascending order.  Odd enties
    +        * are style markers (e.g., PR_COMMENT) that run from that position until
    +        * the end.
    +        * @type {Array.<number|string>}
    +        */
    +      var decorations = [basePos, PR_PLAIN];
    +      var pos = 0;  // index into sourceCode
    +      var tokens = sourceCode.match(tokenizer) || [];
    +      var styleCache = {};
    +
    +      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    +        var token = tokens[ti];
    +        var style = styleCache[token];
    +        var match = void 0;
    +
    +        var isEmbedded;
    +        if (typeof style === 'string') {
    +          isEmbedded = false;
    +        } else {
    +          var patternParts = shortcuts[token.charAt(0)];
    +          if (patternParts) {
    +            match = token.match(patternParts[1]);
    +            style = patternParts[0];
    +          } else {
    +            for (var i = 0; i < nPatterns; ++i) {
    +              patternParts = fallthroughStylePatterns[i];
    +              match = token.match(patternParts[1]);
    +              if (match) {
    +                style = patternParts[0];
    +                break;
    +              }
    +            }
    +
    +            if (!match) {  // make sure that we make progress
    +              style = PR_PLAIN;
    +            }
    +          }
    +
    +          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    +          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    +            isEmbedded = false;
    +            style = PR_SOURCE;
    +          }
    +
    +          if (!isEmbedded) { styleCache[token] = style; }
    +        }
    +
    +        var tokenStart = pos;
    +        pos += token.length;
    +
    +        if (!isEmbedded) {
    +          decorations.push(basePos + tokenStart, style);
    +        } else {  // Treat group 1 as an embedded block of source code.
    +          var embeddedSource = match[1];
    +          var embeddedSourceStart = token.indexOf(embeddedSource);
    +          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    +          if (match[2]) {
    +            // If embeddedSource can be blank, then it would match at the
    +            // beginning which would cause us to infinitely recurse on the
    +            // entire token, so we catch the right context in match[2].
    +            embeddedSourceEnd = token.length - match[2].length;
    +            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    +          }
    +          var lang = style.substring(5);
    +          // Decorate the left of the embedded source
    +          appendDecorations(
    +              basePos + tokenStart,
    +              token.substring(0, embeddedSourceStart),
    +              decorate, decorations);
    +          // Decorate the embedded source
    +          appendDecorations(
    +              basePos + tokenStart + embeddedSourceStart,
    +              embeddedSource,
    +              langHandlerForExtension(lang, embeddedSource),
    +              decorations);
    +          // Decorate the right of the embedded section
    +          appendDecorations(
    +              basePos + tokenStart + embeddedSourceEnd,
    +              token.substring(embeddedSourceEnd),
    +              decorate, decorations);
    +        }
    +      }
    +      job.decorations = decorations;
    +    };
    +    return decorate;
    +  }
    +
    +  /** returns a function that produces a list of decorations from source text.
    +    *
    +    * This code treats ", ', and ` as string delimiters, and \ as a string
    +    * escape.  It does not recognize perl's qq() style strings.
    +    * It has no special handling for double delimiter escapes as in basic, or
    +    * the tripled delimiters used in python, but should work on those regardless
    +    * although in those cases a single string literal may be broken up into
    +    * multiple adjacent string literals.
    +    *
    +    * It recognizes C, C++, and shell style comments.
    +    *
    +    * @param {Object} options a set of optional parameters.
    +    * @return {function (Object)} a function that examines the source code
    +    *     in the input job and builds the decoration list.
    +    */
    +  function sourceDecorator(options) {
    +    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    +    if (options['tripleQuotedStrings']) {
    +      // '''multi-line-string''', 'single-line-string', and double-quoted
    +      shortcutStylePatterns.push(
    +          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    +           null, '\'"']);
    +    } else if (options['multiLineStrings']) {
    +      // 'multi-line-string', "multi-line-string"
    +      shortcutStylePatterns.push(
    +          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    +           null, '\'"`']);
    +    } else {
    +      // 'single-line-string', "single-line-string"
    +      shortcutStylePatterns.push(
    +          [PR_STRING,
    +           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    +           null, '"\'']);
    +    }
    +    if (options['verbatimStrings']) {
    +      // verbatim-string-literal production from the C# grammar.  See issue 93.
    +      fallthroughStylePatterns.push(
    +          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    +    }
    +    if (options['hashComments']) {
    +      if (options['cStyleComments']) {
    +        // Stop C preprocessor declarations at an unclosed open comment
    +        shortcutStylePatterns.push(
    +            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
    +             null, '#']);
    +        fallthroughStylePatterns.push(
    +            [PR_STRING,
    +             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
    +             null]);
    +      } else {
    +        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    +      }
    +    }
    +    if (options['cStyleComments']) {
    +      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    +      fallthroughStylePatterns.push(
    +          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    +    }
    +    if (options['regexLiterals']) {
    +      var REGEX_LITERAL = (
    +          // A regular expression literal starts with a slash that is
    +          // not followed by * or / so that it is not confused with
    +          // comments.
    +          '/(?=[^/*])'
    +          // and then contains any number of raw characters,
    +          + '(?:[^/\\x5B\\x5C]'
    +          // escape sequences (\x5C),
    +          +    '|\\x5C[\\s\\S]'
    +          // or non-nesting character sets (\x5B\x5D);
    +          +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
    +          // finally closed by a /.
    +          + '/');
    +      fallthroughStylePatterns.push(
    +          ['lang-regex',
    +           new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    +           ]);
    +    }
    +
    +    var keywords = options['keywords'].replace(/^\s+|\s+$/g, '');
    +    if (keywords.length) {
    +      fallthroughStylePatterns.push(
    +          [PR_KEYWORD,
    +           new RegExp('^(?:' + keywords.replace(/\s+/g, '|') + ')\\b'), null]);
    +    }
    +
    +    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    +    fallthroughStylePatterns.push(
    +        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    +        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    +        [PR_TYPE,        /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null],
    +        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    +        [PR_LITERAL,
    +         new RegExp(
    +             '^(?:'
    +             // A hex number
    +             + '0x[a-f0-9]+'
    +             // or an octal or decimal number,
    +             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    +             // possibly in scientific notation
    +             + '(?:e[+\\-]?\\d+)?'
    +             + ')'
    +             // with an optional modifier like UL for unsigned long
    +             + '[a-z]*', 'i'),
    +         null, '0123456789'],
    +        [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null]);
    +
    +    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    +  }
    +
    +  var decorateSource = sourceDecorator({
    +        'keywords': ALL_KEYWORDS,
    +        'hashComments': true,
    +        'cStyleComments': true,
    +        'multiLineStrings': true,
    +        'regexLiterals': true
    +      });
    +
    +  /** Breaks {@code job.source} around style boundaries in
    +    * {@code job.decorations} while re-interleaving {@code job.extractedTags},
    +    * and leaves the result in {@code job.prettyPrintedHtml}.
    +    * @param {Object} job like {
    +    *    source: {string} source as plain text,
    +    *    extractedTags: {Array.<number|string>} extractedTags chunks of raw
    +    *                   html preceded by their position in {@code job.source}
    +    *                   in order
    +    *    decorations: {Array.<number|string} an array of style classes preceded
    +    *                 by the position at which they start in job.source in order
    +    * }
    +    * @private
    +    */
    +  function recombineTagsAndDecorations(job) {
    +    var sourceText = job.source;
    +    var extractedTags = job.extractedTags;
    +    var decorations = job.decorations;
    +
    +    var html = [];
    +    // index past the last char in sourceText written to html
    +    var outputIdx = 0;
    +
    +    var openDecoration = null;
    +    var currentDecoration = null;
    +    var tagPos = 0;  // index into extractedTags
    +    var decPos = 0;  // index into decorations
    +    var tabExpander = makeTabExpander(window['PR_TAB_WIDTH']);
    +
    +    var adjacentSpaceRe = /([\r\n ]) /g;
    +    var startOrSpaceRe = /(^| ) /gm;
    +    var newlineRe = /\r\n?|\n/g;
    +    var trailingSpaceRe = /[ \r\n]$/;
    +    var lastWasSpace = true;  // the last text chunk emitted ended with a space.
    +
    +    // A helper function that is responsible for opening sections of decoration
    +    // and outputing properly escaped chunks of source
    +    function emitTextUpTo(sourceIdx) {
    +      if (sourceIdx > outputIdx) {
    +        if (openDecoration && openDecoration !== currentDecoration) {
    +          // Close the current decoration
    +          html.push('</span>');
    +          openDecoration = null;
    +        }
    +        if (!openDecoration && currentDecoration) {
    +          openDecoration = currentDecoration;
    +          html.push('<span class="', openDecoration, '">');
    +        }
    +        // This interacts badly with some wikis which introduces paragraph tags
    +        // into pre blocks for some strange reason.
    +        // It's necessary for IE though which seems to lose the preformattedness
    +        // of <pre> tags when their innerHTML is assigned.
    +        // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
    +        // and it serves to undo the conversion of <br>s to newlines done in
    +        // chunkify.
    +        var htmlChunk = textToHtml(
    +            tabExpander(sourceText.substring(outputIdx, sourceIdx)))
    +            .replace(lastWasSpace
    +                     ? startOrSpaceRe
    +                     : adjacentSpaceRe, '$1&nbsp;');
    +        // Keep track of whether we need to escape space at the beginning of the
    +        // next chunk.
    +        lastWasSpace = trailingSpaceRe.test(htmlChunk);
    +        // IE collapses multiple adjacient <br>s into 1 line break.
    +        // Prefix every <br> with '&nbsp;' can prevent such IE's behavior.
    +        var lineBreakHtml = window['_pr_isIE6']() ? '&nbsp;<br />' : '<br />';
    +        html.push(htmlChunk.replace(newlineRe, lineBreakHtml));
    +        outputIdx = sourceIdx;
    +      }
    +    }
    +
    +    while (true) {
    +      // Determine if we're going to consume a tag this time around.  Otherwise
    +      // we consume a decoration or exit.
    +      var outputTag;
    +      if (tagPos < extractedTags.length) {
    +        if (decPos < decorations.length) {
    +          // Pick one giving preference to extractedTags since we shouldn't open
    +          // a new style that we're going to have to immediately close in order
    +          // to output a tag.
    +          outputTag = extractedTags[tagPos] <= decorations[decPos];
    +        } else {
    +          outputTag = true;
    +        }
    +      } else {
    +        outputTag = false;
    +      }
    +      // Consume either a decoration or a tag or exit.
    +      if (outputTag) {
    +        emitTextUpTo(extractedTags[tagPos]);
    +        if (openDecoration) {
    +          // Close the current decoration
    +          html.push('</span>');
    +          openDecoration = null;
    +        }
    +        html.push(extractedTags[tagPos + 1]);
    +        tagPos += 2;
    +      } else if (decPos < decorations.length) {
    +        emitTextUpTo(decorations[decPos]);
    +        currentDecoration = decorations[decPos + 1];
    +        decPos += 2;
    +      } else {
    +        break;
    +      }
    +    }
    +    emitTextUpTo(sourceText.length);
    +    if (openDecoration) {
    +      html.push('</span>');
    +    }
    +    job.prettyPrintedHtml = html.join('');
    +  }
    +
    +  /** Maps language-specific file extensions to handlers. */
    +  var langHandlerRegistry = {};
    +  /** Register a language handler for the given file extensions.
    +    * @param {function (Object)} handler a function from source code to a list
    +    *      of decorations.  Takes a single argument job which describes the
    +    *      state of the computation.   The single parameter has the form
    +    *      {@code {
    +    *        source: {string} as plain text.
    +    *        decorations: {Array.<number|string>} an array of style classes
    +    *                     preceded by the position at which they start in
    +    *                     job.source in order.
    +    *                     The language handler should assigned this field.
    +    *        basePos: {int} the position of source in the larger source chunk.
    +    *                 All positions in the output decorations array are relative
    +    *                 to the larger source chunk.
    +    *      } }
    +    * @param {Array.<string>} fileExtensions
    +    */
    +  function registerLangHandler(handler, fileExtensions) {
    +    for (var i = fileExtensions.length; --i >= 0;) {
    +      var ext = fileExtensions[i];
    +      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    +        langHandlerRegistry[ext] = handler;
    +      } else if ('console' in window) {
    +        console.warn('cannot override language handler %s', ext);
    +      }
    +    }
    +  }
    +  function langHandlerForExtension(extension, source) {
    +    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    +      // Treat it as markup if the first non whitespace character is a < and
    +      // the last non-whitespace character is a >.
    +      extension = /^\s*</.test(source)
    +          ? 'default-markup'
    +          : 'default-code';
    +    }
    +    return langHandlerRegistry[extension];
    +  }
    +  registerLangHandler(decorateSource, ['default-code']);
    +  registerLangHandler(
    +      createSimpleLexer(
    +          [],
    +          [
    +           [PR_PLAIN,       /^[^<?]+/],
    +           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    +           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    +           // Unescaped content in an unknown language
    +           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    +           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    +           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    +           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    +           // Unescaped content in javascript.  (Or possibly vbscript).
    +           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    +           // Contains unescaped stylesheet content
    +           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    +           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    +          ]),
    +      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    +  registerLangHandler(
    +      createSimpleLexer(
    +          [
    +           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    +           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    +           ],
    +          [
    +           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    +           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    +           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    +           [PR_PUNCTUATION,  /^[=<>\/]+/],
    +           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    +           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    +           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    +           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    +           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    +           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    +           ]),
    +      ['in.tag']);
    +  registerLangHandler(
    +      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': CPP_KEYWORDS,
    +          'hashComments': true,
    +          'cStyleComments': true
    +        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': 'null true false'
    +        }), ['json']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': CSHARP_KEYWORDS,
    +          'hashComments': true,
    +          'cStyleComments': true,
    +          'verbatimStrings': true
    +        }), ['cs']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': JAVA_KEYWORDS,
    +          'cStyleComments': true
    +        }), ['java']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': SH_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true
    +        }), ['bsh', 'csh', 'sh']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': PYTHON_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'tripleQuotedStrings': true
    +        }), ['cv', 'py']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': PERL_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'regexLiterals': true
    +        }), ['perl', 'pl', 'pm']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': RUBY_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'regexLiterals': true
    +        }), ['rb']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': JSCRIPT_KEYWORDS,
    +          'cStyleComments': true,
    +          'regexLiterals': true
    +        }), ['js']);
    +  registerLangHandler(
    +      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    +
    +  function applyDecorator(job) {
    +    var sourceCodeHtml = job.sourceCodeHtml;
    +    var opt_langExtension = job.langExtension;
    +
    +    // Prepopulate output in case processing fails with an exception.
    +    job.prettyPrintedHtml = sourceCodeHtml;
    +
    +    try {
    +      // Extract tags, and convert the source code to plain text.
    +      var sourceAndExtractedTags = extractTags(sourceCodeHtml);
    +      /** Plain text. @type {string} */
    +      var source = sourceAndExtractedTags.source;
    +      job.source = source;
    +      job.basePos = 0;
    +
    +      /** Even entries are positions in source in ascending order.  Odd entries
    +        * are tags that were extracted at that position.
    +        * @type {Array.<number|string>}
    +        */
    +      job.extractedTags = sourceAndExtractedTags.tags;
    +
    +      // Apply the appropriate language handler
    +      langHandlerForExtension(opt_langExtension, source)(job);
    +      // Integrate the decorations and tags back into the source code to produce
    +      // a decorated html string which is left in job.prettyPrintedHtml.
    +      recombineTagsAndDecorations(job);
    +    } catch (e) {
    +      if ('console' in window) {
    +        console.log(e);
    +        console.trace();
    +      }
    +    }
    +  }
    +
    +  function prettyPrintOne(sourceCodeHtml, opt_langExtension) {
    +    var job = {
    +      sourceCodeHtml: sourceCodeHtml,
    +      langExtension: opt_langExtension
    +    };
    +    applyDecorator(job);
    +    return job.prettyPrintedHtml;
    +  }
    +
    +  function prettyPrint(opt_whenDone) {
    +    var isIE678 = window['_pr_isIE6']();
    +    var ieNewline = isIE678 === 6 ? '\r\n' : '\r';
    +    // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7-
    +
    +    // fetch a list of nodes to rewrite
    +    var codeSegments = [
    +        document.getElementsByTagName('pre'),
    +        document.getElementsByTagName('code'),
    +        document.getElementsByTagName('td'),  /* ND Change: Add tables to support prototypes. */
    +        document.getElementsByTagName('xmp') ];
    +    var elements = [];
    +    for (var i = 0; i < codeSegments.length; ++i) {
    +      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    +        elements.push(codeSegments[i][j]);
    +      }
    +    }
    +    codeSegments = null;
    +
    +    var clock = Date;
    +    if (!clock['now']) {
    +      clock = { 'now': function () { return (new Date).getTime(); } };
    +    }
    +
    +    // The loop is broken into a series of continuations to make sure that we
    +    // don't make the browser unresponsive when rewriting a large page.
    +    var k = 0;
    +    var prettyPrintingJob;
    +
    +    function doWork() {
    +      var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
    +                     clock.now() + 250 /* ms */ :
    +                     Infinity);
    +      for (; k < elements.length && clock.now() < endTime; k++) {
    +        var cs = elements[k];
    +        if (cs.className && cs.className.indexOf('prettyprint') >= 0) {
    +          // If the classes includes a language extensions, use it.
    +          // Language extensions can be specified like
    +          //     <pre class="prettyprint lang-cpp">
    +          // the language extension "cpp" is used to find a language handler as
    +          // passed to PR_registerLangHandler.
    +          var langExtension = cs.className.match(/\blang-(\w+)\b/);
    +          if (langExtension) { langExtension = langExtension[1]; }
    +
    +          // make sure this is not nested in an already prettified element
    +          var nested = false;
    +          for (var p = cs.parentNode; p; p = p.parentNode) {
    +            if ((p.tagName === 'pre' || p.tagName === 'code' ||
    +                 p.tagName === 'xmp' || p.tagName === 'td') &&  /* ND Change: Add tables to support prototypes */
    +                p.className && p.className.indexOf('prettyprint') >= 0) {
    +              nested = true;
    +              break;
    +            }
    +          }
    +          if (!nested) {
    +            // fetch the content as a snippet of properly escaped HTML.
    +            // Firefox adds newlines at the end.
    +            var content = getInnerHtml(cs);
    +            content = content.replace(/(?:\r\n?|\n)$/, '');
    +
    +	  		/* ND Change: we need to preserve &nbsp;s so change them to a special character instead of a space. */
    +			content = content.replace(/&nbsp;/g, '\x11');
    +
    +            // do the pretty printing
    +            prettyPrintingJob = {
    +              sourceCodeHtml: content,
    +              langExtension: langExtension,
    +              sourceNode: cs
    +            };
    +            applyDecorator(prettyPrintingJob);
    +            replaceWithPrettyPrintedHtml();
    +          }
    +        }
    +      }
    +      if (k < elements.length) {
    +        // finish up in a continuation
    +        setTimeout(doWork, 250);
    +      } else if (opt_whenDone) {
    +        opt_whenDone();
    +      }
    +    }
    +
    +    function replaceWithPrettyPrintedHtml() {
    +      var newContent = prettyPrintingJob.prettyPrintedHtml;
    +      if (!newContent) { return; }
    +
    +      /* ND Change: Restore the preserved &nbsp;s.  */
    +	  newContent = newContent.replace(/\x11/g, '&nbsp;');
    +
    +      var cs = prettyPrintingJob.sourceNode;
    +
    +      // push the prettified html back into the tag.
    +      if (!isRawContent(cs)) {
    +        // just replace the old html with the new
    +        cs.innerHTML = newContent;
    +      } else {
    +        // we need to change the tag to a <pre> since <xmp>s do not allow
    +        // embedded tags such as the span tags used to attach styles to
    +        // sections of source code.
    +        var pre = document.createElement('PRE');
    +        for (var i = 0; i < cs.attributes.length; ++i) {
    +          var a = cs.attributes[i];
    +          if (a.specified) {
    +            var aname = a.name.toLowerCase();
    +            if (aname === 'class') {
    +              pre.className = a.value;  // For IE 6
    +            } else {
    +              pre.setAttribute(a.name, a.value);
    +            }
    +          }
    +        }
    +        pre.innerHTML = newContent;
    +
    +        // remove the old
    +        cs.parentNode.replaceChild(pre, cs);
    +        cs = pre;
    +      }
    +
    +      // Replace <br>s with line-feeds so that copying and pasting works
    +      // on IE 6.
    +      // Doing this on other browsers breaks lots of stuff since \r\n is
    +      // treated as two newlines on Firefox, and doing this also slows
    +      // down rendering.
    +      if (isIE678 && cs.tagName === 'PRE') {
    +        var lineBreaks = cs.getElementsByTagName('br');
    +        for (var j = lineBreaks.length; --j >= 0;) {
    +          var lineBreak = lineBreaks[j];
    +          lineBreak.parentNode.replaceChild(
    +              document.createTextNode(ieNewline), lineBreak);
    +        }
    +      }
    +    }
    +
    +    doWork();
    +  }
    +
    +  window['PR_normalizedHtml'] = normalizedHtml;
    +  window['prettyPrintOne'] = prettyPrintOne;
    +  window['prettyPrint'] = prettyPrint;
    +  window['PR'] = {
    +        'combinePrefixPatterns': combinePrefixPatterns,
    +        'createSimpleLexer': createSimpleLexer,
    +        'registerLangHandler': registerLangHandler,
    +        'sourceDecorator': sourceDecorator,
    +        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    +        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    +        'PR_COMMENT': PR_COMMENT,
    +        'PR_DECLARATION': PR_DECLARATION,
    +        'PR_KEYWORD': PR_KEYWORD,
    +        'PR_LITERAL': PR_LITERAL,
    +        'PR_NOCODE': PR_NOCODE,
    +        'PR_PLAIN': PR_PLAIN,
    +        'PR_PUNCTUATION': PR_PUNCTUATION,
    +        'PR_SOURCE': PR_SOURCE,
    +        'PR_STRING': PR_STRING,
    +        'PR_TAG': PR_TAG,
    +        'PR_TYPE': PR_TYPE
    +      };
    +})();
    +
    +
    +// ____________________________________________________________________________
    +
    +
    +
    +// Lua extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],[PR.PR_STRING,/^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],[PR.PR_KEYWORD,/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_]\w*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]]),['lua'])
    +
    +
    +// Haskell extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\x0B\x0C\r ]+/,null,'	\n\r '],[PR.PR_STRING,/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'\"'],[PR.PR_STRING,/^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,null,'\''],[PR.PR_LITERAL,/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,'0123456789']],[[PR.PR_COMMENT,/^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],[PR.PR_KEYWORD,/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/,null],[PR.PR_PLAIN,/^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],[PR.PR_PUNCTUATION,/^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]]),['hs'])
    +
    +
    +// ML extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_COMMENT,/^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i,null,'#'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/],[PR.PR_KEYWORD,/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],[PR.PR_LITERAL,/^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^(?:[a-z_]\w*[!?#]?|``[^\r\n\t`]*(?:``|$))/i],[PR.PR_PUNCTUATION,/^[^\t\n\r \xA0\"\'\w]+/]]),['fs','ml'])
    +
    +
    +// SQL extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_STRING,/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],[PR.PR_KEYWORD,/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_][\w-]*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),['sql'])
    +
    +
    +// VB extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0\u2028\u2029]+/,null,'	\n\r \xa0\u2028\u2029'],[PR.PR_STRING,/^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i,null,'\"\u201c\u201d'],[PR.PR_COMMENT,/^[\'\u2018\u2019][^\r\n\u2028\u2029]*/,null,'\'\u2018\u2019']],[[PR.PR_KEYWORD,/^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i,null],[PR.PR_COMMENT,/^REM[^\r\n\u2028\u2029]*/i],[PR.PR_LITERAL,/^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i],[PR.PR_PLAIN,/^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*\])/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/],[PR.PR_PUNCTUATION,/^(?:\[|\])/]]),['vb','vbs'])
    diff --git a/src/drivers/dave2d/docs/javascript/searchdata.js b/src/drivers/dave2d/docs/javascript/searchdata.js
    new file mode 100644
    index 000000000..c697041d8
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/javascript/searchdata.js
    @@ -0,0 +1,92 @@
    +var indexSectionsWithContent = {
    +   "General": {
    +      "Symbols": false,
    +      "Numbers": false,
    +      "A": true,
    +      "B": true,
    +      "C": true,
    +      "D": true,
    +      "E": true,
    +      "F": true,
    +      "G": true,
    +      "H": false,
    +      "I": true,
    +      "J": false,
    +      "K": false,
    +      "L": true,
    +      "M": true,
    +      "N": true,
    +      "O": true,
    +      "P": true,
    +      "Q": false,
    +      "R": true,
    +      "S": true,
    +      "T": true,
    +      "U": true,
    +      "V": true,
    +      "W": true,
    +      "X": false,
    +      "Y": false,
    +      "Z": false
    +      },
    +   "Functions": {
    +      "Symbols": false,
    +      "Numbers": false,
    +      "A": true,
    +      "B": true,
    +      "C": true,
    +      "D": true,
    +      "E": true,
    +      "F": true,
    +      "G": true,
    +      "H": false,
    +      "I": true,
    +      "J": false,
    +      "K": false,
    +      "L": true,
    +      "M": true,
    +      "N": true,
    +      "O": true,
    +      "P": true,
    +      "Q": false,
    +      "R": true,
    +      "S": true,
    +      "T": false,
    +      "U": true,
    +      "V": false,
    +      "W": true,
    +      "X": false,
    +      "Y": false,
    +      "Z": false
    +      },
    +   "Types": {
    +      "Symbols": false,
    +      "Numbers": false,
    +      "A": false,
    +      "B": false,
    +      "C": false,
    +      "D": true,
    +      "E": false,
    +      "F": false,
    +      "G": false,
    +      "H": false,
    +      "I": false,
    +      "J": false,
    +      "K": false,
    +      "L": false,
    +      "M": false,
    +      "N": false,
    +      "O": false,
    +      "P": false,
    +      "Q": false,
    +      "R": false,
    +      "S": false,
    +      "T": false,
    +      "U": false,
    +      "V": false,
    +      "W": false,
    +      "X": false,
    +      "Y": false,
    +      "Z": false
    +      }
    +   }
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsA.html b/src/drivers/dave2d/docs/search/FunctionsA.html
    new file mode 100644
    index 000000000..1d02d45d2
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsA.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_add64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_add64" target=_parent class=ISymbol>add64</a></div></div><div class=SRResult id=SR_adddlist><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_dlist-c.html#d2_adddlist" target=_parent class=ISymbol>adddlist</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsB.html b/src/drivers/dave2d/docs/search/FunctionsB.html
    new file mode 100644
    index 000000000..f8d6369f1
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsB.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_blitcopy><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_blit-c.html#d2_blitcopy" target=_parent class=ISymbol>blitcopy</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsC.html b/src/drivers/dave2d/docs/search/FunctionsC.html
    new file mode 100644
    index 000000000..2fa8c7ce3
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsC.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_cast32to64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_cast32to64" target=_parent class=ISymbol>cast32to64</a></div></div><div class=SRResult id=SR_cast64to32><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_cast64to32" target=_parent class=ISymbol>cast64to32</a></div></div><div class=SRResult id=SR_clear><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_clear" target=_parent class=ISymbol>clear</a></div></div><div class=SRResult id=SR_cliprect><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_cliprect" target=_parent class=ISymbol>cliprect</a></div></div><div class=SRResult id=SR_closedevice><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_closedevice" target=_parent class=ISymbol>closedevice</a></div></div><div class=SRResult id=SR_commandspending><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_commandspending" target=_parent class=ISymbol>commandspending</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsD.html b/src/drivers/dave2d/docs/search/FunctionsD.html
    new file mode 100644
    index 000000000..eaee130ac
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsD.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_D2_undFIX4_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_FIX4(x)" target=_parent class=ISymbol>D2_FIX4(x)</a></div></div><div class=SRResult id=SR_deinithw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_deinithw" target=_parent class=ISymbol>deinithw</a></div></div><div class=SRResult id=SR_div6432><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_div6432" target=_parent class=ISymbol>div6432</a></div></div><div class=SRResult id=SR_dumprenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_dumprenderbuffer" target=_parent class=ISymbol>dumprenderbuffer</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsE.html b/src/drivers/dave2d/docs/search/FunctionsE.html
    new file mode 100644
    index 000000000..4b7b149df
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsE.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_endframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_endframe" target=_parent class=ISymbol>endframe</a></div></div><div class=SRResult id=SR_executedlist><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_dlist-c.html#d2_executedlist" target=_parent class=ISymbol>executedlist</a></div></div><div class=SRResult id=SR_executerenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_executerenderbuffer" target=_parent class=ISymbol>executerenderbuffer</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsF.html b/src/drivers/dave2d/docs/search/FunctionsF.html
    new file mode 100644
    index 000000000..be95afd97
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsF.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_flushframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_flushframe" target=_parent class=ISymbol>flushframe</a></div></div><div class=SRResult id=SR_framebuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_framebuffer" target=_parent class=ISymbol>framebuffer</a></div></div><div class=SRResult id=SR_freecontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_freecontext" target=_parent class=ISymbol>freecontext</a></div></div><div class=SRResult id=SR_freedumpedbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_freedumpedbuffer" target=_parent class=ISymbol>freedumpedbuffer</a></div></div><div class=SRResult id=SR_freerenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_freerenderbuffer" target=_parent class=ISymbol>freerenderbuffer</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsG.html b/src/drivers/dave2d/docs/search/FunctionsG.html
    new file mode 100644
    index 000000000..391afe6a9
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsG.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_getalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalpha" target=_parent class=ISymbol>getalpha</a></div></div><div class=SRResult id=SR_getalphablendmodedst><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphablendmodedst" target=_parent class=ISymbol>getalphablendmodedst</a></div></div><div class=SRResult id=SR_getalphablendmodeflags><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphablendmodeflags" target=_parent class=ISymbol>getalphablendmodeflags</a></div></div><div class=SRResult id=SR_getalphablendmodesrc><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphablendmodesrc" target=_parent class=ISymbol>getalphablendmodesrc</a></div></div><div class=SRResult id=SR_getalphaex><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphaex" target=_parent class=ISymbol>getalphaex</a></div></div><div class=SRResult id=SR_getalphamode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphamode" target=_parent class=ISymbol>getalphamode</a></div></div><div class=SRResult id=SR_getantialiasing><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getantialiasing" target=_parent class=ISymbol>getantialiasing</a></div></div><div class=SRResult id=SR_getblendmodedst><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getblendmodedst" target=_parent class=ISymbol>getblendmodedst</a></div></div><div class=SRResult id=SR_getblendmodesrc><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getblendmodesrc" target=_parent class=ISymbol>getblendmodesrc</a></div></div><div class=SRResult id=SR_getblur><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getblur" target=_parent class=ISymbol>getblur</a></div></div><div class=SRResult id=SR_getcliprect><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_getcliprect" target=_parent class=ISymbol>getcliprect</a></div></div><div class=SRResult id=SR_getcolor><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getcolor" target=_parent class=ISymbol>getcolor</a></div></div><div class=SRResult id=SR_getcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getcontext" target=_parent class=ISymbol>getcontext</a></div></div><div class=SRResult id=SR_getdlistblockcount><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getdlistblockcount" target=_parent class=ISymbol>getdlistblockcount</a></div></div><div class=SRResult id=SR_getdlistblocksize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getdlistblocksize" target=_parent class=ISymbol>getdlistblocksize</a></div></div><div class=SRResult id=SR_geterror><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_geterror" target=_parent class=ISymbol>geterror</a></div></div><div class=SRResult id=SR_geterrorstring><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_geterrorstring" target=_parent class=ISymbol>geterrorstring</a></div></div><div class=SRResult id=SR_getfillmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getfillmode" target=_parent class=ISymbol>getfillmode</a></div></div><div class=SRResult id=SR_getframebuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_getframebuffer" target=_parent class=ISymbol>getframebuffer</a></div></div><div class=SRResult id=SR_getlinecap><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getlinecap" target=_parent class=ISymbol>getlinecap</a></div></div><div class=SRResult id=SR_getlinejoin><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getlinejoin" target=_parent class=ISymbol>getlinejoin</a></div></div><div class=SRResult id=SR_getpattern><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpattern" target=_parent class=ISymbol>getpattern</a></div></div><div class=SRResult id=SR_getpatternalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpatternalpha" target=_parent class=ISymbol>getpatternalpha</a></div></div><div class=SRResult id=SR_getpatternmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpatternmode" target=_parent class=ISymbol>getpatternmode</a></div></div><div class=SRResult id=SR_getpatternsize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpatternsize" target=_parent class=ISymbol>getpatternsize</a></div></div><div class=SRResult id=SR_getperfcountvalue><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_perfcount-c.html#d2_getperfcountvalue" target=_parent class=ISymbol>getperfcountvalue</a></div></div><div class=SRResult id=SR_getrenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_getrenderbuffer" target=_parent class=ISymbol>getrenderbuffer</a></div></div><div class=SRResult id=SR_getrenderbuffersize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_getrenderbuffersize" target=_parent class=ISymbol>getrenderbuffersize</a></div></div><div class=SRResult id=SR_getrendermode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getrendermode" target=_parent class=ISymbol>getrendermode</a></div></div><div class=SRResult id=SR_getrevisionhw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getrevisionhw" target=_parent class=ISymbol>getrevisionhw</a></div></div><div class=SRResult id=SR_getrevisionstringhw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getrevisionstringhw" target=_parent class=ISymbol>getrevisionstringhw</a></div></div><div class=SRResult id=SR_gettexopparam1><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettexopparam1" target=_parent class=ISymbol>gettexopparam1</a></div></div><div class=SRResult id=SR_gettexopparam2><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettexopparam2" target=_parent class=ISymbol>gettexopparam2</a></div></div><div class=SRResult id=SR_gettextureoperationa><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationa" target=_parent class=ISymbol>gettextureoperationa</a></div></div><div class=SRResult id=SR_gettextureoperationb><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationb" target=_parent class=ISymbol>gettextureoperationb</a></div></div><div class=SRResult id=SR_gettextureoperationg><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationg" target=_parent class=ISymbol>gettextureoperationg</a></div></div><div class=SRResult id=SR_gettextureoperationr><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationr" target=_parent class=ISymbol>gettextureoperationr</a></div></div><div class=SRResult id=SR_getversion><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getversion" target=_parent class=ISymbol>getversion</a></div></div><div class=SRResult id=SR_getversionstring><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getversionstring" target=_parent class=ISymbol>getversionstring</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsI.html b/src/drivers/dave2d/docs/search/FunctionsI.html
    new file mode 100644
    index 000000000..c465a06a2
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsI.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_inithw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_inithw" target=_parent class=ISymbol>inithw</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsL.html b/src/drivers/dave2d/docs/search/FunctionsL.html
    new file mode 100644
    index 000000000..66092b510
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsL.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_layermerge><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_layermerge" target=_parent class=ISymbol>layermerge</a></div></div><div class=SRResult id=SR_level1interface><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_level1interface" target=_parent class=ISymbol>level1interface</a></div></div><div class=SRResult id=SR_lowlocalmemmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_lowlocalmemmode" target=_parent class=ISymbol>lowlocalmemmode</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsM.html b/src/drivers/dave2d/docs/search/FunctionsM.html
    new file mode 100644
    index 000000000..5cebe2256
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsM.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_mul3232to64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_mul3232to64" target=_parent class=ISymbol>mul3232to64</a></div></div><div class=SRResult id=SR_mul3264><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_mul3264" target=_parent class=ISymbol>mul3264</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsN.html b/src/drivers/dave2d/docs/search/FunctionsN.html
    new file mode 100644
    index 000000000..9c12095a1
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsN.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_newcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_newcontext" target=_parent class=ISymbol>newcontext</a></div></div><div class=SRResult id=SR_newrenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_newrenderbuffer" target=_parent class=ISymbol>newrenderbuffer</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsO.html b/src/drivers/dave2d/docs/search/FunctionsO.html
    new file mode 100644
    index 000000000..ad4a32b7a
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsO.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_opendevice><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_opendevice" target=_parent class=ISymbol>opendevice</a></div></div><div class=SRResult id=SR_outlinecontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_outlinecontext" target=_parent class=ISymbol>outlinecontext</a></div></div><div class=SRResult id=SR_outlinewidth><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_outlinewidth" target=_parent class=ISymbol>outlinewidth</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsP.html b/src/drivers/dave2d/docs/search/FunctionsP.html
    new file mode 100644
    index 000000000..eda1680be
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsP.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_pow2mask><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/inc/dave_math-h.html#d2_pow2mask" target=_parent class=ISymbol>pow2mask</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsR.html b/src/drivers/dave2d/docs/search/FunctionsR.html
    new file mode 100644
    index 000000000..22beb4382
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsR.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_relocateframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_relocateframe" target=_parent class=ISymbol>relocateframe</a></div></div><div class=SRResult id=SR_renderbox><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderbox" target=_parent class=ISymbol>renderbox</a></div></div><div class=SRResult id=SR_rendercircle><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendercircle" target=_parent class=ISymbol>rendercircle</a></div></div><div class=SRResult id=SR_rendercircle_undno_undhilimiterprecision><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_rendercircle_no_hilimiterprecision" target=_parent class=ISymbol>rendercircle_no_hilimiterprecision</a></div></div><div class=SRResult id=SR_renderline><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderline" target=_parent class=ISymbol>renderline</a></div></div><div class=SRResult id=SR_renderline2><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderline2" target=_parent class=ISymbol>renderline2</a></div></div><div class=SRResult id=SR_renderpolygon><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderpolygon" target=_parent class=ISymbol>renderpolygon</a></div></div><div class=SRResult id=SR_renderpolyline><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderpolyline" target=_parent class=ISymbol>renderpolyline</a></div></div><div class=SRResult id=SR_renderpolyline2><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderpolyline2" target=_parent class=ISymbol>renderpolyline2</a></div></div><div class=SRResult id=SR_renderquad><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderquad" target=_parent class=ISymbol>renderquad</a></div></div><div class=SRResult id=SR_rendertri><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertri" target=_parent class=ISymbol>rendertri</a></div></div><div class=SRResult id=SR_rendertrifan><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertrifan" target=_parent class=ISymbol>rendertrifan</a></div></div><div class=SRResult id=SR_rendertrilist><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertrilist" target=_parent class=ISymbol>rendertrilist</a></div></div><div class=SRResult id=SR_rendertristrip><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertristrip" target=_parent class=ISymbol>rendertristrip</a></div></div><div class=SRResult id=SR_renderwedge><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderwedge" target=_parent class=ISymbol>renderwedge</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsS.html b/src/drivers/dave2d/docs/search/FunctionsS.html
    new file mode 100644
    index 000000000..c86aeeba4
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsS.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_selectcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_selectcontext" target=_parent class=ISymbol>selectcontext</a></div></div><div class=SRResult id=SR_selectrenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_selectrenderbuffer" target=_parent class=ISymbol>selectrenderbuffer</a></div></div><div class=SRResult id=SR_selectrendermode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_selectrendermode" target=_parent class=ISymbol>selectrendermode</a></div></div><div class=SRResult id=SR_setalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalpha" target=_parent class=ISymbol>setalpha</a></div></div><div class=SRResult id=SR_setalphablendmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphablendmode" target=_parent class=ISymbol>setalphablendmode</a></div></div><div class=SRResult id=SR_setalphablendmodeex><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphablendmodeex" target=_parent class=ISymbol>setalphablendmodeex</a></div></div><div class=SRResult id=SR_setalphaex><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphaex" target=_parent class=ISymbol>setalphaex</a></div></div><div class=SRResult id=SR_setalphagradient><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphagradient" target=_parent class=ISymbol>setalphagradient</a></div></div><div class=SRResult id=SR_setalphamode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphamode" target=_parent class=ISymbol>setalphamode</a></div></div><div class=SRResult id=SR_setantialiasing><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setantialiasing" target=_parent class=ISymbol>setantialiasing</a></div></div><div class=SRResult id=SR_setblendmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setblendmode" target=_parent class=ISymbol>setblendmode</a></div></div><div class=SRResult id=SR_setblitsrc><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_blit-c.html#d2_setblitsrc" target=_parent class=ISymbol>setblitsrc</a></div></div><div class=SRResult id=SR_setblur><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setblur" target=_parent class=ISymbol>setblur</a></div></div><div class=SRResult id=SR_setcircleextend><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setcircleextend" target=_parent class=ISymbol>setcircleextend</a></div></div><div class=SRResult id=SR_setclipgradient><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setclipgradient" target=_parent class=ISymbol>setclipgradient</a></div></div><div class=SRResult id=SR_setcolor><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setcolor" target=_parent class=ISymbol>setcolor</a></div></div><div class=SRResult id=SR_setcolorkey><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_setcolorkey" target=_parent class=ISymbol>setcolorkey</a></div></div><div class=SRResult id=SR_setdlistblocksize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_setdlistblocksize" target=_parent class=ISymbol>setdlistblocksize</a></div></div><div class=SRResult id=SR_setfillmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setfillmode" target=_parent class=ISymbol>setfillmode</a></div></div><div class=SRResult id=SR_setlinecap><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setlinecap" target=_parent class=ISymbol>setlinecap</a></div></div><div class=SRResult id=SR_setlinejoin><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setlinejoin" target=_parent class=ISymbol>setlinejoin</a></div></div><div class=SRResult id=SR_setlinepattern><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setlinepattern" target=_parent class=ISymbol>setlinepattern</a></div></div><div class=SRResult id=SR_setmiterlimit><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setmiterlimit" target=_parent class=ISymbol>setmiterlimit</a></div></div><div class=SRResult id=SR_setpattern><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpattern" target=_parent class=ISymbol>setpattern</a></div></div><div class=SRResult id=SR_setpatternalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternalpha" target=_parent class=ISymbol>setpatternalpha</a></div></div><div class=SRResult id=SR_setpatternmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternmode" target=_parent class=ISymbol>setpatternmode</a></div></div><div class=SRResult id=SR_setpatternparam><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternparam" target=_parent class=ISymbol>setpatternparam</a></div></div><div class=SRResult id=SR_setpatternsize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternsize" target=_parent class=ISymbol>setpatternsize</a></div></div><div class=SRResult id=SR_setperfcountevent><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_perfcount-c.html#d2_setperfcountevent" target=_parent class=ISymbol>setperfcountevent</a></div></div><div class=SRResult id=SR_setperfcountvalue><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_perfcount-c.html#d2_setperfcountvalue" target=_parent class=ISymbol>setperfcountvalue</a></div></div><div class=SRResult id=SR_settexclut><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut" target=_parent class=ISymbol>settexclut</a></div></div><div class=SRResult id=SR_settexclut_undformat><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut_format" target=_parent class=ISymbol>settexclut_format</a></div></div><div class=SRResult id=SR_settexclut_undoffset><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut_offset" target=_parent class=ISymbol>settexclut_offset</a></div></div><div class=SRResult id=SR_settexclut_undpart><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut_part" target=_parent class=ISymbol>settexclut_part</a></div></div><div class=SRResult id=SR_settexelcenter><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexelcenter" target=_parent class=ISymbol>settexelcenter</a></div></div><div class=SRResult id=SR_settexopparam><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexopparam" target=_parent class=ISymbol>settexopparam</a></div></div><div class=SRResult id=SR_settexture><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexture" target=_parent class=ISymbol>settexture</a></div></div><div class=SRResult id=SR_settexturemapping><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexturemapping" target=_parent class=ISymbol>settexturemapping</a></div></div><div class=SRResult id=SR_settexturemode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexturemode" target=_parent class=ISymbol>settexturemode</a></div></div><div class=SRResult id=SR_settextureoperation><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settextureoperation" target=_parent class=ISymbol>settextureoperation</a></div></div><div class=SRResult id=SR_shadowoffset><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_shadowoffset" target=_parent class=ISymbol>shadowoffset</a></div></div><div class=SRResult id=SR_shiftleft64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_shiftleft64" target=_parent class=ISymbol>shiftleft64</a></div></div><div class=SRResult id=SR_shiftright64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_shiftright64" target=_parent class=ISymbol>shiftright64</a></div></div><div class=SRResult id=SR_solidcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_solidcontext" target=_parent class=ISymbol>solidcontext</a></div></div><div class=SRResult id=SR_sqrt><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/inc/dave_math-h.html#d2_sqrt" target=_parent class=ISymbol>sqrt</a></div></div><div class=SRResult id=SR_startframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_startframe" target=_parent class=ISymbol>startframe</a></div></div><div class=SRResult id=SR_sub64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_sub64" target=_parent class=ISymbol>sub64</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsU.html b/src/drivers/dave2d/docs/search/FunctionsU.html
    new file mode 100644
    index 000000000..df4abc889
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsU.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_utility_undfbblitcopy><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_utility_fbblitcopy" target=_parent class=ISymbol>utility_fbblitcopy</a></div></div><div class=SRResult id=SR_utility_undmaptriangle><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_utility_maptriangle" target=_parent class=ISymbol>utility_maptriangle</a></div></div><div class=SRResult id=SR_utility_undperspectivewarp><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_utility_perspectivewarp" target=_parent class=ISymbol>utility_perspectivewarp</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/FunctionsW.html b/src/drivers/dave2d/docs/search/FunctionsW.html
    new file mode 100644
    index 000000000..07e3ed6ec
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/FunctionsW.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_writetexclut_unddirect><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_writetexclut_direct" target=_parent class=ISymbol>writetexclut_direct</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralA.html b/src/drivers/dave2d/docs/search/GeneralA.html
    new file mode 100644
    index 000000000..1d02d45d2
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralA.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_add64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_add64" target=_parent class=ISymbol>add64</a></div></div><div class=SRResult id=SR_adddlist><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_dlist-c.html#d2_adddlist" target=_parent class=ISymbol>adddlist</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralB.html b/src/drivers/dave2d/docs/search/GeneralB.html
    new file mode 100644
    index 000000000..c76b3bd76
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralB.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Basic_spcFunctions><div class=IEntry><a href="../files/code/dave_driver-c.html#Basic_Functions" target=_parent class=ISymbol>Basic Functions</a></div></div><div class=SRResult id=SR_Basic_spcTypes><div class=IEntry><a href="../files/inc/dave_driver-h.html#Basic_Types" target=_parent class=ISymbol>Basic Types</a></div></div><div class=SRResult id=SR_BLIT_spcAttributes_spcWrites><div class=IEntry><a href="../files/code/dave_blit-c.html#BLIT_Attributes_Writes" target=_parent class=ISymbol>BLIT Attributes Writes</a></div></div><div class=SRResult id=SR_Blit_spcFunctions><div class=IEntry><a href="../files/code/dave_blit-c.html#Blit_Functions" target=_parent class=ISymbol>Blit Functions</a></div></div><div class=SRResult id=SR_BLIT_spcRendering_spcFunctions><div class=IEntry><a href="../files/code/dave_blit-c.html#BLIT_Rendering_Functions" target=_parent class=ISymbol>BLIT Rendering Functions</a></div></div><div class=SRResult id=SR_blitcopy><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_blit-c.html#d2_blitcopy" target=_parent class=ISymbol>blitcopy</a></div></div><div class=SRResult id=SR_Buffer_spcRendering><div class=IEntry><a href="../files/code/dave_render-c.html#Buffer_Rendering" target=_parent class=ISymbol>Buffer Rendering</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralC.html b/src/drivers/dave2d/docs/search/GeneralC.html
    new file mode 100644
    index 000000000..cb5412919
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralC.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_cast32to64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_cast32to64" target=_parent class=ISymbol>cast32to64</a></div></div><div class=SRResult id=SR_cast64to32><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_cast64to32" target=_parent class=ISymbol>cast64to32</a></div></div><div class=SRResult id=SR_clear><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_clear" target=_parent class=ISymbol>clear</a></div></div><div class=SRResult id=SR_Clipping><div class=IEntry><a href="../files/code/dave_viewport-c.html#Clipping" target=_parent class=ISymbol>Clipping</a></div></div><div class=SRResult id=SR_cliprect><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_cliprect" target=_parent class=ISymbol>cliprect</a></div></div><div class=SRResult id=SR_closedevice><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_closedevice" target=_parent class=ISymbol>closedevice</a></div></div><div class=SRResult id=SR_Coding_spcconventions><div class=IEntry><a href="../files/doc/overview-txt.html#Coding_conventions" target=_parent class=ISymbol>Coding conventions</a></div></div><div class=SRResult id=SR_commandspending><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_commandspending" target=_parent class=ISymbol>commandspending</a></div></div><div class=SRResult id=SR_Concept><div class=IEntry><a href="../files/doc/overview-txt.html#Concept" target=_parent class=ISymbol>Concept</a></div></div><div class=SRResult id=SR_Context_spcAttribute_spcQueries><div class=IEntry><a href="../files/code/dave_context-c.html#Context_Attribute_Queries" target=_parent class=ISymbol>Context Attribute Queries</a></div></div><div class=SRResult id=SR_Context_spcAttribute_spcWrites><div class=IEntry><a href="../files/code/dave_context-c.html#Context_Attribute_Writes" target=_parent class=ISymbol>Context Attribute Writes</a></div></div><div class=SRResult id=SR_Context_spcFunctions><div class=IEntry><a href="../files/code/dave_context-c.html#Context_Functions" target=_parent class=ISymbol>Context Functions</a></div></div><div class=SRResult id=SR_Context_spcManagement><div class=IEntry><a href="../files/code/dave_context-c.html#Context_Management" target=_parent class=ISymbol>Context Management</a></div></div><div class=SRResult id=SR_Coordinate_spcrange_spclimitations><div class=IEntry><a href="../files/doc/limitations-txt.html#Coordinate_range_limitations" target=_parent class=ISymbol>Coordinate range limitations</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralD.html b/src/drivers/dave2d/docs/search/GeneralD.html
    new file mode 100644
    index 000000000..24c34e846
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralD.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_d2_undalpha><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_alpha" target=_parent class=ISymbol>d2_alpha</a></div></div><div class=SRResult id=SR_d2_undblitpos><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_blitpos" target=_parent class=ISymbol>d2_blitpos</a></div></div><div class=SRResult id=SR_d2_undborder><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_border" target=_parent class=ISymbol>d2_border</a></div></div><div class=SRResult id=SR_D2_undCEIL16_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_CEIL16(x)" target=_parent class=ISymbol>D2_CEIL16(x)</a></div></div><div class=SRResult id=SR_D2_undCEIL4_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_CEIL4(x)" target=_parent class=ISymbol>D2_CEIL4(x)</a></div></div><div class=SRResult id=SR_d2_undcolor><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_color" target=_parent class=ISymbol>d2_color</a></div></div><div class=SRResult id=SR_d2_undcontext><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_context" target=_parent class=ISymbol>d2_context</a></div></div><div class=SRResult id=SR_d2_unddevice><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_device" target=_parent class=ISymbol>d2_device</a></div></div><div class=SRResult id=SR_D2_undEPSILON><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_EPSILON" target=_parent class=ISymbol>D2_EPSILON</a></div></div><div class=SRResult id=SR_D2_undFIX16_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_FIX16(x)" target=_parent class=ISymbol>D2_FIX16(x)</a></div></div><div class=SRResult id=SR_D2_undFIX4_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_FIX4(x)" target=_parent class=ISymbol>D2_FIX4(x)</a></div></div><div class=SRResult id=SR_D2_undFLOOR16_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_FLOOR16(x)" target=_parent class=ISymbol>D2_FLOOR16(x)</a></div></div><div class=SRResult id=SR_D2_undFLOOR4_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_FLOOR4(x)" target=_parent class=ISymbol>D2_FLOOR4(x)</a></div></div><div class=SRResult id=SR_D2_undFRAC16_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_FRAC16(x)" target=_parent class=ISymbol>D2_FRAC16(x)</a></div></div><div class=SRResult id=SR_D2_undFRAC4_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_FRAC4(x)" target=_parent class=ISymbol>D2_FRAC4(x)</a></div></div><div class=SRResult id=SR_D2_undINT16_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_INT16(x)" target=_parent class=ISymbol>D2_INT16(x)</a></div></div><div class=SRResult id=SR_D2_undINT4_lpax_rpa><div class=IEntry><a href="../files/inc/dave_math-h.html#D2_INT4(x)" target=_parent class=ISymbol>D2_INT4(x)</a></div></div><div class=SRResult id=SR_d2_undpattern><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_pattern" target=_parent class=ISymbol>d2_pattern</a></div></div><div class=SRResult id=SR_d2_undpoint><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_point" target=_parent class=ISymbol>d2_point</a></div></div><div class=SRResult id=SR_d2_undrenderbuffer><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_renderbuffer" target=_parent class=ISymbol>d2_renderbuffer</a></div></div><div class=SRResult id=SR_d2_undwidth><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_width" target=_parent class=ISymbol>d2_width</a></div></div><div class=SRResult id=SR_deinithw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_deinithw" target=_parent class=ISymbol>deinithw</a></div></div><div class=SRResult id=SR_Device_spcmanagement><div class=IEntry><a href="../files/code/dave_driver-c.html#Device_management" target=_parent class=ISymbol>Device management</a></div></div><div class=SRResult id=SR_Direct_spcRendering><div class=IEntry><a href="../files/code/dave_render-c.html#Direct_Rendering" target=_parent class=ISymbol>Direct Rendering</a></div></div><div class=SRResult id=SR_div6432><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_div6432" target=_parent class=ISymbol>div6432</a></div></div><div class=SRResult id=SR_Dlist_spcFunctions><div class=IEntry><a href="../files/code/dave_dlist-c.html#Dlist_Functions" target=_parent class=ISymbol>Dlist Functions</a></div></div><div class=SRResult id=SR_Driver_spcOverview><div class=IEntry><a href="../files/doc/overview-txt.html#Driver_Overview" target=_parent class=ISymbol>Driver Overview</a></div></div><div class=SRResult id=SR_dumprenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_dumprenderbuffer" target=_parent class=ISymbol>dumprenderbuffer</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralE.html b/src/drivers/dave2d/docs/search/GeneralE.html
    new file mode 100644
    index 000000000..63eab87f6
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralE.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_endframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_endframe" target=_parent class=ISymbol>endframe</a></div></div><div class=SRResult id=SR_Errorcodes><div class=IEntry><a href="../files/inc/dave_errorcodes-h.html#Errorcodes" target=_parent class=ISymbol>Errorcodes</a></div></div><div class=SRResult id=SR_executedlist><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_dlist-c.html#d2_executedlist" target=_parent class=ISymbol>executedlist</a></div></div><div class=SRResult id=SR_executerenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_executerenderbuffer" target=_parent class=ISymbol>executerenderbuffer</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralF.html b/src/drivers/dave2d/docs/search/GeneralF.html
    new file mode 100644
    index 000000000..b803d25e9
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralF.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Fixedpoint_spcMacros><div class=IEntry><a href="../files/inc/dave_math-h.html#Fixedpoint_Macros" target=_parent class=ISymbol>Fixedpoint Macros</a></div></div><div class=SRResult id=SR_flushframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_flushframe" target=_parent class=ISymbol>flushframe</a></div></div><div class=SRResult id=SR_framebuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_framebuffer" target=_parent class=ISymbol>framebuffer</a></div></div><div class=SRResult id=SR_Framebuffer_spcmanagement><div class=IEntry><a href="../files/code/dave_viewport-c.html#Framebuffer_management" target=_parent class=ISymbol>Framebuffer management</a></div></div><div class=SRResult id=SR_Framebuffer_spcsize_spclimitations><div class=IEntry><a href="../files/doc/limitations-txt.html#Framebuffer_size_limitations" target=_parent class=ISymbol>Framebuffer size limitations</a></div></div><div class=SRResult id=SR_freecontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_freecontext" target=_parent class=ISymbol>freecontext</a></div></div><div class=SRResult id=SR_freedumpedbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_freedumpedbuffer" target=_parent class=ISymbol>freedumpedbuffer</a></div></div><div class=SRResult id=SR_freerenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_freerenderbuffer" target=_parent class=ISymbol>freerenderbuffer</a></div></div><div class=SRResult id=SR_Functions><div class=IEntry><a href="javascript:searchResults.Toggle('SR_Functions')" class=ISymbol>Functions</a><div class=ISubIndex><a href="../files/code/dave_64bitoperation-c.html#Functions" target=_parent class=IFile>code/<wbr>dave_64bitoperation.c</a><a href="../files/code/dave_dlist-c.html#Functions" target=_parent class=IFile>code/<wbr>dave_dlist.c</a><a href="../files/code/dave_utility-c.html#Functions" target=_parent class=IFile>code/<wbr>dave_utility.c</a></div></div></div><div class=SRResult id=SR_functions_spcfor_spc64bit_spcoperations><div class=IEntry><a href="../files/code/dave_64bitoperation-c.html#functions_for_64bit_operations" target=_parent class=ISymbol>functions for 64bit operations</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralG.html b/src/drivers/dave2d/docs/search/GeneralG.html
    new file mode 100644
    index 000000000..391afe6a9
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralG.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_getalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalpha" target=_parent class=ISymbol>getalpha</a></div></div><div class=SRResult id=SR_getalphablendmodedst><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphablendmodedst" target=_parent class=ISymbol>getalphablendmodedst</a></div></div><div class=SRResult id=SR_getalphablendmodeflags><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphablendmodeflags" target=_parent class=ISymbol>getalphablendmodeflags</a></div></div><div class=SRResult id=SR_getalphablendmodesrc><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphablendmodesrc" target=_parent class=ISymbol>getalphablendmodesrc</a></div></div><div class=SRResult id=SR_getalphaex><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphaex" target=_parent class=ISymbol>getalphaex</a></div></div><div class=SRResult id=SR_getalphamode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getalphamode" target=_parent class=ISymbol>getalphamode</a></div></div><div class=SRResult id=SR_getantialiasing><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getantialiasing" target=_parent class=ISymbol>getantialiasing</a></div></div><div class=SRResult id=SR_getblendmodedst><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getblendmodedst" target=_parent class=ISymbol>getblendmodedst</a></div></div><div class=SRResult id=SR_getblendmodesrc><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getblendmodesrc" target=_parent class=ISymbol>getblendmodesrc</a></div></div><div class=SRResult id=SR_getblur><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getblur" target=_parent class=ISymbol>getblur</a></div></div><div class=SRResult id=SR_getcliprect><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_getcliprect" target=_parent class=ISymbol>getcliprect</a></div></div><div class=SRResult id=SR_getcolor><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getcolor" target=_parent class=ISymbol>getcolor</a></div></div><div class=SRResult id=SR_getcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getcontext" target=_parent class=ISymbol>getcontext</a></div></div><div class=SRResult id=SR_getdlistblockcount><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getdlistblockcount" target=_parent class=ISymbol>getdlistblockcount</a></div></div><div class=SRResult id=SR_getdlistblocksize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getdlistblocksize" target=_parent class=ISymbol>getdlistblocksize</a></div></div><div class=SRResult id=SR_geterror><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_geterror" target=_parent class=ISymbol>geterror</a></div></div><div class=SRResult id=SR_geterrorstring><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_geterrorstring" target=_parent class=ISymbol>geterrorstring</a></div></div><div class=SRResult id=SR_getfillmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getfillmode" target=_parent class=ISymbol>getfillmode</a></div></div><div class=SRResult id=SR_getframebuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_viewport-c.html#d2_getframebuffer" target=_parent class=ISymbol>getframebuffer</a></div></div><div class=SRResult id=SR_getlinecap><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getlinecap" target=_parent class=ISymbol>getlinecap</a></div></div><div class=SRResult id=SR_getlinejoin><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getlinejoin" target=_parent class=ISymbol>getlinejoin</a></div></div><div class=SRResult id=SR_getpattern><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpattern" target=_parent class=ISymbol>getpattern</a></div></div><div class=SRResult id=SR_getpatternalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpatternalpha" target=_parent class=ISymbol>getpatternalpha</a></div></div><div class=SRResult id=SR_getpatternmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpatternmode" target=_parent class=ISymbol>getpatternmode</a></div></div><div class=SRResult id=SR_getpatternsize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_getpatternsize" target=_parent class=ISymbol>getpatternsize</a></div></div><div class=SRResult id=SR_getperfcountvalue><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_perfcount-c.html#d2_getperfcountvalue" target=_parent class=ISymbol>getperfcountvalue</a></div></div><div class=SRResult id=SR_getrenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_getrenderbuffer" target=_parent class=ISymbol>getrenderbuffer</a></div></div><div class=SRResult id=SR_getrenderbuffersize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_getrenderbuffersize" target=_parent class=ISymbol>getrenderbuffersize</a></div></div><div class=SRResult id=SR_getrendermode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getrendermode" target=_parent class=ISymbol>getrendermode</a></div></div><div class=SRResult id=SR_getrevisionhw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getrevisionhw" target=_parent class=ISymbol>getrevisionhw</a></div></div><div class=SRResult id=SR_getrevisionstringhw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getrevisionstringhw" target=_parent class=ISymbol>getrevisionstringhw</a></div></div><div class=SRResult id=SR_gettexopparam1><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettexopparam1" target=_parent class=ISymbol>gettexopparam1</a></div></div><div class=SRResult id=SR_gettexopparam2><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettexopparam2" target=_parent class=ISymbol>gettexopparam2</a></div></div><div class=SRResult id=SR_gettextureoperationa><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationa" target=_parent class=ISymbol>gettextureoperationa</a></div></div><div class=SRResult id=SR_gettextureoperationb><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationb" target=_parent class=ISymbol>gettextureoperationb</a></div></div><div class=SRResult id=SR_gettextureoperationg><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationg" target=_parent class=ISymbol>gettextureoperationg</a></div></div><div class=SRResult id=SR_gettextureoperationr><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_gettextureoperationr" target=_parent class=ISymbol>gettextureoperationr</a></div></div><div class=SRResult id=SR_getversion><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getversion" target=_parent class=ISymbol>getversion</a></div></div><div class=SRResult id=SR_getversionstring><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_getversionstring" target=_parent class=ISymbol>getversionstring</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralI.html b/src/drivers/dave2d/docs/search/GeneralI.html
    new file mode 100644
    index 000000000..c465a06a2
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralI.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_inithw><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_inithw" target=_parent class=ISymbol>inithw</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralL.html b/src/drivers/dave2d/docs/search/GeneralL.html
    new file mode 100644
    index 000000000..aff731aa1
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralL.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_layermerge><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_layermerge" target=_parent class=ISymbol>layermerge</a></div></div><div class=SRResult id=SR_level1interface><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_level1interface" target=_parent class=ISymbol>level1interface</a></div></div><div class=SRResult id=SR_Limitations><div class=IEntry><a href="../files/doc/limitations-txt.html#Limitations" target=_parent class=ISymbol>Limitations</a></div></div><div class=SRResult id=SR_lowlocalmemmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_lowlocalmemmode" target=_parent class=ISymbol>lowlocalmemmode</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralM.html b/src/drivers/dave2d/docs/search/GeneralM.html
    new file mode 100644
    index 000000000..f0c5b2356
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralM.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Math_spcFunctions><div class=IEntry><a href="../files/inc/dave_math-h.html#Math_Functions" target=_parent class=ISymbol>Math Functions</a></div></div><div class=SRResult id=SR_mul3232to64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_mul3232to64" target=_parent class=ISymbol>mul3232to64</a></div></div><div class=SRResult id=SR_mul3264><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_mul3264" target=_parent class=ISymbol>mul3264</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralN.html b/src/drivers/dave2d/docs/search/GeneralN.html
    new file mode 100644
    index 000000000..9c12095a1
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralN.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_newcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_newcontext" target=_parent class=ISymbol>newcontext</a></div></div><div class=SRResult id=SR_newrenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_newrenderbuffer" target=_parent class=ISymbol>newrenderbuffer</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralO.html b/src/drivers/dave2d/docs/search/GeneralO.html
    new file mode 100644
    index 000000000..bc244ae1d
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralO.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Object_slaprimitive_spcsize_spclimitations><div class=IEntry><a href="../files/doc/limitations-txt.html#Object/primitive_size_limitations" target=_parent class=ISymbol>Object/<wbr>primitive size limitations</a></div></div><div class=SRResult id=SR_opendevice><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_opendevice" target=_parent class=ISymbol>opendevice</a></div></div><div class=SRResult id=SR_outlinecontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_outlinecontext" target=_parent class=ISymbol>outlinecontext</a></div></div><div class=SRResult id=SR_outlinewidth><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_outlinewidth" target=_parent class=ISymbol>outlinewidth</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralP.html b/src/drivers/dave2d/docs/search/GeneralP.html
    new file mode 100644
    index 000000000..e9fbecdf0
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralP.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Performance_spccounting><div class=IEntry><a href="../files/code/dave_perfcount-c.html#Performance_counting" target=_parent class=ISymbol>Performance counting</a></div></div><div class=SRResult id=SR_pow2mask><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/inc/dave_math-h.html#d2_pow2mask" target=_parent class=ISymbol>pow2mask</a></div></div><div class=SRResult id=SR_Profiling><div class=IEntry><a href="../files/code/dave_perfcount-c.html#Profiling" target=_parent class=ISymbol>Profiling</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralR.html b/src/drivers/dave2d/docs/search/GeneralR.html
    new file mode 100644
    index 000000000..b051457f5
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralR.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_relocateframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_relocateframe" target=_parent class=ISymbol>relocateframe</a></div></div><div class=SRResult id=SR_Render_spcBuffers><div class=IEntry><a href="../files/code/dave_rbuffer-c.html#Render_Buffers" target=_parent class=ISymbol>Render Buffers</a></div></div><div class=SRResult id=SR_renderbox><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderbox" target=_parent class=ISymbol>renderbox</a></div></div><div class=SRResult id=SR_Renderbuffer_spcManagement><div class=IEntry><a href="../files/code/dave_rbuffer-c.html#Renderbuffer_Management" target=_parent class=ISymbol>Renderbuffer Management</a></div></div><div class=SRResult id=SR_rendercircle><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendercircle" target=_parent class=ISymbol>rendercircle</a></div></div><div class=SRResult id=SR_rendercircle_undno_undhilimiterprecision><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_rendercircle_no_hilimiterprecision" target=_parent class=ISymbol>rendercircle_no_hilimiterprecision</a></div></div><div class=SRResult id=SR_Rendering_spcFunctions><div class=IEntry><a href="../files/code/dave_render-c.html#Rendering_Functions" target=_parent class=ISymbol>Rendering Functions</a></div></div><div class=SRResult id=SR_Rendering_spcMode><div class=IEntry><a href="../files/code/dave_driver-c.html#Rendering_Mode" target=_parent class=ISymbol>Rendering Mode</a></div></div><div class=SRResult id=SR_renderline><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderline" target=_parent class=ISymbol>renderline</a></div></div><div class=SRResult id=SR_renderline2><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderline2" target=_parent class=ISymbol>renderline2</a></div></div><div class=SRResult id=SR_renderpolygon><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderpolygon" target=_parent class=ISymbol>renderpolygon</a></div></div><div class=SRResult id=SR_renderpolyline><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderpolyline" target=_parent class=ISymbol>renderpolyline</a></div></div><div class=SRResult id=SR_renderpolyline2><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderpolyline2" target=_parent class=ISymbol>renderpolyline2</a></div></div><div class=SRResult id=SR_renderquad><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderquad" target=_parent class=ISymbol>renderquad</a></div></div><div class=SRResult id=SR_rendertri><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertri" target=_parent class=ISymbol>rendertri</a></div></div><div class=SRResult id=SR_rendertrifan><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertrifan" target=_parent class=ISymbol>rendertrifan</a></div></div><div class=SRResult id=SR_rendertrilist><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertrilist" target=_parent class=ISymbol>rendertrilist</a></div></div><div class=SRResult id=SR_rendertristrip><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_rendertristrip" target=_parent class=ISymbol>rendertristrip</a></div></div><div class=SRResult id=SR_renderwedge><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_render-c.html#d2_renderwedge" target=_parent class=ISymbol>renderwedge</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralS.html b/src/drivers/dave2d/docs/search/GeneralS.html
    new file mode 100644
    index 000000000..428603964
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralS.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Sample_spccode><div class=IEntry><a href="../files/doc/overview-txt.html#Sample_code" target=_parent class=ISymbol>Sample code</a></div></div><div class=SRResult id=SR_selectcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_selectcontext" target=_parent class=ISymbol>selectcontext</a></div></div><div class=SRResult id=SR_selectrenderbuffer><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_selectrenderbuffer" target=_parent class=ISymbol>selectrenderbuffer</a></div></div><div class=SRResult id=SR_selectrendermode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_selectrendermode" target=_parent class=ISymbol>selectrendermode</a></div></div><div class=SRResult id=SR_setalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalpha" target=_parent class=ISymbol>setalpha</a></div></div><div class=SRResult id=SR_setalphablendmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphablendmode" target=_parent class=ISymbol>setalphablendmode</a></div></div><div class=SRResult id=SR_setalphablendmodeex><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphablendmodeex" target=_parent class=ISymbol>setalphablendmodeex</a></div></div><div class=SRResult id=SR_setalphaex><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphaex" target=_parent class=ISymbol>setalphaex</a></div></div><div class=SRResult id=SR_setalphagradient><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphagradient" target=_parent class=ISymbol>setalphagradient</a></div></div><div class=SRResult id=SR_setalphamode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setalphamode" target=_parent class=ISymbol>setalphamode</a></div></div><div class=SRResult id=SR_setantialiasing><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setantialiasing" target=_parent class=ISymbol>setantialiasing</a></div></div><div class=SRResult id=SR_setblendmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setblendmode" target=_parent class=ISymbol>setblendmode</a></div></div><div class=SRResult id=SR_setblitsrc><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_blit-c.html#d2_setblitsrc" target=_parent class=ISymbol>setblitsrc</a></div></div><div class=SRResult id=SR_setblur><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setblur" target=_parent class=ISymbol>setblur</a></div></div><div class=SRResult id=SR_setcircleextend><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setcircleextend" target=_parent class=ISymbol>setcircleextend</a></div></div><div class=SRResult id=SR_setclipgradient><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setclipgradient" target=_parent class=ISymbol>setclipgradient</a></div></div><div class=SRResult id=SR_setcolor><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setcolor" target=_parent class=ISymbol>setcolor</a></div></div><div class=SRResult id=SR_setcolorkey><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_setcolorkey" target=_parent class=ISymbol>setcolorkey</a></div></div><div class=SRResult id=SR_setdlistblocksize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_setdlistblocksize" target=_parent class=ISymbol>setdlistblocksize</a></div></div><div class=SRResult id=SR_setfillmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setfillmode" target=_parent class=ISymbol>setfillmode</a></div></div><div class=SRResult id=SR_setlinecap><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setlinecap" target=_parent class=ISymbol>setlinecap</a></div></div><div class=SRResult id=SR_setlinejoin><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setlinejoin" target=_parent class=ISymbol>setlinejoin</a></div></div><div class=SRResult id=SR_setlinepattern><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setlinepattern" target=_parent class=ISymbol>setlinepattern</a></div></div><div class=SRResult id=SR_setmiterlimit><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setmiterlimit" target=_parent class=ISymbol>setmiterlimit</a></div></div><div class=SRResult id=SR_setpattern><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpattern" target=_parent class=ISymbol>setpattern</a></div></div><div class=SRResult id=SR_setpatternalpha><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternalpha" target=_parent class=ISymbol>setpatternalpha</a></div></div><div class=SRResult id=SR_setpatternmode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternmode" target=_parent class=ISymbol>setpatternmode</a></div></div><div class=SRResult id=SR_setpatternparam><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternparam" target=_parent class=ISymbol>setpatternparam</a></div></div><div class=SRResult id=SR_setpatternsize><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_setpatternsize" target=_parent class=ISymbol>setpatternsize</a></div></div><div class=SRResult id=SR_setperfcountevent><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_perfcount-c.html#d2_setperfcountevent" target=_parent class=ISymbol>setperfcountevent</a></div></div><div class=SRResult id=SR_setperfcountvalue><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_perfcount-c.html#d2_setperfcountvalue" target=_parent class=ISymbol>setperfcountvalue</a></div></div><div class=SRResult id=SR_settexclut><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut" target=_parent class=ISymbol>settexclut</a></div></div><div class=SRResult id=SR_settexclut_undformat><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut_format" target=_parent class=ISymbol>settexclut_format</a></div></div><div class=SRResult id=SR_settexclut_undoffset><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut_offset" target=_parent class=ISymbol>settexclut_offset</a></div></div><div class=SRResult id=SR_settexclut_undpart><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexclut_part" target=_parent class=ISymbol>settexclut_part</a></div></div><div class=SRResult id=SR_settexelcenter><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexelcenter" target=_parent class=ISymbol>settexelcenter</a></div></div><div class=SRResult id=SR_settexopparam><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexopparam" target=_parent class=ISymbol>settexopparam</a></div></div><div class=SRResult id=SR_settexture><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexture" target=_parent class=ISymbol>settexture</a></div></div><div class=SRResult id=SR_settexturemapping><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexturemapping" target=_parent class=ISymbol>settexturemapping</a></div></div><div class=SRResult id=SR_settexturemode><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settexturemode" target=_parent class=ISymbol>settexturemode</a></div></div><div class=SRResult id=SR_settextureoperation><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_settextureoperation" target=_parent class=ISymbol>settextureoperation</a></div></div><div class=SRResult id=SR_shadowoffset><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_driver-c.html#d2_shadowoffset" target=_parent class=ISymbol>shadowoffset</a></div></div><div class=SRResult id=SR_shiftleft64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_shiftleft64" target=_parent class=ISymbol>shiftleft64</a></div></div><div class=SRResult id=SR_shiftright64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_shiftright64" target=_parent class=ISymbol>shiftright64</a></div></div><div class=SRResult id=SR_solidcontext><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_context-c.html#d2_solidcontext" target=_parent class=ISymbol>solidcontext</a></div></div><div class=SRResult id=SR_sqrt><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/inc/dave_math-h.html#d2_sqrt" target=_parent class=ISymbol>sqrt</a></div></div><div class=SRResult id=SR_startframe><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_rbuffer-c.html#d2_startframe" target=_parent class=ISymbol>startframe</a></div></div><div class=SRResult id=SR_Static_spcfunctions><div class=IEntry><a href="../files/code/dave_driver-c.html#Static_functions" target=_parent class=ISymbol>Static functions</a></div></div><div class=SRResult id=SR_sub64><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_64bitoperation-c.html#d2_sub64" target=_parent class=ISymbol>sub64</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralT.html b/src/drivers/dave2d/docs/search/GeneralT.html
    new file mode 100644
    index 000000000..d060ff157
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralT.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Texture_spcAttribute_spcQueries><div class=IEntry><a href="../files/code/dave_texture-c.html#Texture_Attribute_Queries" target=_parent class=ISymbol>Texture Attribute Queries</a></div></div><div class=SRResult id=SR_Texture_spcAttribute_spcWrites><div class=IEntry><a href="../files/code/dave_texture-c.html#Texture_Attribute_Writes" target=_parent class=ISymbol>Texture Attribute Writes</a></div></div><div class=SRResult id=SR_Texture_spcFunctions><div class=IEntry><a href="../files/code/dave_texture-c.html#Texture_Functions" target=_parent class=ISymbol>Texture Functions</a></div></div><div class=SRResult id=SR_Texture_spcsize_spclimitations><div class=IEntry><a href="../files/doc/limitations-txt.html#Texture_size_limitations" target=_parent class=ISymbol>Texture size limitations</a></div></div><div class=SRResult id=SR_Types><div class=IEntry><a href="../files/inc/dave_driver-h.html#Types" target=_parent class=ISymbol>Types</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralU.html b/src/drivers/dave2d/docs/search/GeneralU.html
    new file mode 100644
    index 000000000..6893b545c
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralU.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Utility_spcFunctions><div class=IEntry><a href="javascript:searchResults.Toggle('SR_Utility_spcFunctions')" class=ISymbol>Utility Functions</a><div class=ISubIndex><a href="../files/code/dave_driver-c.html#Utility_Functions" target=_parent class=IFile>code/<wbr>dave_driver.c</a><a href="../files/code/dave_rbuffer-c.html#Utility_Functions" target=_parent class=IFile>code/<wbr>dave_rbuffer.c</a><a href="../files/code/dave_utility-c.html#Utility_Functions" target=_parent class=IFile>code/<wbr>dave_utility.c</a></div></div></div><div class=SRResult id=SR_utility_undfbblitcopy><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_utility_fbblitcopy" target=_parent class=ISymbol>utility_fbblitcopy</a></div></div><div class=SRResult id=SR_utility_undmaptriangle><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_utility_maptriangle" target=_parent class=ISymbol>utility_maptriangle</a></div></div><div class=SRResult id=SR_utility_undperspectivewarp><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_utility-c.html#d2_utility_perspectivewarp" target=_parent class=ISymbol>utility_perspectivewarp</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralV.html b/src/drivers/dave2d/docs/search/GeneralV.html
    new file mode 100644
    index 000000000..55ecbf0bc
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralV.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_Viewport_spcFunctions><div class=IEntry><a href="../files/code/dave_viewport-c.html#Viewport_Functions" target=_parent class=ISymbol>Viewport Functions</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/GeneralW.html b/src/drivers/dave2d/docs/search/GeneralW.html
    new file mode 100644
    index 000000000..07e3ed6ec
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/GeneralW.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_writetexclut_unddirect><div class=IEntry><span class=ISymbolPrefix>d2_</span><a href="../files/code/dave_texture-c.html#d2_writetexclut_direct" target=_parent class=ISymbol>writetexclut_direct</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/NoResults.html b/src/drivers/dave2d/docs/search/NoResults.html
    new file mode 100644
    index 000000000..8c7249660
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/NoResults.html
    @@ -0,0 +1,15 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=NoMatches>No Matches</div></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/search/TypesD.html b/src/drivers/dave2d/docs/search/TypesD.html
    new file mode 100644
    index 000000000..854fe33d3
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/search/TypesD.html
    @@ -0,0 +1,20 @@
    +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
    +
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
    +
    +<!--  Generated by Natural Docs, version 1.52 -->
    +<!--  http://www.naturaldocs.org  -->
    +
    +<!-- saved from url=(0026)http://www.naturaldocs.org -->
    +
    +
    +
    +
    +<div id=Index><div class=SRStatus id=Loading>Loading...</div><table border=0 cellspacing=0 cellpadding=0><div class=SRResult id=SR_d2_undalpha><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_alpha" target=_parent class=ISymbol>d2_alpha</a></div></div><div class=SRResult id=SR_d2_undblitpos><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_blitpos" target=_parent class=ISymbol>d2_blitpos</a></div></div><div class=SRResult id=SR_d2_undborder><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_border" target=_parent class=ISymbol>d2_border</a></div></div><div class=SRResult id=SR_d2_undcolor><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_color" target=_parent class=ISymbol>d2_color</a></div></div><div class=SRResult id=SR_d2_undcontext><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_context" target=_parent class=ISymbol>d2_context</a></div></div><div class=SRResult id=SR_d2_unddevice><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_device" target=_parent class=ISymbol>d2_device</a></div></div><div class=SRResult id=SR_d2_undpattern><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_pattern" target=_parent class=ISymbol>d2_pattern</a></div></div><div class=SRResult id=SR_d2_undpoint><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_point" target=_parent class=ISymbol>d2_point</a></div></div><div class=SRResult id=SR_d2_undrenderbuffer><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_renderbuffer" target=_parent class=ISymbol>d2_renderbuffer</a></div></div><div class=SRResult id=SR_d2_undwidth><div class=IEntry><a href="../files/inc/dave_driver-h.html#d2_width" target=_parent class=ISymbol>d2_width</a></div></div></table><div class=SRStatus id=Searching>Searching...</div><div class=SRStatus id=NoMatches>No Matches</div><script type="text/javascript"><!--
    +document.getElementById("Loading").style.display="none";
    +document.getElementById("NoMatches").style.display="none";
    +var searchResults = new SearchResults("searchResults", "HTML");
    +searchResults.Search();
    +--></script></div><script language=JavaScript><!--
    +if (browserType) {if (browserVer) {document.write("</div>"); }document.write("</div>");}// --></script></body></html>
    \ No newline at end of file
    diff --git a/src/drivers/dave2d/docs/styles/main.css b/src/drivers/dave2d/docs/styles/main.css
    new file mode 100644
    index 000000000..30c90cfc3
    --- /dev/null
    +++ b/src/drivers/dave2d/docs/styles/main.css
    @@ -0,0 +1,829 @@
    +/*
    +   IMPORTANT: If you're editing this file in the output directory of one of
    +   your projects, your changes will be overwritten the next time you run
    +   Natural Docs.  Instead, copy this file to your project directory, make your
    +   changes, and you can use it with -s.  Even better would be to make a CSS
    +   file in your project directory with only your changes, which you can then
    +   use with -s [original style] [your changes].
    +
    +   On the other hand, if you're editing this file in the Natural Docs styles
    +   directory, the changes will automatically be applied to all your projects
    +   that use this style the next time Natural Docs is run on them.
    +
    +   This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure.
    +   Natural Docs is licensed under version 3 of the GNU Affero General Public
    +   License (AGPL).  Refer to License.txt for the complete details.
    +
    +   This file may be distributed with documentation files generated by Natural Docs.
    +   Such documentation is not covered by Natural Docs' copyright and licensing,
    +   and may have its own copyright and distribution terms as decided by its author.
    +*/
    +
    +body {
    +    font: 10pt Verdana, Arial, sans-serif;
    +    color: #000000;
    +    margin: 0; padding: 0;
    +    }
    +
    +.ContentPage,
    +.IndexPage,
    +.FramedMenuPage {
    +    background-color: #E8E8E8;
    +    }
    +.FramedContentPage,
    +.FramedIndexPage,
    +.FramedSearchResultsPage,
    +.PopupSearchResultsPage {
    +    background-color: #FFFFFF;
    +    }
    +
    +
    +a:link,
    +a:visited { color: #900000; text-decoration: none }
    +a:hover { color: #900000; text-decoration: underline }
    +a:active { color: #FF0000; text-decoration: underline }
    +
    +td {
    +    vertical-align: top }
    +
    +img { border: 0;  }
    +
    +
    +/*
    +    Comment out this line to use web-style paragraphs (blank line between
    +    paragraphs, no indent) instead of print-style paragraphs (no blank line,
    +    indented.)
    +*/
    +/*
    +p {
    +    text-indent: 5ex; margin: 0 }
    +*/
    +
    +/*  Opera doesn't break with just wbr, but will if you add this.  */
    +.Opera wbr:after {
    +	content: "\00200B";
    +	}
    +
    +
    +/*  Blockquotes are used as containers for things that may need to scroll.  */
    +blockquote {
    +    padding: 0;
    +    margin: 0;
    +    overflow: auto;
    +    }
    +
    +
    +.Firefox1 blockquote {
    +    padding-bottom: .5em;
    +    }
    +
    +/*  Turn off scrolling when printing.  */
    +@media print {
    +    blockquote {
    +        overflow: visible;
    +        }
    +    .IE blockquote {
    +        width: auto;
    +        }
    +    }
    +
    +
    +
    +#Menu {
    +    font-size: 9pt;
    +    padding: 10px 0 0 0;
    +    }
    +.ContentPage #Menu,
    +.IndexPage #Menu {
    +    position: absolute;
    +    top: 0;
    +    left: 0;
    +    width: 31ex;
    +    overflow: hidden;
    +    }
    +.ContentPage .Firefox #Menu,
    +.IndexPage .Firefox #Menu {
    +    width: 27ex;
    +    }
    +
    +
    +    .MTitle {
    +        font-size: 16pt; font-weight: bold; font-variant: small-caps;
    +        text-align: center;
    +        padding: 5px 10px 15px 10px;
    +        border-bottom: 1px dotted #000000;
    +        margin-bottom: 15px }
    +
    +    .MSubTitle {
    +        font-size: 9pt; font-weight: normal; font-variant: normal;
    +        margin-top: 1ex; margin-bottom: 5px }
    +
    +
    +    .MEntry a:link,
    +    .MEntry a:hover,
    +    .MEntry a:visited { color: #606060; margin-right: 0 }
    +    .MEntry a:active { color: #A00000; margin-right: 0 }
    +
    +
    +    .MGroup {
    +        font-variant: small-caps; font-weight: bold;
    +        margin: 1em 0 1em 10px;
    +        }
    +
    +    .MGroupContent {
    +        font-variant: normal; font-weight: normal }
    +
    +    .MGroup a:link,
    +    .MGroup a:hover,
    +    .MGroup a:visited { color: #545454; margin-right: 10px }
    +    .MGroup a:active { color: #A00000; margin-right: 10px }
    +
    +
    +    .MFile,
    +    .MText,
    +    .MLink,
    +    .MIndex {
    +        padding: 1px 17px 2px 10px;
    +        margin: .25em 0 .25em 0;
    +        }
    +
    +    .MText {
    +        font-size: 8pt; font-style: italic }
    +
    +    .MLink {
    +        font-style: italic }
    +
    +    #MSelected {
    +        color: #000000; background-color: #FFFFFF;
    +        /*  Replace padding with border.  */
    +        padding: 0 10px 0 10px;
    +        border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000;
    +        margin-right: 5px;
    +        }
    +
    +    /*  Close off the left side when its in a group.  */
    +    .MGroup #MSelected {
    +        padding-left: 9px; border-left-width: 1px }
    +
    +    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
    +    .Firefox #MSelected {
    +        -moz-border-radius-topright: 10px;
    +        -moz-border-radius-bottomright: 10px }
    +    .Firefox .MGroup #MSelected {
    +        -moz-border-radius-topleft: 10px;
    +        -moz-border-radius-bottomleft: 10px }
    +
    +
    +    #MSearchPanel {
    +        padding: 0px 6px;
    +        margin: .25em 0;
    +        }
    +
    +
    +    #MSearchField {
    +        font: italic 9pt Verdana, sans-serif;
    +        color: #606060;
    +        background-color: #E8E8E8;
    +        border: none;
    +        padding: 2px 4px;
    +        width: 100%;
    +        }
    +    /* Only Opera gets it right. */
    +    .Firefox #MSearchField,
    +    .IE #MSearchField,
    +    .Safari #MSearchField {
    +        width: 94%;
    +        }
    +    .Opera9 #MSearchField,
    +    .Konqueror #MSearchField {
    +        width: 97%;
    +        }
    +    .FramedMenuPage .Firefox #MSearchField,
    +    .FramedMenuPage .Safari #MSearchField,
    +    .FramedMenuPage .Konqueror #MSearchField {
    +        width: 98%;
    +        }
    +
    +    /* Firefox doesn't do this right in frames without #MSearchPanel added on.
    +        It's presence doesn't hurt anything other browsers. */
    +    #MSearchPanel.MSearchPanelInactive:hover #MSearchField {
    +        background-color: #FFFFFF;
    +        border: 1px solid #C0C0C0;
    +        padding: 1px 3px;
    +        }
    +    .MSearchPanelActive #MSearchField {
    +        background-color: #FFFFFF;
    +        border: 1px solid #C0C0C0;
    +        font-style: normal;
    +        padding: 1px 3px;
    +        }
    +
    +    #MSearchType {
    +        visibility: hidden;
    +        font: 8pt Verdana, sans-serif;
    +        width: 98%;
    +        padding: 0;
    +        border: 1px solid #C0C0C0;
    +        }
    +    .MSearchPanelActive #MSearchType,
    +    /*  As mentioned above, Firefox doesn't do this right in frames without #MSearchPanel added on. */
    +    #MSearchPanel.MSearchPanelInactive:hover #MSearchType,
    +    #MSearchType:focus {
    +        visibility: visible;
    +        color: #606060;
    +        }
    +    #MSearchType option#MSearchEverything {
    +        font-weight: bold;
    +        }
    +
    +    .Opera8 .MSearchPanelInactive:hover,
    +    .Opera8 .MSearchPanelActive {
    +        margin-left: -1px;
    +        }
    +
    +
    +    iframe#MSearchResults {
    +        width: 60ex;
    +        height: 15em;
    +        }
    +    #MSearchResultsWindow {
    +        display: none;
    +        position: absolute;
    +        left: 0; top: 0;
    +        border: 1px solid #000000;
    +        background-color: #E8E8E8;
    +        }
    +    #MSearchResultsWindowClose {
    +        font-weight: bold;
    +        font-size: 8pt;
    +        display: block;
    +        padding: 2px 5px;
    +        }
    +    #MSearchResultsWindowClose:link,
    +    #MSearchResultsWindowClose:visited {
    +        color: #000000;
    +        text-decoration: none;
    +        }
    +    #MSearchResultsWindowClose:active,
    +    #MSearchResultsWindowClose:hover {
    +        color: #800000;
    +        text-decoration: none;
    +        background-color: #F4F4F4;
    +        }
    +
    +
    +
    +
    +#Content {
    +    padding-bottom: 15px;
    +    }
    +
    +.ContentPage #Content {
    +    border-width: 0 0 1px 1px;
    +    border-style: solid;
    +    border-color: #000000;
    +    background-color: #FFFFFF;
    +    font-size: 9pt;  /* To make 31ex match the menu's 31ex. */
    +    margin-left: 31ex;
    +    }
    +.ContentPage .Firefox #Content {
    +    margin-left: 27ex;
    +    }
    +
    +
    +
    +    .CTopic {
    +        font-size: 10pt;
    +        margin-bottom: 3em;
    +        }
    +
    +
    +    .CTitle {
    +        font-size: 12pt; font-weight: bold;
    +        border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0;
    +        margin: 0 15px .5em 15px }
    +
    +    .CGroup .CTitle {
    +        font-size: 16pt; font-variant: small-caps;
    +        padding-left: 15px; padding-right: 15px;
    +        border-width: 0 0 2px 0; border-color: #000000;
    +        margin-left: 0; margin-right: 0 }
    +
    +    .CClass .CTitle,
    +    .CInterface .CTitle,
    +    .CDatabase .CTitle,
    +    .CDatabaseTable .CTitle,
    +    .CSection .CTitle {
    +        font-size: 18pt;
    +        color: #FFFFFF; background-color: #A0A0A0;
    +        padding: 10px 15px 10px 15px;
    +        border-width: 2px 0; border-color: #000000;
    +        margin-left: 0; margin-right: 0 }
    +
    +    #MainTopic .CTitle {
    +        font-size: 20pt;
    +        color: #FFFFFF; background-color: #7070C0;
    +        padding: 10px 15px 10px 15px;
    +        border-width: 0 0 3px 0; border-color: #000000;
    +        margin-left: 0; margin-right: 0 }
    +
    +    .CBody {
    +        margin-left: 15px; margin-right: 15px }
    +
    +
    +    .CToolTip {
    +        position: absolute; visibility: hidden;
    +        left: 0; top: 0;
    +        background-color: #FFFFE0;
    +        padding: 5px;
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000;
    +        font-size: 8pt;
    +        }
    +
    +    .Opera .CToolTip {
    +        max-width: 98%;
    +        }
    +
    +    /*  Scrollbars would be useless.  */
    +    .CToolTip blockquote {
    +        overflow: hidden;
    +        }
    +    .IE6 .CToolTip blockquote {
    +        overflow: visible;
    +        }
    +
    +    .CHeading {
    +        font-weight: bold; font-size: 10pt;
    +        margin: 1.5em 0 .5em 0;
    +        }
    +
    +    .CBody pre {
    +        font: 10pt "Courier New", Courier, monospace;
    +	    background-color: #FCFCFC;
    +	    margin: 1em 35px;
    +	    padding: 10px 15px 10px 10px;
    +	    border-color: #E0E0E0 #E0E0E0 #E0E0E0 #E4E4E4;
    +	    border-width: 1px 1px 1px 6px;
    +	    border-style: dashed dashed dashed solid;
    +        }
    +
    +    .CBody ul {
    +        /*  I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever.
    +             Reapply it here as padding.  */
    +        padding-left: 15px; padding-right: 15px;
    +        margin: .5em 5ex .5em 5ex;
    +        }
    +
    +    .CDescriptionList {
    +        margin: .5em 5ex 0 5ex }
    +
    +        .CDLEntry {
    +            font: 10pt "Courier New", Courier, monospace; color: #808080;
    +            padding-bottom: .25em;
    +            white-space: nowrap }
    +
    +        .CDLDescription {
    +            font-size: 10pt;  /*  For browsers that don't inherit correctly, like Opera 5.  */
    +            padding-bottom: .5em; padding-left: 5ex }
    +
    +
    +    .CTopic img {
    +        text-align: center;
    +        display: block;
    +        margin: 1em auto;
    +        }
    +    .CImageCaption {
    +        font-variant: small-caps;
    +        font-size: 8pt;
    +        color: #808080;
    +        text-align: center;
    +        position: relative;
    +        top: 1em;
    +        }
    +
    +    .CImageLink {
    +        color: #808080;
    +        font-style: italic;
    +        }
    +    a.CImageLink:link,
    +    a.CImageLink:visited,
    +    a.CImageLink:hover { color: #808080 }
    +
    +
    +
    +
    +
    +.Prototype {
    +    font: 10pt "Courier New", Courier, monospace;
    +    padding: 5px 3ex;
    +    border-width: 1px; border-style: solid;
    +    margin: 0 5ex 1.5em 5ex;
    +    }
    +
    +    .Prototype td {
    +        font-size: 10pt;
    +        }
    +
    +    .PDefaultValue,
    +    .PDefaultValuePrefix,
    +    .PTypePrefix {
    +        color: #8F8F8F;
    +        }
    +    .PTypePrefix {
    +        text-align: right;
    +        }
    +    .PAfterParameters {
    +        vertical-align: bottom;
    +        }
    +
    +    .IE .Prototype table {
    +        padding: 0;
    +        }
    +
    +    .CFunction .Prototype {
    +        background-color: #F4F4F4; border-color: #D0D0D0 }
    +    .CProperty .Prototype {
    +        background-color: #F4F4FF; border-color: #C0C0E8 }
    +    .CVariable .Prototype {
    +        background-color: #FFFFF0; border-color: #E0E0A0 }
    +
    +    .CClass .Prototype {
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
    +        background-color: #F4F4F4;
    +        }
    +    .CInterface .Prototype {
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0D0;
    +        background-color: #F4F4FF;
    +        }
    +
    +    .CDatabaseIndex .Prototype,
    +    .CConstant .Prototype {
    +        background-color: #D0D0D0; border-color: #000000 }
    +    .CType .Prototype,
    +    .CEnumeration .Prototype {
    +        background-color: #FAF0F0; border-color: #E0B0B0;
    +        }
    +    .CDatabaseTrigger .Prototype,
    +    .CEvent .Prototype,
    +    .CDelegate .Prototype {
    +        background-color: #F0FCF0; border-color: #B8E4B8 }
    +
    +    .CToolTip .Prototype {
    +        margin: 0 0 .5em 0;
    +        white-space: nowrap;
    +        }
    +
    +
    +
    +
    +
    +.Summary {
    +    margin: 1.5em 5ex 0 5ex }
    +
    +    .STitle {
    +        font-size: 12pt; font-weight: bold;
    +        margin-bottom: .5em }
    +
    +
    +    .SBorder {
    +        background-color: #FFFFF0;
    +        padding: 15px;
    +        border: 1px solid #C0C060 }
    +
    +    /* In a frame IE 6 will make them too long unless you set the width to 100%.  Without frames it will be correct without a width
    +        or slightly too long (but not enough to scroll) with a width.  This arbitrary weirdness simply astounds me.  IE 7 has the same
    +        problem with frames, haven't tested it without.  */
    +    .FramedContentPage .IE .SBorder {
    +        width: 100% }
    +
    +    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
    +    .Firefox .SBorder {
    +        -moz-border-radius: 20px }
    +
    +
    +    .STable {
    +        font-size: 9pt; width: 100% }
    +
    +    .SEntry {
    +        width: 30% }
    +    .SDescription {
    +        width: 70% }
    +
    +
    +    .SMarked {
    +        background-color: #F8F8D8 }
    +
    +    .SDescription { padding-left: 2ex }
    +    .SIndent1 .SEntry { padding-left: 1.5ex }   .SIndent1 .SDescription { padding-left: 3.5ex }
    +    .SIndent2 .SEntry { padding-left: 3.0ex }   .SIndent2 .SDescription { padding-left: 5.0ex }
    +    .SIndent3 .SEntry { padding-left: 4.5ex }   .SIndent3 .SDescription { padding-left: 6.5ex }
    +    .SIndent4 .SEntry { padding-left: 6.0ex }   .SIndent4 .SDescription { padding-left: 8.0ex }
    +    .SIndent5 .SEntry { padding-left: 7.5ex }   .SIndent5 .SDescription { padding-left: 9.5ex }
    +
    +    .SDescription a { color: #800000}
    +    .SDescription a:active { color: #A00000 }
    +
    +    .SGroup td {
    +        padding-top: .5em; padding-bottom: .25em }
    +
    +    .SGroup .SEntry {
    +        font-weight: bold; font-variant: small-caps }
    +
    +    .SGroup .SEntry a { color: #800000 }
    +    .SGroup .SEntry a:active { color: #F00000 }
    +
    +
    +    .SMain td,
    +    .SClass td,
    +    .SDatabase td,
    +    .SDatabaseTable td,
    +    .SSection td {
    +        font-size: 10pt;
    +        padding-bottom: .25em }
    +
    +    .SClass td,
    +    .SDatabase td,
    +    .SDatabaseTable td,
    +    .SSection td {
    +        padding-top: 1em }
    +
    +    .SMain .SEntry,
    +    .SClass .SEntry,
    +    .SDatabase .SEntry,
    +    .SDatabaseTable .SEntry,
    +    .SSection .SEntry {
    +        font-weight: bold;
    +        }
    +
    +    .SMain .SEntry a,
    +    .SClass .SEntry a,
    +    .SDatabase .SEntry a,
    +    .SDatabaseTable .SEntry a,
    +    .SSection .SEntry a { color: #000000 }
    +
    +    .SMain .SEntry a:active,
    +    .SClass .SEntry a:active,
    +    .SDatabase .SEntry a:active,
    +    .SDatabaseTable .SEntry a:active,
    +    .SSection .SEntry a:active { color: #A00000 }
    +
    +
    +
    +
    +
    +.ClassHierarchy {
    +    margin: 0 15px 1em 15px }
    +
    +    .CHEntry {
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
    +        margin-bottom: 3px;
    +        padding: 2px 2ex;
    +        font-size: 10pt;
    +        background-color: #F4F4F4; color: #606060;
    +        }
    +
    +    .Firefox .CHEntry {
    +        -moz-border-radius: 4px;
    +        }
    +
    +    .CHCurrent .CHEntry {
    +        font-weight: bold;
    +        border-color: #000000;
    +        color: #000000;
    +        }
    +
    +    .CHChildNote .CHEntry {
    +        font-style: italic;
    +        font-size: 8pt;
    +        }
    +
    +    .CHIndent {
    +        margin-left: 3ex;
    +        }
    +
    +    .CHEntry a:link,
    +    .CHEntry a:visited,
    +    .CHEntry a:hover {
    +        color: #606060;
    +        }
    +    .CHEntry a:active {
    +        color: #800000;
    +        }
    +
    +
    +
    +
    +
    +#Index {
    +    background-color: #FFFFFF;
    +    }
    +
    +/*  As opposed to .PopupSearchResultsPage #Index  */
    +.IndexPage #Index,
    +.FramedIndexPage #Index,
    +.FramedSearchResultsPage #Index {
    +    padding: 15px;
    +    }
    +
    +.IndexPage #Index {
    +    border-width: 0 0 1px 1px;
    +    border-style: solid;
    +    border-color: #000000;
    +    font-size: 9pt;  /* To make 27ex match the menu's 27ex. */
    +    margin-left: 27ex;
    +    }
    +
    +
    +    .IPageTitle {
    +        font-size: 20pt; font-weight: bold;
    +        color: #FFFFFF; background-color: #7070C0;
    +        padding: 10px 15px 10px 15px;
    +        border-width: 0 0 3px 0; border-color: #000000; border-style: solid;
    +        margin: -15px -15px 0 -15px }
    +
    +    .FramedSearchResultsPage .IPageTitle {
    +        margin-bottom: 15px;
    +        }
    +
    +    .INavigationBar {
    +        font-size: 10pt;
    +        text-align: center;
    +        background-color: #FFFFF0;
    +        padding: 5px;
    +        border-bottom: solid 1px black;
    +        margin: 0 -15px 15px -15px;
    +        }
    +
    +    .INavigationBar a {
    +        font-weight: bold }
    +
    +    .IHeading {
    +        font-size: 16pt; font-weight: bold;
    +        padding: 2.5em 0 .5em 0;
    +        text-align: center;
    +        width: 3.5ex;
    +        }
    +    #IFirstHeading {
    +        padding-top: 0;
    +        }
    +
    +    .IEntry {
    +        font-size: 10pt;
    +        padding-left: 1ex;
    +        }
    +    .PopupSearchResultsPage .IEntry {
    +        font-size: 8pt;
    +        padding: 1px 5px;
    +        }
    +    .PopupSearchResultsPage .Opera9 .IEntry,
    +    .FramedSearchResultsPage .Opera9 .IEntry {
    +        text-align: left;
    +        }
    +    .FramedSearchResultsPage .IEntry {
    +        padding: 0;
    +        }
    +
    +    .ISubIndex {
    +        padding-left: 3ex; padding-bottom: .5em }
    +    .PopupSearchResultsPage .ISubIndex {
    +        display: none;
    +        }
    +
    +    /*  While it may cause some entries to look like links when they aren't, I found it's much easier to read the
    +         index if everything's the same color.  */
    +    .ISymbol {
    +        font-weight: bold; color: #900000  }
    +
    +    .IndexPage .ISymbolPrefix,
    +    .FramedIndexPage .ISymbolPrefix {
    +        font-size: 10pt;
    +        text-align: right;
    +        color: #C47C7C;
    +        background-color: #F8F8F8;
    +        border-right: 3px solid #E0E0E0;
    +        border-left: 1px solid #E0E0E0;
    +        padding: 0 1px 0 2px;
    +        }
    +    .PopupSearchResultsPage .ISymbolPrefix,
    +    .FramedSearchResultsPage .ISymbolPrefix {
    +        color: #900000;
    +        }
    +    .PopupSearchResultsPage .ISymbolPrefix {
    +        font-size: 8pt;
    +        }
    +
    +    .IndexPage #IFirstSymbolPrefix,
    +    .FramedIndexPage #IFirstSymbolPrefix {
    +        border-top: 1px solid #E0E0E0;
    +        }
    +    .IndexPage #ILastSymbolPrefix,
    +    .FramedIndexPage #ILastSymbolPrefix {
    +        border-bottom: 1px solid #E0E0E0;
    +        }
    +    .IndexPage #IOnlySymbolPrefix,
    +    .FramedIndexPage #IOnlySymbolPrefix {
    +        border-top: 1px solid #E0E0E0;
    +        border-bottom: 1px solid #E0E0E0;
    +        }
    +
    +    a.IParent,
    +    a.IFile {
    +        display: block;
    +        }
    +
    +    .PopupSearchResultsPage .SRStatus {
    +        padding: 2px 5px;
    +        font-size: 8pt;
    +        font-style: italic;
    +        }
    +    .FramedSearchResultsPage .SRStatus {
    +        font-size: 10pt;
    +        font-style: italic;
    +        }
    +
    +    .SRResult {
    +        display: none;
    +        }
    +
    +
    +
    +#Footer {
    +    font-size: 8pt;
    +    color: #989898;
    +    text-align: right;
    +    }
    +
    +#Footer p {
    +    text-indent: 0;
    +    margin-bottom: .5em;
    +    }
    +
    +.ContentPage #Footer,
    +.IndexPage #Footer {
    +    text-align: right;
    +    margin: 2px;
    +    }
    +
    +.FramedMenuPage #Footer {
    +    text-align: center;
    +    margin: 5em 10px 10px 10px;
    +    padding-top: 1em;
    +    border-top: 1px solid #C8C8C8;
    +    }
    +
    +    #Footer a:link,
    +    #Footer a:hover,
    +    #Footer a:visited { color: #989898 }
    +    #Footer a:active { color: #A00000 }
    +
    +
    +
    +.prettyprint .kwd { color: #800000; }  /* keywords */
    +
    +    .prettyprint.PDefaultValue .kwd,
    +    .prettyprint.PDefaultValuePrefix .kwd,
    +    .prettyprint.PTypePrefix .kwd {
    +        color: #C88F8F;
    +        }
    +
    +.prettyprint .com { color: #008000; }  /* comments */
    +
    +    .prettyprint.PDefaultValue .com,
    +    .prettyprint.PDefaultValuePrefix .com,
    +    .prettyprint.PTypePrefix .com {
    +        color: #8FC88F;
    +        }
    +
    +.prettyprint .str { color: #0000B0; }  /* strings */
    +.prettyprint .lit { color: #0000B0; }  /* literals */
    +
    +    .prettyprint.PDefaultValue .str,
    +    .prettyprint.PDefaultValuePrefix .str,
    +    .prettyprint.PTypePrefix .str,
    +    .prettyprint.PDefaultValue .lit,
    +    .prettyprint.PDefaultValuePrefix .lit,
    +    .prettyprint.PTypePrefix .lit {
    +        color: #8F8FC0;
    +        }
    +
    +.prettyprint .typ { color: #000000; }  /* types */
    +.prettyprint .pun { color: #000000; }  /* punctuation */
    +.prettyprint .pln { color: #000000; }  /* punctuation */
    +
    +    .prettyprint.PDefaultValue .typ,
    +    .prettyprint.PDefaultValuePrefix .typ,
    +    .prettyprint.PTypePrefix .typ,
    +    .prettyprint.PDefaultValue .pun,
    +    .prettyprint.PDefaultValuePrefix .pun,
    +    .prettyprint.PTypePrefix .pun,
    +    .prettyprint.PDefaultValue .pln,
    +    .prettyprint.PDefaultValuePrefix .pln,
    +    .prettyprint.PTypePrefix .pln {
    +        color: #8F8F8F;
    +        }
    +
    +.prettyprint .tag { color: #008; }
    +.prettyprint .atn { color: #606; }
    +.prettyprint .atv { color: #080; }
    +.prettyprint .dec { color: #606; }
    +
    diff --git a/src/drivers/dave2d/include/dave_base.h b/src/drivers/dave2d/include/dave_base.h
    new file mode 100644
    index 000000000..57ad40225
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_base.h
    @@ -0,0 +1,1362 @@
    +//--------------------------------------------------------------------------
    +// Project: D/AVE
    +// File:    dave_base.h (%version: 33 %)
    +//          created Fri Aug 19 11:00:59 2005 by hh04027
    +//
    +// Description:
    +//  %date_modified: Thu Oct 18 12:36:18 2007 %  (%derived_by:  hh74040 %)
    +//
    +// Changes:
    +//  2005-12-22 CSe  - added enums for timeouts and copyflags
    +//                  - changed declaration of d1_waitforirq to d1_queryirq
    +//  2006-01-04 CSe  - added new memarchitecture flags
    +//                  - added 2 memory management functions
    +//                  - changed display controller interface
    +//                  - added timer interface
    +//  2006-01-13 NSc  - moved videomode descriptor to videomodes.h
    +//  2006-02-16 CSe  - added d1_deviceclkfreq function
    +//  2006-02-28 CSe  - added d1_cacheblockflush function
    +//  2006-03-02 CSe  - extensions for video-input (vip)
    +//  2006-03-08 CSe  - added d1_displaytriggerupdate function
    +//  2006-03-15 CSe  - added d1_callirqhandler function
    +//  2006-03-22 CSe  - added d1_displayswitchlayersource function
    +//  2006-04-12 CSe  - changed d1_irqtypes to single bit values
    +//  2006-06-01 CSe  - added d1_getthreadid function
    +//  2006-06-15 CSe  - extension for system ID
    +//  2006-07-06 MGe  - added DAVE_TRACE deviceid ( dave_tace level1 driver )
    +//  2007-02-21 MGe  - added d1_irq_enum to d1_irqtypes
    +//  2007-10-05 CSe  - added function d1_displaygetactivelayersource
    +//  2007-10-18 ASc  - added display related structs to allow compilation of 
    +//                    dave driver without the display driver
    +//  2009-03-17 MMa  - support for TES DISPLAY CONTROLLER:
    +//                  - added device ID for TES Display Controller
    +//                  - added enums d1_alphamodes and d1_blendmodes
    +//                  - added new layermodes to d1_layermodes
    +//                  - added fields to d1_displaycaps
    +//                  - added fields to d1_layercaps
    +//                  - added display controller functions
    +//  2009-10-30 ASt  - extended enumeration type d1_layermodes (contains now the 6 supported formats)
    +//  2012-08-27 MRe  - added d1 devices D1_USERDATA and D1_DLISTINDIRECT (new version 1.3)
    +
    +/*--------------------------------------------------------------------------
    +*  Title: D1 API
    +*
    +* Hardware dependent  D/AVE 2D low level driver
    +*
    +*---------------------------------------------------------------------
    +*/
    +
    +
    +#ifndef __1_dave_base_h_H
    +#define __1_dave_base_h_H
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +
    +#define D1_VERSION_MAJOR    1
    +#define D1_VERSION_MINOR    4
    +
    +//---------------------------------------------------------------------------
    +// types
    +
    +#ifndef D1_STDCALL
    +#ifdef WIN32
    +#define D1_STDCALL __stdcall
    +#else
    +#define D1_STDCALL
    +#endif
    +#endif
    +
    +
    +
    +//---------------------------------------------------------------------------
    +// device id's
    +
    +#define D1_DAVE2D       1
    +#define D1_BUTTONS      2
    +#define D1_LCDALTERA    3
    +#define D1_DAVEDBG      4
    +#define D1_VIP          5
    +#define D1_SYSID        6
    +#define D1_DAVE_TRACE   7
    +#define D1_LCDTES       8
    +#define D1_USERDATA     9
    +#define D1_DLISTINDIRECT   10
    +#define D1_TOUCHSCREEN  11
    +
    +
    +/*---------------------------------------------------------------------------
    +*  Enum: d1_buttons
    +*
    +*  Buttons
    +*
    +*  Values:
    +*    d1_btn_1       -  Button 1
    +*    d1_btn_2       -  Button 2
    +*    d1_btn_3       -  Button 3
    +*    d1_btn_4       -  Button 4
    +*    d1_btn_5       -  Button 5
    +*    d1_btn_6       -  Button 6
    +*
    +*/
    +enum d1_buttons
    +{
    +    d1_btn_1 = 1,
    +    d1_btn_2 = 2,
    +    d1_btn_3 = 4,
    +    d1_btn_4 = 8,
    +    d1_btn_5 = 16,
    +    d1_btn_6 = 32
    +};
    +
    +
    +/*---------------------------------------------------------------------------
    +*  Section: Types and enumerations
    +*/
    +
    +#ifndef __1_dave_driver_h_H
    +/*---------------------------------------------------------------------------
    +*  Type: d1_device
    +*
    +*    Abstract type void
    +*
    +*    The application uses pointers of this type to hold address of 
    +*    low level device structure without knowing the internal layout. The low level 
    +*    device structure layout being devie dependent.
    +*    See <d1_opendevice>
    +*/
    +typedef void d1_device;
    +#endif
    +
    +typedef void  ( D1_STDCALL *d1_interrupt)( int irqtype, void *irqdata, void *usrdata );
    +
    +/*---------------------------------------------------------------------------*/
    +
    +enum d1_timeouts
    +{
    +  d1_to_wait_forever = -1,
    +  d1_to_no_wait      =  0
    +};
    +
    +/*---------------------------------------------------------------------------*/
    +
    +enum d1_memtypes
    +{
    +  d1_mem_display = 1,
    +  d1_mem_texture = 2,
    +  d1_mem_dlist   = 4,
    +
    +  d1_mem_any     = 7
    +};
    +
    +/*---------------------------------------------------------------------------*/
    +
    +enum d1_memqueries
    +{
    +  d1_mq_installed = 0,
    +  d1_mq_available,
    +  d1_mq_free,
    +  d1_mq_allocated
    +};
    +
    +/*---------------------------------------------------------------------------*/
    +
    +enum d1_mapflags
    +{
    +  d1_mf_read = 1,
    +  d1_mf_write = 2,
    +  d1_mf_readwrite = 3,
    +  d1_mf_direct = 4
    +};
    +
    +/*---------------------------------------------------------------------------*/
    +
    +enum d1_copyflags
    +{
    +  d1_cf_shorts = 1,
    +  d1_cf_ints   = 2,
    +  d1_cf_async  = 16
    +};
    +
    +/*---------------------------------------------------------------------------*/
    +
    +enum d1_irqtypes
    +{
    +  d1_irq_break = 1,
    +  d1_irq_vbi   = 2,
    +  d1_irq_dlist = 4,
    +  d1_irq_vip   = 8,
    +  d1_irq_enum  = 16
    +};
    +
    +/*---------------------------------------------------------------------------
    +*  Enum: d1_memarchitectures
    +*  
    +*  Memory architecture types
    +*  
    +*  Values:
    +*    d1_ma_unified     -  CPU can directly access pointers returned by allocvidmem                                                 
    +*    d1_ma_separated   -  Video memory is separated from system memory and can be accessed by transfer or mapping functions only.  
    +*    d1_ma_uncached    -  CPU access to mapped video memory is not cached                                                          
    +*    d1_ma_fulluma     -  Static arrays and malloced memory can be accessed by the hardware                                        
    +*    d1_ma_mapped      -  alloced video mem is static mapped into system mem -> use <d1_mapfromvidmem>                                
    +*    d1_ma_fullmapped  -  hardware can access malloced memory and static arrays  -> use <d1_mapfromvidmem> and <d1_maptovidmem>
    +*
    +*/
    +
    +enum d1_memarchitectures
    +{
    +  d1_ma_unified    = 0x1,   
    +  d1_ma_separated  = 0x2,   
    +  d1_ma_uncached   = 0x4,   
    +  d1_ma_fulluma    = 0x8,   
    +  d1_ma_mapped     = 0x10,  
    +  d1_ma_fullmapped = 0x20
    +};
    +
    +
    +
    +/*--------------------------------------------------------------------------
    +*  Enum: enum d1_layermodes
    +*  
    +*  Video input formats for layers.
    +* 
    +*  Values:
    +*    d1_mode_alpha8   - 8 bit per pixel, alpha only
    +*    d1_mode_rgb565   - 16 bit per pixel: 5 red, 6 green, 5 blue
    +*    d1_mode_rgb888   - 32 bit per pixel: 8 red, 8 green, 8 blue, 8 unused
    +*    d1_mode_rgb444   - 16 bit per pixel: 4 red, 4 green, 4 blue, 4 unused
    +*    d1_mode_argb8888 - 32 bit per pixel: 8 alpha, 8 red, 8 green, 8 blue
    +*    d1_mode_argb4444 - 16 bit per pixel: 4 alpha, 4 red, 4 green, 4 blue
    +*    d1_mode_argb1555 - 16 bit per pixel: 1 alpha, 5 red, 5 green, 5 blue
    +*    d1_mode_rgba8888 - 32 bit per pixel: 8 red, 8 green, 8 blue, 8 alpha
    +*    d1_mode_rgba4444 - 16 bit per pixel: 4 red, 4 green, 4 blue, 4 alpha
    +*    d1_mode_grey8    -  8 bit per pixel: greyscale
    +*/
    +enum d1_layermodes
    +{
    +   d1_mode_alpha8       = 0,
    +   d1_mode_rgb565       = 1,
    +   d1_mode_rgb888       = 2,
    +   d1_mode_rgb444       = 3,
    +   d1_mode_argb8888     = 4,
    +   d1_mode_argb4444     = 5,
    +   d1_mode_argb1555     = 6,
    +   d1_mode_rgba8888     = 7,
    +   d1_mode_rgba4444     = 8,
    +   d1_mode_rgba5551     = 9,
    +   d1_mode_grey8        = 10,
    +   d1_mode_count
    +};
    +
    +
    +/*--------------------------------------------------------------------------
    +* type: enum d1_alphamodes
    +* Constant alpha modes
    +*
    +* values:
    +*  d1_alpha_none    - constant alpha is ignored
    +*  d1_alpha_replace - constant alpha is used for layer
    +*  d1_alpha_mul     - original alpha is multiplied by constant alpha
    +*/
    +enum d1_alphamodes {
    +    d1_alpha_none    = 0,
    +    d1_alpha_replace = 1,
    +    d1_alpha_mul     = 2        
    +};
    +
    +/*--------------------------------------------------------------------------
    +* type: enum d1_blendmodes
    +* Alpha Blending Modes  
    +*
    +* values:
    +*  d1_blend_zero        - set alpha to 0.0
    +*  d1_blend_one         - set alpha to 1.0
    +*  d1_blend_app         - leave alpha unchanged
    +*  d1_blend_inv_app     - use inverted alpha
    +*  d1_blend_sub_app     - use alpha of subjacent layer
    +*  d1_blend_inv_sub_app - use inverted alpha of subjacent layer
    +*/
    +enum d1_blendmodes {
    +    d1_blend_zero        = 0,
    +    d1_blend_one         = 1,
    +    d1_blend_app         = 2,
    +    d1_blend_inv_app     = 3,
    +    d1_blend_sub_app     = 4,
    +    d1_blend_inv_sub_app = 5
    +};
    +
    +
    +/*--------------------------------------------------------------------------
    +*  Type: struct d1_videomode
    +*
    +*  Display controller video output parameters.
    +* 
    +*  Members:
    +*    modeid - global ID for mode
    +*    width  - width of output picture in pixels
    +*    height - height of output picture in pixels
    +*    vfreq  - refresh rate in Hz
    +*
    +*/
    +typedef struct _d1_videomode
    +{
    +   unsigned int modeid;
    +   unsigned int width;
    +   unsigned int height;
    +   unsigned int vfreq;
    +   
    +} d1_videomode;
    +
    +
    +/*--------------------------------------------------------------------------
    +*  Type: struct d1_layercaps
    +*
    +*  Display controller layer capabilities.
    +* 
    +*  Members:
    +*    modecount  - number of modes supported by layer
    +*    layermodes - array of modes (pixel formats) supported by layer of type (<enum d1_layermodes>)
    +*    constant   - true when layer allows constant color only (e.g. background) (use: <d1_displaysetlayercolor>)
    +*    alpha      - true when layer supports alpha (use: <d1_displaysetlayeralpha>)
    +*    window     - true when layer supports windowing (use: <d1_displaysetlayerwindow>)
    +*    swappable  - true when top-down position of layer can be changed (use: <d1_displaysetlayerorder>)
    +*   moveable     - true when the position of layer can be changed (use <d1_displaysetlayerwindow>)
    +*  resizeable   - true when layer can be resized if windowing is enabled (use <d1_displaysetlayerwindow>)
    +*   framecolour  - true when a framecolour can be set for layer (use <d1_displaysetlayerframecolour>)
    +*   alphalayer   - true when a alphalayer is available for layer (use <d1_displaysetlayerenable>)
    +*   pitch        - true when the width can be smaller than the pitch (use <d1_displaysetlayerformat> and <d1_displaysetlayerwindow>)
    +*   duplicate    - true when the layer can be duplicated in horizontal and/or vertical direction (use <d1_displaysetlayerduplication>)
    +*   colourkey    - true when a colourkey can be set for the layer (use <d1_displaysetlayercolourkey>)
    +*   a1_modecount - number blendmodes for upper alpha supported by layer
    +*   a1_modes     - array of blendmodes for upper alpha supported by layer of type (<enum d1_blendmodes>) (use <d1_displaysetlayerblendmode>)
    +*   a0_modecount - number blendmodes for lower alpha supported by layer
    +*   a0_modes     - array of blendmodes for lower alpha supported by layer of type (<enum d1_blendmodes>) (use <d1_displaysetlayerblendmode>)
    +*/
    +typedef struct _d1_layercaps
    +{
    +  unsigned int modecount;
    +  const int *layermodes;
    +  int constant;  
    +  int alpha;     
    +  int window;    
    +  int swappable; 
    +  int moveable;
    +  int resizeable;
    +  int framecolour;
    +  int alphalayer;
    +  int pitch;
    +  int duplicate;
    +  int colourkey;
    +  int a1_modecount;
    +  int *a1_modes;
    +  int a0_modecount;
    +  int *a0_modes;
    +} d1_layercaps;
    +
    +
    +/*--------------------------------------------------------------------------
    +*  Type: struct d1_displaycaps
    +*  
    +*  Display controller capabilities.
    +* 
    +*  Members:
    +*   modecount     - number of output modes supported by display controller
    +*   videomodes    - array of output modes supported by display controller of type <struct d1_videomode>
    +*   layercount    - number of layers supported by display controller
    +*   layercaps     - array of layers capabilities of type <struct d1_layercaps>
    +*   major_rev     - major hardware revision of display controller
    +*   minor_rev     - minor hardware revision of display controller
    +*   blind_mode    - true when controller runs in blind mode
    +*   shadowing     - true when controller has shadow registers
    +*   gammaramp     - true when controller has a gammaramp
    +*   windowing     - true when controller supports windowing for layers
    +*   precise_blend - true when a precise alphablending method is used
    +*   red_bits      - number of red output bits
    +*   green_bits    - number of green output bits
    +*   blue_bits     - number of blue output bits
    +* 
    +*/ 
    +typedef struct _d1_displaycaps
    +{
    +  unsigned int modecount;
    +  const d1_videomode *videomodes;
    +  unsigned int       layercount;
    +  const d1_layercaps *layercaps;
    +  int major_rev;
    +  int minor_rev;
    +  int blind_mode;
    +  int shadowing;
    +  int gammaramp;
    +  int windowing;
    +  int precise_blend;
    +  int red_bits;
    +  int green_bits;
    +  int blue_bits;
    +} d1_displaycaps;
    +
    +
    +
    +/*---------------------------------------------------------------------------
    +*  Section: Basic Functions
    +*/
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_getversion
    +*   
    +*  Query version ID (device dependent).
    +*  
    +*  Parameters:
    +*    None
    +*  
    +*  Returns:
    +*    The driver revision as a single 32-bit integer (major version in the upper 16 bits)
    +*
    +*  See also:
    +*    <d1_getversionstring>
    +*/
    +extern int d1_getversion();
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_getversionstring
    +*   
    +*  Query version ID string (device dependent).
    +*  
    +*  Parameters:
    +*    None
    +*  
    +*  Returns:
    +*    the driver version as a atring
    +*
    +*  See also:
    +*    <d1_getversion>
    +*
    +*/
    +extern const char * d1_getversionstring();
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_opendevice
    +*   
    +*  Creates a device handle to access hardware
    +*
    +*  This function sets the D/AVE ISR, enables the interrupt handling and allocates
    +*  memory for a d1 handle.
    +*  It is called by the D/AVE 2D driver when initialising the hardware <d2_inithw>.
    +*  
    +*  Parameters:
    +*    flags - reserved. pass 0
    +*  
    +*  Returns:
    +*    pointer to a <d1_device> object or 0 if hardware access failed
    +*
    +*/
    +extern d1_device * d1_opendevice( long flags );
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_closedevice
    +*   
    +*  Close a device handle
    +*
    +*  It is called by the D/AVE 2D driver when de-initialising the hardware <d2_deinithw>.
    +*  Disables all interrupts.
    +*  
    +*  Parameters:
    +*    handle - pointer to the <d1_device> object
    +*  
    +*  Returns:
    +*    int - 0 if error else 1.
    +*
    +*/
    +extern int d1_closedevice( d1_device *handle );
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_getthreadid 
    +*    
    +*  Return current thread ID
    +*    
    +*  Parameters:
    +*    handle - device handle <d1_device>, see <d1_opendevice>
    +*  
    +*  Returns:
    +*    Id of the current thread based on query to OS.
    +*/
    +extern int d1_getthreadid( d1_device *handle );
    +
    +/*---------------------------------------------------------------------------
    +*  Section: Memory management  
    +*/
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_memsize
    +*   
    +*  Returns the size of the given memory block
    +*  
    +*  Parameters:
    +*    ptr - pointer to a memory block in Heap
    +*  
    +*  Returns:
    +*    int - size of the memory block.
    +*
    +*/
    +extern unsigned int d1_memsize(void * ptr);
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_allocmem
    +*   
    +*  Allocates memory on the CPU heap
    +*  
    +*  Parameters:
    +*    size - Size of the memory to be allocated
    +*  
    +*  Returns:
    +*    void * - Pointer to the start address of the allocated memory block
    +*               0 if not successful
    +*
    +*/
    +extern void * d1_allocmem(unsigned int size );
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_freemem
    +*   
    +*  Free the specified memory area on the CPU heap
    +*  
    +*  Parameters:
    +*    ptr - Pointer to the memory area to be freed
    +*  
    +*  Returns:
    +*    None
    +*
    +*/
    +extern void d1_freemem(void *ptr );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_allocvidmem
    +*
    +*  Allocate video memory
    +* 
    +*  For systems without a unified memory architecture all memory that will
    +*  be accessed directly by hardware has to be video memory.
    +*  On a UMA platform d1_allocvidmem will most likely behave just like a simple malloc.
    +* 
    +*  Note that not every platform will make use of the 'memtype' it is
    +*  used as a hint in order to get the memory best suited for the specified
    +*  purpose.
    +* 
    +*  All memory allocated using this function must be released by <d1_freevidmem>
    +* 
    +*  Parameters:
    +*    handle  - device handle (see: <d1_opendevice>)
    +*    memtype - type of memory (see list below)
    +*    size    - number of bytes
    +* 
    +*  Memtypes:
    +*    d1_mem_display - used if the memory is going to be displayed (framebuffer)
    +*    d1_mem_texture - used for textures (accessed by dave but not by the displaycontroller)
    +*    d1_mem_dlist   - used for display lists (read only for hardware)
    +* 
    +*  Returns:
    +*    pointer to memorychunk or NULL.
    +*    
    +*    the pointer returned by allocvidmem points directly to video memory and can
    +*    not be accessed by the CPU (unless the memory architecture is unified - see
    +*    <d1_queryarchitecture>). Transfer functions like <d1_copytovidmem>
    +*    and <d1_copyfromvidmem> can access video memory directly.
    +*/
    +extern void * d1_allocvidmem( d1_device *handle, int memtype, unsigned int size );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_freevidmem
    +*
    +*  Release video memory
    +* 
    +*  The memtype should be identical to what has been specified when allocating
    +*  the block.
    +* 
    +*  Parameters:
    +*    handle  - device handle (see: <d1_opendevice>)
    +*    memtype - memory pool id (see: <d1_allocvidmem>)
    +*    ptr     - address returned by <d1_allocvidmem>
    +*
    +*  Returns:
    +*    None
    +*/
    +extern void d1_freevidmem( d1_device *handle, int memtype, void *ptr );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_queryvidmem
    +* 
    +*  Get current memory status
    +* 
    +*  Not every platform will treat all memory pools as distinct heaps, so
    +*  the return values might be the same for different memtype's.
    +* 
    +*  Parameters:
    +*    handle  - device handle (see: <d1_opendevice>)
    +*    memtype - memory pool id (see: <d1_allocvidmem>)
    +*    query   - type of requested information (see below)
    +* 
    +*  Query types:
    +*    d1_mq_installed - size of installed memory
    +*    d1_mq_available - largest available free chunk
    +*    d1_mq_free      - total amount of free memory
    +*    d1_mq_allocated - total amount of allocated memory
    +* 
    +*  returns:
    +*    number of bytes
    +*/
    +extern int d1_queryvidmem( d1_device *handle, int memtype, int query );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_mapvidmem
    +* 
    +*  Map video memory for direct CPU access
    +* 
    +*  In order to access video memory directly with the CPU it has to be
    +*  mapped into system memory (unless the host has a unified memory architecture).
    +*  This function always maps an entire block (as allocated by <d1_allocvidmem>)
    +*  and therfore does not need a 'size' argument.
    +* 
    +*  Mappings must be released before the memory is freed by <d1_freevidmem>.
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +*    ptr    - video memory address returned by <d1_allocvidmem>
    +*    flags  - memory mapping flags (see below)
    +* 
    +*  Memory mapping flags:
    +*    d1_mf_read      - mapped memory will be read only
    +*    d1_mf_write     - mapped memory will be written only
    +*    d1_mf_readwrite - full access to mapped memory
    +*    d1_mf_direct    - try mapping to the same address (make videomemory visible to
    +*                      current process using its original address)
    +* 
    +*  Returns:
    +*    CPU accessible pointer to the same memory region
    +* 
    +*  See also:
    +*    <d1_unmapvidmem>
    +*/  
    +
    +extern void * d1_mapvidmem( d1_device *handle, void *ptr, int flags );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_unmapvidmem
    +* 
    +*  Release memory mapping
    +*  
    +*  Memory mapped using <d1_mapvidmem> should be unmapped before it is released.
    +*  
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +*    ptr    - mapped video memory address returned by <d1_mapvidmem>
    +*  
    +*  Returns:
    +*    boolean success.
    +*/
    +extern int d1_unmapvidmem( d1_device *handle, void *ptr );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_maptovidmem
    +* 
    +*  Map CPU accessible address of a video memory block back to video memory
    +*  address
    +* 
    +*  In systems, which have CPU and hardware address spaces statically mapped to each other
    +*  (see: <d1_queryarchitecture>), this function can be used to convert an address inside
    +*  the CPU address space and pointing to a block of video memory back to a video memory address.
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +*    ptr    - CPU accessible address pointing to a video memory block originally allocated using <d1_allocvidmem>
    +* 
    +*  Returns:
    +*    hardware accessible pointer to the same memory region or NULL if mapping not possible
    +* 
    +*  See also:
    +*    <d1_mapfromvidmem>
    +*/
    +extern void * d1_maptovidmem( d1_device *handle, void *ptr );
    +
    +/*--------------------------------------------------------------------------
    +*   Function: d1_mapfromvidmem
    +* 
    +*   Map already allocated video memory address to an address for direct CPU access
    +*  
    +*   In systems, which have CPU and hardware address spaces statically mapped to each other
    +*   (see: <d1_queryarchitecture>), this function can be used to convert a video memory
    +*   address to an address in the CPU address space.
    +*  
    +*   Parameters:
    +*     handle - device handle (see: <d1_opendevice>)
    +*     ptr    - video memory address returned by <d1_allocvidmem>
    +*  
    +*   Returns:
    +*     CPU accessible pointer to the same memory region or NULL if mapping not possible
    +*  
    +*   See also:
    +*     <d1_maptovidmem>
    +*/
    +extern void * d1_mapfromvidmem( d1_device *handle, void *ptr );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_copytovidmem
    +* 
    +*  Copy data to video memory
    +* 
    +*  Destination (video) memory area has to be allocated by <d1_allocvidmem>.
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +*    dst    - pointer into video memory (destination)
    +*    src    - pointer into system memory (source)
    +*    size   - number of bytes to copy
    +*    flags  - bitfield containing additional information on data to be copied
    +*    
    +*  Flags:
    +*    d1_cf_shorts - data consists of 16 bit values
    +*    d1_cf_ints   - data consists of 32 bit values
    +*    d1_cf_async  - allow asynchronous copy and return before the transfer is finished
    +* 
    +*  Returns:
    +*    boolean success.
    +* 
    +*  Note:
    +*    A cache flush is implicitly done if the flag 'd1_cf_async' is not passed.
    +*    To be sure, an asynchronous copy was finished, either start another copy or use see <d1_cacheflush>.
    +*/
    +extern int d1_copytovidmem( d1_device *handle, void *dst, const void *src, unsigned int size, int flags );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_copyfromvidmem
    +* 
    +*  Copy data from video memory
    +*  
    +*  Source (video) memory area has to be allocated by <d1_allocvidmem>.
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +*    dst    - pointer into system memory (destination)
    +*    src    - pointer into video memory (source)
    +*    size   - number of bytes to copy
    +*    flags  - reserved for future use. pass 0 for now.
    +* 
    +*  Returns:
    +*    boolean success.
    +* 
    +*  Note:
    +*    a cache flush is implicitly done to be sure to use correct data.
    +*/
    +extern int d1_copyfromvidmem( d1_device *handle, void *dst, const void *src, unsigned int size, int flags );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_cacheflush
    +* 
    +*  Flush CPU data caches
    +*  
    +*  When accessing video memory using the CPU it might be necessary to flush
    +*  CPU data caches in order for the DAVE hardware to see the changes.
    +* 
    +*  Parameters:
    +*    handle  - device handle (see: <d1_opendevice>)
    +*    memtype - memory pools to flush (can be or'ed together)
    +* 
    +*  Memtypes:
    +*    d1_mem_any     - flush datacache entirely
    +*    d1_mem_display - flush addresses from d1_mem_display only
    +*    d1_mem_texture - flush addresses from d1_mem_texture only
    +*    d1_mem_dlist   - flush addresses from d1_mem_dlist only
    +*    
    +*  Returns:
    +*    boolean success.
    +* 
    +*  See also:
    +*    <d1_queryarchitecture>
    +*/
    +extern int d1_cacheflush( d1_device *handle, int memtype );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_cacheblockflush
    +* 
    +*  Flush part of CPU data caches
    +*  
    +*  When accessing video memory using the CPU it might be necessary to flush
    +*  CPU data caches in order for the DAVE hardware to see the changes.
    +* 
    +*  Parameters:
    +*    handle  - device handle (see: <d1_opendevice>)
    +*    memtype - memory type to be flushed
    +*    ptr     - start address of memory to be flushed
    +*    size    - size of memory to be flushed
    +* 
    +*  Memtypes:
    +*    d1_mem_display - flush addresses from d1_mem_display only
    +*    d1_mem_texture - flush addresses from d1_mem_texture only
    +*    d1_mem_dlist   - flush addresses from d1_mem_dlist only
    +* 
    +*  Returns:
    +*    boolean success.
    +* 
    +*  See also:
    +*    <d1_queryarchitecture>
    +*/
    +extern int d1_cacheblockflush( d1_device *handle, int memtype, const void *ptr, unsigned int size );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_queryarchitecture
    +* 
    +*  Return hints about systems memory architecture
    +*  
    +*  The application can often avoid memory transfers if a unified memory
    +*  architecture is available on the host system. This function can be used
    +*  to query the host memory architecture.
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +* 
    +*  Returns:
    +* 
    +*    a bitfield with the following bits set if applicable :
    +* 
    +*    d1_ma_unified    - CPU can directly access pointers returned by <d1_allocvidmem>.
    +*                       Transfer and mapping functions will work but are unnecessary.
    +*    d1_ma_separated  - Video memory is separated from CPU memory and can be
    +*                       accessed by copy or mapping functions only.
    +*    d1_ma_uncached   - CPU access to mapped video memory is not cached.
    +*    d1_ma_fulluma    - Static arrays and malloced memory can be accessed by the hardware.
    +*    d1_ma_mapped     - Allocated video memory is statically mapped into CPU memory.
    +*                       Use <d1_mapfromvidmem> and <d1_maptovidmem> to convert addresses.
    +*    d1_ma_fullmapped - The whole CPU memory (malloced memory as well as static arrays)
    +*                       is statically mapped to the address space of the hardware.
    +*                       Use <d1_mapfromvidmem> and <d1_maptovidmem> to convert addresses
    +*                       between CPU address space and hardware address space.
    +*/
    +extern int d1_queryarchitecture( d1_device *handle );
    +
    +/*---------------------------------------------------------------------------
    +*    Section: Hardware port interface
    +*/
    +
    +/*--------------------------------------------------------------------------- 
    +*   Function: d1_devicesupported
    +*    
    +*   Check if the specified device is supported
    +*
    +*   Different hardware components and revisions offer different hardware registers (see: <Device IDs>). 
    +*   Use this function to verify that a specific hardware interface is available on the current host system.
    +*
    +*   Parameters:
    +*     handle   - pointer to a low level device <d1_device>, see <d1_opendevice>
    +*     deviceId - used to specify target hardware component, see <Device IDs> 
    +*
    +*   Returns:
    +*     int - 0 if not supported else 1
    +*
    +*/
    +extern int d1_devicesupported( d1_device *handle, int deviceid );
    +
    +/*--------------------------------------------------------------------------- 
    +*   Function: d1_deviceclkfreq
    +*    
    +*   Returns the clock frequency of the D/AVE 2D hardware
    +*
    +*   Parameters:
    +*     handle   - pointer to a low level device <d1_device>, see <d1_opendevice>
    +*     deviceid - device type
    +*   
    +*   Returns:
    +*     unsigned long - clock frequency of the drawing engine
    +*
    +*/
    +extern unsigned long d1_deviceclkfreq( d1_device *handle, int deviceid );
    +
    +/*--------------------------------------------------------------------------- 
    +*   Function: d1_setregister
    +*    
    +*   Writes to hardware register
    +*
    +*   Access to an invalid or unsupported deviceid will be ignored
    +*
    +*   Parameters:
    +*     handle   - pointer to a device <d1_device>, see <d1_opendevice>
    +*     deviceid - used to specify target hardware component, see <Device IDs>
    +*     index    - register index (starts with 0)
    +*     value    - 32-bit value to write
    +*       
    +*   Returns:
    +*     None
    +*
    +*/
    +extern void d1_setregister( d1_device *handle, int deviceid, int index, long value );
    +
    +/*--------------------------------------------------------------------------- 
    +*   Function: d1_getregister
    +*    
    +*   Read from hardware register
    +*
    +*   Reading a register from an invalid or unsupported deviceId will always return 0
    +*
    +*   Parameters:
    +*     handle   - pointer to a low level device <d1_device>, see <d1_opendevice>
    +*     deviceid - used to specify target hardware component, see <Device IDs>
    +*     index    - register index (starts with 0)
    +*   
    +*   Returns:
    +*     long     - 32-bit value of the register
    +*
    +*/
    +extern long d1_getregister( d1_device *handle, int deviceid, int index );
    +
    +
    +/*---------------------------------------------------------------------------
    +*    Section: Interrupt control
    +*/
    +
    +/*--------------------------------------------------------------------------- 
    +*   Function: d1_setirqhandler
    +*   
    +*   Register an IRQ handler
    +*
    +*   Registered callback will be called when the specified IRQ triggers. 
    +*   The IRQ will be reset automatically after the callback has been executed.  
    +*   Note that the callback code might run at a different privilege level than the main application.
    +*
    +*   You can pass NULL instead of a function pointer in order to remove a registered callback.
    +*   
    +*   Not every interrupt is available on every platform.  Unsupported IRQs will never trigger but 
    +*   setting or removing a callback for them does no harm.
    +*    
    +*   Parameters:
    +*     handle  - device handle (see: <d1_opendevice>)
    +*     irqtype - interrupt ID (see below)
    +*     code    - callback address (NULL to remove handler)
    +*     data    - userdefined data (passed on to callback directly)
    +*
    +*   Interrupt IDs:
    +*     d1_irq_break - userbreak
    +*     d1_irq_vbi   - vertical blank
    +*     d1_irq_dlist - display list finished
    +*   
    +*   Callback signature:
    +*   
    +*     | void D1_STDCALL d1_interrupt( int irqtype, void *irqdata, void *usrdata );
    +*   
    +*   Note:
    +*   
    +*     Consider that existing ISR registrations might be disabled when setting new irq handlers. 
    +*     An ISR should always call the original ISR that was registered before d1_setirqhandler was 
    +*     called (use <d1_getirqhandler>). Otherwise, e.g. in case of the vertical blank irq (d1_irq_vbi),
    +*     this will disable the display controller driver.
    +*
    +*   See also:
    +*     <d1_getirqhandler>, <d1_getirqdata>
    +*/
    +extern void d1_setirqhandler( d1_device *handle, int irqtype, d1_interrupt code, void *data );
    +
    +/*--------------------------------------------------------------------------- 
    +*  Function: d1_getirqhandler
    +*   
    +*  Retrieve an IRD handler
    +*
    +*  IRQ handler callbacks installed by <d1_setirqhandler> can be retrieved using this function
    +*
    +*  Parameters:
    +*    handle  - device handle (see: <d1_opendevice>)
    +*    irqtype - interrupt ID (see: <d1_setirqhandler>)
    +*
    +*  Returns:
    +*    callback address or 0 if no callback is registered for given IRQ       
    +*
    +*  See also:
    +*    <d1_getirqdata>, <d1_setirqhandler>
    +*/
    +extern d1_interrupt d1_getirqhandler( d1_device *handle, int irqtype );
    +
    +/*--------------------------------------------------------------------------- 
    +*   d1_callirqhandler
    +*
    +*/
    +extern int d1_callirqhandler( d1_device *handle, int irqtype, void *irqdata );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_getirqdata
    +*
    +*  Retrieve user defined data of specified IRQ
    +*  
    +*  User defined data assigned by <d1_setirqhandler> can be retrieved
    +*  using this function.
    +*  
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +*    irqtype - interrupt ID (see: <d1_setirqhandler>)
    +*  
    +*  Returns:
    +*    userdefined data or NULL if no callback is registered for given IRQ
    +*  
    +*  See also:
    +*    <d1_getirqhandler>, <d1_setirqhandler>
    +*/
    +extern void * d1_getirqdata( d1_device *handle, int irqtype );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_queryirq
    +*
    +*  Wait for next execution of specified IRQ
    +*  
    +*  Instead of using IRQ callbacks you can manually block execution until a
    +*  certain IRQ triggers. This is equivalent to setting up a callback that
    +*  signals an Event and a 'WaitForEvent' inside the main thread.
    +*  
    +*  This function is often used to synchronize rendering with the vertical
    +*  blank for flicker free animation.
    +*   
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +*    irqmask - interrupt ID (see: <d1_setirqhandler>)
    +*    timeout - flag to specify how long to wait for the interrupt (see below)
    +*   
    +*  Returns:
    +*     irqID that triggered
    +*   
    +*  Timeout flags:
    +*     d1_to_wait_forever - wait forever
    +*     d1_to_no_wait - do not wait at all
    +*/
    +extern int d1_queryirq( d1_device *handle, int irqmask, int timeout );
    +
    +/*---------------------------------------------------------------------------
    +*   Section: Timer interface
    +*   Not required by the d2 driver at all: Only for better platform portability of applications.
    +*/
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_timerres
    +*
    +*  Get the resolution of the timer
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +* 
    +*  Returns:
    +*    resolution of the timer (in microseconds)
    +* 
    +*  See also:
    +*    <d1_timerlimit>, <d1_timerreset>, <d1_timervalue>
    +*/
    +extern unsigned long d1_timerres  ( d1_device *handle );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_timerlimit
    +*
    +*  Get the maximum value of the timer
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +* 
    +*  Returns:
    +*    the maximum timer value
    +* 
    +*  See also:
    +*    <d1_timerlimit>, <d1_timerreset>, <d1_timervalue>
    +*/
    +extern unsigned long d1_timerlimit( d1_device *handle );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_timerreset
    +*
    +*  Reset the timer to zero
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +* 
    +*  See also:
    +*    <d1_timerlimit>, <d1_timerreset>, <d1_timervalue>
    +*/
    +extern void          d1_timerreset( d1_device *handle );
    +
    +/*--------------------------------------------------------------------------
    +*  Function: d1_timervalue
    +*
    +*  Retrieves the number of microseconds that have elapsed since the
    +*  last reset
    +*
    +*  It is limited to the resolution of the used timer (see <d1_timerres>).
    +* 
    +*  Parameters:
    +*    handle - device handle (see: <d1_opendevice>)
    +* 
    +*  Returns:
    +*    the return value is the number of microseconds that have elapsed since
    +*    the last reset
    +* 
    +*  See also:
    +*    <d1_timerlimit>, <d1_timerreset>, <d1_timervalue>
    +*/
    +extern unsigned long d1_timervalue( d1_device *handle );
    +
    +#ifndef Dx4
    +/*---------------------------------------------------------------------------
    +*   Section: Display controller interface
    +*   Not required by the d2 driver at all: Only for better platform portability of applications.
    +*/
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetmode
    +//
    +// Set display controller output mode.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  mode   - ID of output mode (see <struct d1_videomode>)
    +//
    +// Pre-defined mode IDs:
    +//  D1_VIDEO_OFF        - turn off display controller (if possible) 
    +//  D1_VIDEO_DEFAULT    - use default mode (first mode in list of
    +//                        possible modes from <d1_displaygetcaps>)
    +//  D1_VIDEO_640_400_60 - 640x400 pixels at 60 Hz
    +//  D1_VIDEO_640_480_60 - 640x480 pixels at 60 Hz
    +//  D1_VIDEO_800_600_60 - 800x600 pixels at 60 Hz
    +//
    +// Mode IDs of modes that are supported can be found out using
    +// <d1_displaygetcaps>.
    +//
    +// returns:
    +//  boolean success (false if display is not capable)
    +//
    +extern int d1_displaysetmode( d1_device *handle, unsigned int mode );
    +
    +extern int d1_displaysetlayerblendmode( d1_device *handle, int layer, int a1_mode, int a0_mode );
    +
    +extern int d1_displaysetlayeralphamode( d1_device *handle, int layer, int mode );
    +
    +extern int d1_displaysetlayercolourkey( d1_device *handle, int layer, unsigned int colourkey, int enable );
    +
    +extern int d1_displaysetlayerduplication( d1_device *handle, int layer, int hor_duplication, int ver_duplication );
    +
    +extern int d1_displaysetlayerframecolour( d1_device *handle, int layer, unsigned int framecolour );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetlayersource
    +//
    +// Set pointer to frame buffer for non-constant layer.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  layer  - layer number starting at 0 (see <d1_displaygetcaps> for number of layers/capabilities) 
    +//  data   - start address of frame buffer
    +//
    +// returns:
    +//  boolean success (false if layer is not capable)
    +//
    +extern int d1_displaysetlayersource( d1_device *handle, int layer, void *data );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetlayerformat
    +//
    +// Set input pixel format for layer.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  layer  - layer number starting at 0 (see <d1_displaygetcaps> for number of layers/capabilities) 
    +//  mode   - pixel format (see <enum d1_layermodes> for possible values)
    +//  pitch  - length of lines in pixels (normally width of layer)
    +//
    +// returns:
    +//  boolean success (false if layer is not capable)
    +//
    +extern int d1_displaysetlayerformat( d1_device *handle, int layer, int mode, int pitch );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetlayerwindow
    +//
    +// Set window for layer if layer is capable.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  layer  - layer number starting at 0 (see <d1_displaygetcaps> for number of layers/capabilities) 
    +//  x      - x position of top left corner in display pixel coordinates
    +//  y      - y position of top left corner in display pixel coordinates
    +//  width  - width of window in pixels
    +//  height - height of window in pixels
    +//
    +// returns:
    +//  boolean success (false if layer is not capable)
    +//
    +extern int d1_displaysetlayerwindow( d1_device *handle, int layer, int x, int y, int width, int height );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetlayeralpha
    +//
    +// Set constant alpha value for layer if layer is capable.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  layer  - layer number starting at 0 (see <d1_displaygetcaps> for number of layers/capabilities) 
    +//  alpha  - alpha value in layer alpha format (see <d1_displaysetlayerformat>)
    +//
    +// returns:
    +//  boolean success (false if layer is not capable)
    +//
    +extern int d1_displaysetlayeralpha( d1_device *handle, int layer, int alpha );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetlayercolor
    +//
    +// Set constant color value for layer if layer is capable.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  layer  - layer number starting at 0 (see <d1_displaygetcaps> for number of layers/capabilities) 
    +//  color  - color value in layer pixel format (see <d1_displaysetlayerformat>)
    +//
    +// returns:
    +//  boolean success (false if layer is not capable)
    +//
    +extern int d1_displaysetlayercolor( d1_device *handle, int layer, int color );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetlayerorder
    +//
    +// Change top-down order of layers if possible.
    +//
    +// parameters:
    +//  handle   - device handle (see <d1_opendevice>)
    +//  layer    - layer number starting at 0 (see <d1_displaygetcaps> for number of layers/capabilities) 
    +//  position - new position of layer (0 is bottom)
    +//
    +// If a layer is moved to a new position the positions of the other layers are affected
    +// in the following way:
    +// Default layer position is the same as layer number (layer 0 is at bottom).
    +// When a new position is assigned the layer is removed where it was before and inserted at the
    +// new position thus shifting all other layers in between by 1 towards the position where the layer
    +// was located before.
    +//
    +// returns:
    +//  boolean success (false if display/controller is not capable)
    +//
    +extern int d1_displaysetlayerorder( d1_device *handle, int layer, int position );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaysetlayerenable
    +//
    +// Switch separate layers on/off.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  layer  - layer number starting at 0
    +//  enable - boolean enable
    +//
    +// returns:
    +//  boolean success (false if display/controller is not capable)
    +//
    +extern int d1_displaysetlayerenable( d1_device *handle, int layer, int enable );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displayswitchlayersource
    +//
    +// Change pointer to frame buffer for non-constant layer immediately or synchronized to vertical blanking.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//  layer  - layer number starting at 0 (see <d1_displaygetcaps> for number of layers/capabilities) 
    +//  data   - start address of frame buffer
    +//  sync   - boolean: synchronize change to vertical blanking or not
    +//
    +// Not every display controller might be capable of changing the frame buffer source out of sync.
    +// In this case, the 'sync' parameter is not considered.
    +//
    +// returns:
    +//  boolean success (false if layer is not capable)
    +//
    +extern int d1_displayswitchlayersource( d1_device *handle, int layer, void *data, int sync );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaytriggerupdate
    +//
    +// Trigger an update of new display controller settings during next vertical
    +// blanking.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//
    +// Activates all new settings made by d1_displayset... functions since
    +// last update during next vertical blanking.
    +//
    +// Returns immediately: Settings made after this call before next vertical
    +// blanking are also activated!!
    +//
    +// returns:
    +//  boolean success
    +//
    +extern int d1_displaytriggerupdate( d1_device *handle );
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displayupdate
    +//
    +// Apply new display controller settings and update screen.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//
    +// Activates all new settings made by d1_displayset... functions since
    +// last update during next vertical blanking.
    +// Returns after next vertical blanking. 
    +//
    +// returns:
    +//  boolean success
    +//
    +extern int d1_displayupdate( d1_device *handle );
    +
    +extern void * d1_displaygetactivelayersource( d1_device *handle, int layer ); 
    +
    +//--------------------------------------------------------------------------
    +// function: d1_displaygetcaps
    +//
    +// Query display controller/layer capabilities.
    +//
    +// parameters:
    +//  handle - device handle (see <d1_opendevice>)
    +//
    +// returns:
    +//  pointer to (<struct d1_displaycaps>)
    +//
    +extern const d1_displaycaps * d1_displaygetcaps( d1_device *handle );
    +#endif /* Dx4 */
    +
    +/*--------------------------------------------------------------------------
    +*   Function: d1_createdifbo
    +* 
    +*   Create a DI FBO for a given frame buffer.
    +*
    +*   Parameters:
    +*     handle - device handle (see: <d1_opendevice>)
    +*     ptr    - gpu video memory address returned by <see: d1_allocvidmem>
    +*     width  - frame buffer width
    +*     height - frame buffer height in pixels
    +*     pitch  - frame buffer pitch in bytes
    +*     bpp    - frame buffer bytes per pixel
    +*  
    +*   Returns:
    +*     DI FBO handle for the given frame buffer.
    +*
    +*/
    +#ifndef di_fbo_t
    +typedef struct _di_fbo di_fbo_t;
    +#endif
    +extern di_fbo_t * d1_createdifbo(d1_device *handle, void *ptr, unsigned int width, unsigned int height, unsigned int pitch, int bpp);
    +
    +/*--------------------------------------------------------------------------
    +*   Function: d1_deletedifbo
    +* 
    +*   Delete a DI FBO.
    +*
    +*   Parameters:
    +*     handle - device handle (see: <d1_opendevice>)
    +*     difbo  - DI FBO handle to delete <see: d1_createdifbo>
    +*
    +*/
    +extern void d1_deletedifbo(d1_device *handle, di_fbo_t *fbo);
    +
    +#ifdef __cplusplus
    +}
    +#endif
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_box.h b/src/drivers/dave2d/include/dave_box.h
    new file mode 100644
    index 000000000..dcb003bdd
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_box.h
    @@ -0,0 +1,35 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_box.h (%version: 3 %)
    + *          created Tue Feb 08 17:11:45 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Jan 16 17:10:30 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_box_h_H
    +#define __1_dave_box_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_renderbox_intern(  d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +
    +D2_EXTERN d2_s32 d2_renderbox_inline( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +
    +D2_EXTERN d2_s32 d2_renderbox_solid( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +
    +D2_EXTERN d2_s32 d2_renderbox_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +
    +D2_EXTERN d2_s32 d2_renderbox_outline( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +
    +D2_EXTERN d2_s32 d2_renderbox_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +
    +D2_EXTERN d2_s32 d2_renderbox_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +
    +D2_EXTERN d2_s32 d2_clearbox_solid( d2_device *handle, d2_color clearcolor );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_circle.h b/src/drivers/dave2d/include/dave_circle.h
    new file mode 100644
    index 000000000..27941a88b
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_circle.h
    @@ -0,0 +1,31 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_circle.h (%version: 3 %)
    + *          created Mon Jan 24 15:25:42 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Feb 14 14:37:17 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_circle_h_H
    +#define __1_dave_circle_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +d2_s32 d2_rendercircle_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x, d2_point y, d2_width r, d2_width w );
    +
    +extern d2_s32 d2_rendercircle_solid( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w );
    +
    +extern d2_s32 d2_rendercircle_shadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w );
    +
    +extern d2_s32 d2_rendercircle_outline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w );
    +
    +extern d2_s32 d2_rendercircle_solidoutline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w );
    +
    +extern d2_s32 d2_rendercircle_solidshadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_context.h b/src/drivers/dave2d/include/dave_context.h
    new file mode 100644
    index 000000000..3ebbf1052
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_context.h
    @@ -0,0 +1,160 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_context.h (%version: 20 %)
    + *          created Tue Jan 11 16:24:57 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Dec 12 13:43:08 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2008-04-30 MRe  added RLE and subbyte formats
    + *  2008-09-25 MRe  added circleextendoffset
    + *  2010-02-26 MRe  removed srcblend and dstblend from context
    + *  2011-03-17 MRe  reduced size of context structure
    + *  2012-09-25 BSp  MISRA cleanup
    +*-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_context_h_H
    +#define __1_dave_context_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +#include "dave_gradient.h"
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u8 d2_context_featurebits;
    +
    +#define d2_feat_none   0u
    +#define d2_feat_blur   1u    /* set if bluring is active */
    +#define d2_feat_aa     2u    /* set if antialiasing is active */
    +#define d2_feat_ulim   4u    /* set if ulimiter is required */
    +#define d2_feat_vlim   8u    /* set if vlimiter is required */
    +
    +/*---------------------------------------------------------------------------*/
    +
    +typedef d2_u8 d2_context_dirtybits;
    + 
    +#define d2_dirty_material      1u
    +#define d2_dirty_premalpha_p   2u
    +#define d2_dirty_premalpha_t   4u
    +#define d2_dirty_upatlim       8u
    +#define d2_dirty_texlim       16u
    +
    +/*---------------------------------------------------------------------------
    + * Context structure */
    +
    +typedef struct _d2_contextdata
    +{
    +   struct _d2_contextdata *next;       /* to chain device context's [must be index 0] */
    +   struct _d2_devicedata *device;
    +
    +   /* material parameters */
    +   d2_color         basecolor[2];
    +   d2_alpha         patternalpha[2];
    +   d2_alpha         basealpha[2];
    +   d2_width         blurring;
    +   d2_u8            alphamode;
    +   d2_u8            fillmode;
    +   d2_u8            alphablendflags;
    +   d2_u8            gradients;
    +   d2_gradientdata  gradient[4];
    +   d2_gradientdata  patulim[1];
    +   d2_gradientdata  texlim[2];
    +   d2_s32           orgpattern;
    +   d2_s32           patlen;
    +   d2_s32           patoffset;
    +   d2_s32           patscale;
    +   d2_u8            patmode;
    +   d2_u8            features;
    +   d2_u8            linecap;
    +   d2_u8            linejoin;
    +   d2_width         miterlimit;
    +   d2_width         circleextendoffset;
    +   d2_alpha         texop_p1[4];
    +   d2_alpha         texop_p2[4];
    +   d2_u8            texamode, texrmode, texgmode, texbmode;
    +   d2_u8            texmode;
    +   d2_u8            texbpp;
    +   d2_u8            texsubppb;    /* sub-byte formats: pixel per byte 1, 2, 4 or 8 */
    +   d2_u8            rlebpp;       /* rle encoded bytes per pixel 1, 2, 3 or 4 */
    +   d2_s32           texpitch;
    +   d2_s32           texwidth;
    +   d2_s32           texheight;
    +   void *           texbase;
    +   d2_s32           texcenterx;
    +   d2_s32           texcentery;
    +   d2_color *       texclut;
    +   d2_color *       texclut_cached;
    +   d2_s8            texclutupload;
    +   d2_u8            texclutoffset;
    +   /* precalculated values */
    +   d2_u8           internaldirty;
    +   d2_s8           roundends;
    +   d2_u32          invblur;
    +   d2_s32          pattern;
    +   d2_s32          invpatscale;
    +
    +   d2_u32          blendmask;
    +   d2_u32          alphablendmask;
    +   d2_u32          cr2mask;
    +   d2_u32          thresholdmask;
    +   d2_u32          tbstylemask;
    +   d2_u32          patmodemask;
    +   d2_u32          texmodemask;
    +   d2_u32          texwrapmask;
    +   d2_u32          rlemask;
    +   d2_u32          clutmask;
    +   d2_u32          colkeymask;
    +
    +   d2_color        colorkey;
    +
    +   d2_color        constalpha;
    +   d2_color        premalpha[2];
    +   d2_color        texmodecl[2];
    +   d2_color        texcolreg[2];
    +
    +   void *          blit_src;
    +   d2_s32          blit_pitch;
    +   d2_s32          blit_width;
    +   d2_s32          blit_height;
    +   d2_u32          blit_format;
    +
    +} d2_contextdata;
    +
    +
    +/*---------------------------------------------------------------------------
    +* Backup data for context content used by blit structure */
    +
    +typedef struct _d2_contextdata_backup
    +{
    +    d2_u8              fillmode;         
    +    d2_u8              features;
    +    d2_u8              internaldirty;
    +    d2_s32             texcenterx;
    +    d2_s32             texcentery;
    +    d2_u32             tbstylemask;
    +    d2_u32             texwrapmask;
    +    d2_u32             texmodemask;
    +    d2_s32             texpitch;
    +    d2_s32             texwidth;
    +    d2_s32             texheight;
    +    void *             texbase;
    +    d2_u8              texmode;
    +    d2_u8              texbpp;
    +    d2_u8              texsubppb;
    +    d2_u8              rlebpp;
    +    d2_u32             rlemask;
    +    d2_u32             clutmask;
    +    d2_u32             cr2mask;
    +    d2_color           texmodecl[2];
    +    d2_gradientdata    texlim[2];
    +
    +} d2_contextdata_backup;
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN void d2_calcpatternalpha_intern( d2_contextdata *ctx );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_curve.h b/src/drivers/dave2d/include/dave_curve.h
    new file mode 100644
    index 000000000..9411185c4
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_curve.h
    @@ -0,0 +1,27 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_curve.h (%version: 12 %)
    + *          created Thu Feb 17 15:09:41 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Dec 02 15:16:48 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2008-10-02 MRe  fix of blurred circles
    + *  2008-11-24 AJ   modify code to support IAR compiler. (no 64bit support)
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_curve_h_H
    +#define __1_dave_curve_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +
    +/*--------------------------------------------------------------------------
    + * r must be positive, for negative circles pass 'invert = 1'
    + * */
    +D2_EXTERN void d2_circlesetup_intern(d2_devicedata *handle, const d2_contextdata *ctx, d2_u32 index, d2_point x, d2_point y, d2_width r, d2_s32 band, d2_s32 invert, d2_s32 hiprec );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_d0_mm_dynamic.h b/src/drivers/dave2d/include/dave_d0_mm_dynamic.h
    new file mode 100644
    index 000000000..a22ebff90
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_d0_mm_dynamic.h
    @@ -0,0 +1,21 @@
    +//--------------------------------------------------------------------------
    +// Project: D/AVE
    +// File:    dave_d0_mm_dynamic.h (%version: 1 %)
    +//
    +// Description:
    +//  dynamic memory managment functions for dave.
    +//  %date_modified: Wed Jan 31 13:56:27 2007 %  (%derived_by:  hh74036 %)
    +//
    +// Changes:
    +//   2007-01-30 MGe start used old structure of d0_libs as base
    +//
    +
    +#ifndef __DAVE_D0_MM_DYNAMIC_H_
    +#define __DAVE_D0_MM_DYNAMIC_H_
    +
    +extern void * d0_dyn_allocmem( unsigned int size );
    +extern void d0_dyn_freemem( void *ptr );
    +extern unsigned int d0_dyn_memsize( void *ptr );
    +
    +#endif
    +
    diff --git a/src/drivers/dave2d/include/dave_d0_mm_fixed_range.h b/src/drivers/dave2d/include/dave_d0_mm_fixed_range.h
    new file mode 100644
    index 000000000..f9dcd5a44
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_d0_mm_fixed_range.h
    @@ -0,0 +1,36 @@
    +//--------------------------------------------------------------------------
    +// Project: D/AVE
    +// File:    dave_d0_mm_fixed_range.h (%version: 1 %)
    +//
    +// Description:
    +//  Memory management in a fixed range of memory
    +//  %date_modified: Wed Jan 31 13:56:41 2007 %  (%derived_by:  hh74036 %)
    +//
    +// Changes:
    +//   2006-11-21 MGe start
    +//
    +
    +#ifndef __DAVE_D0_MM_FIXED_RANGE_H
    +#define __DAVE_D0_MM_FIXED_RANGE_H
    +#ifdef __cplusplus
    +extern "C" {	
    +#endif
    +
    +#ifndef NULL
    +#ifdef __cplusplus
    +#define NULL    0
    +#else
    +#define NULL    ((void *)0)
    +#endif
    +#endif
    +
    +//---------------------------------------------------------------------------
    +extern void * d0_fixed_range_heapalloc(void *ctrlblk, unsigned int size);
    +extern unsigned int d0_fixed_range_heapfree(void *ctrlblk, void *ptr);
    +extern unsigned int d0_fixed_range_heapmsize(void *ctrlblk, void *ptr);
    +extern void d0_fixed_range_setheapmem( void *base, unsigned int size );
    +//---------------------------------------------------------------------------
    +#ifdef __cplusplus
    +}
    +#endif
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_d0_mm_fixed_range_fixed_blkcnt.h b/src/drivers/dave2d/include/dave_d0_mm_fixed_range_fixed_blkcnt.h
    new file mode 100644
    index 000000000..6f64bd926
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_d0_mm_fixed_range_fixed_blkcnt.h
    @@ -0,0 +1,50 @@
    +//--------------------------------------------------------------------------
    +// Project: D/AVE
    +// File:    dave_d0_mm_fixed_range_fixed_blkcnt.h (%version: 1 %)
    +//
    +// Description:
    +//  memory management with controlstructure in a separate addressspace
    +//  %date_modified: Wed Jan 31 13:56:57 2007 %  (%derived_by:  hh74036 %)
    +//
    +// Changes:
    +//   2006-11-21 CSe start
    +//   2006-01-31 MGe redesign
    +
    +#ifndef __DAVE_D0_MM_FIXED_RANGE_FIXED_BLK_H_
    +#define __DAVE_D0_MM_FIXED_RANGE_FIXED_BLK_H_
    +#ifdef __cplusplus
    +extern "C" {	
    +#endif
    +
    +#ifndef NULL
    +#ifdef __cplusplus
    +#define NULL    0
    +#else
    +#define NULL    ((void *)0)
    +#endif
    +#endif
    +
    +typedef struct _d0_fixed_range_fixed_blk_memblock {
    +  void*        addr;
    +  unsigned int size;
    +} d0_fixed_range_fixed_blk_memblock;
    +
    +typedef struct _d0_fixed_range_fixed_blk_heap {
    +  d0_fixed_range_fixed_blk_memblock *freeblocks;
    +  d0_fixed_range_fixed_blk_memblock *usedblocks;
    +  unsigned int maxidx;  // size of both arrays -1
    +} d0_fixed_range_fixed_blkcnt_heap;
    +
    +
    +//---------------------------------------------------------------------------
    +
    +extern void d0_fixed_range_fixed_blkcnt_heapinit( void* ctrlblk, void* heapaddr, unsigned int heapsize, unsigned int maxblocks);
    +extern void * d0_fixed_range_fixed_blkcnt_heapalloc(void* ctrlblk, unsigned int size);
    +extern unsigned int d0_fixed_range_fixed_blkcnt_heapfree(void* ctrlblk, void *ptr);
    +extern unsigned int d0_fixed_range_fixed_blkcnt_heapmsize(void* ctrlblk, void *ptr);
    +
    +//---------------------------------------------------------------------------
    +#ifdef __cplusplus
    +}
    +#endif
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_d0lib.h b/src/drivers/dave2d/include/dave_d0lib.h
    new file mode 100644
    index 000000000..8ea820668
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_d0lib.h
    @@ -0,0 +1,298 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_d0lib.h (%version: 5 %)
    + *
    + * Description:
    + *  memory management
    + *  %date_modified: Mon Feb 05 18:57:37 2007 %  (%derived_by:  hh74036 %)
    + *
    + * Changes:
    + *  MGe 013107 redesign
    + *  ASc 083007 fix d0_initheapmanager description, changed C++ to C comments
    + *  CSe 080422 export d0_preparememorymanager */
    +
    +/******************************************************************************
    + *  Title: Heap management
    + *  Collection of heap managers, which may be used by a d1 driver implementation on
    + *  a certain platform. Eases d1 platform porting e.g. on non-UMA platforms or on
    + *  platforms which don't have a stdlib with malloc/free/msize
    + *
    + *  There are three available types of memory managers. These managers can be
    + *  used to manage blocks of memory e.g. video memory, heap memory etc.
    + *
    + *  Types of memory managers:
    + *
    + *    d0_mm_dynamic  - Wrappers for stdlib malloc, free and msize of the system.
    + *
    + *    d0_mm_fixed_range - Memory manager which uses one block of memory for
    + *                        memory allocation and control structures (list
    + *                        of allocated memory blocks).
    + *                        This manager is normally used as manager for a heap
    + *                        on systems that do not provide dynamic memory
    + *                        allocation.
    + *                        This memory manager needs 42 bytes of fixed control information.
    + *                        For each block of allocated memory additional 8 bytes of
    + *                        control information will be stored.
    + *
    + *    d0_mm_fixed_range_fixed_blkcnt - Memory manager which uses two blocks of
    + *                                     memory: one for allocation and one for
    + *                                     control structures (lists for free and
    + *                                     used blocks).
    + *                                     This manager is normally used to manage
    + *                                     memory that isn't directly mapped to the
    + *                                     system memory. Because of this, it needs
    + *                                     a second block of memory in order to
    + *                                     store control information. You have to
    + *                                     predefine a fixed number of memory
    + *                                     blocks that can be used. Typically used
    + *                                     on systems with separate video memory.
    + *                                     This memory manager needs 28 bytes of fixed control information
    + *                                     and 16 bytes for each block of allocatable memory.
    + *
    + * Topic: Usage
    + * How to use the D/AVE driver memory management interface.
    + *
    + *  If you want to make use of the d0 memory management functions, your d1 platform
    + *  code for <d1_allocmem>, <d1_freemem>, <d1_memsize>, <d1_allocvidmem> and <d1_freevidmem>
    + *  should wrap the respective d0_* functions.
    + *  You then need to initialize the heap managers somewhere in your application
    + *  before you do any d1 or d2 driver calls.
    + *  The simplest way is to call <d0_initdefaultheapmanager>.
    + *  This function registers a wrapper for the stdlib malloc, free and msize
    + *  functions. These functions will be used as managers for the
    + *  video and heap memory.
    + *  In order to register different managers for the heap and video memory, you
    + *  have to use the function <d0_initheapmanager>. This function allows to choose
    + *  different memory managers for video and heap management.
    + *
    + * Topic: 
    + *****************************************************************************/
    +
    +#ifndef __1_dave_d0lib_h_H
    +#define __1_dave_d0lib_h_H
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +/*--------------------------------------------------------------------------- */
    +
    +#ifndef NULL
    +#ifdef __cplusplus
    +#define NULL    0
    +#else
    +#define NULL    ((void *)0)
    +#endif
    +#endif
    +
    +typedef enum
    +{
    +  d0_ma_unified   =0x0,    /* Video memory is in the same address space as the heapmanager */
    +  d0_ma_separated  = 0x1   /* Video memory is separated from system memory and can be accessed by transfer or mapping functions only. */
    +} d0_memarchitectures;
    +
    +
    +
    +typedef enum {
    +  d0_mm_fixed_range,
    +  d0_mm_fixed_range_fixed_blkcnt,
    +  d0_mm_dynamic
    +  } d0_memmanager_type;
    +
    +/*****************************************************************************
    + * typedef : d0_fp_allocmem
    + *  Function pointer to a memory allocation function.
    + *
    + * parameters :
    + *  ctrlblk - pointer to a control block of the current memory manager
    + *  size    - size of the requested memory block
    + *
    + * returns :
    + *  a pointer to the allocated memory block or NULL
    + ****************************************************************************/
    +typedef void*         (*d0_fp_allocmem)( void*, unsigned int );
    +
    +/*****************************************************************************
    + * typedef : d0_fp_freemem
    + *  Function pointer to a memory freeing function.
    + *
    + * parameters :
    + *  ctrlblk - pointer to a control block of the current memory manager
    + *  ptr    - pointer to the memory block that shall be freed
    + ****************************************************************************/
    +typedef void          (*d0_fp_freemem) ( void*, void*  );
    +
    +/*****************************************************************************
    + * typedef : d0_fp_memsize
    + *  Function pointer to the memory size function.
    + *
    + * parameters :
    + *  ctrlblk - pointer to a control block of the current memory manager
    + *  ptr    - pointer to the memory block, whose size is requested
    + *
    + * returns :
    + *  the size of the memory block
    + ****************************************************************************/
    +typedef unsigned int  (*d0_fp_memsize) ( void*, void* );
    +
    +/*****************************************************************************
    + * type : struct d0_memmanager
    + *  Instance of a memory manager
    + *
    + *  fields :
    + *    allocmem  - function pointer to the memory allocation function <d0_fp_allocmem>
    + *    freemem - function pointer to the memory free function <d0_fp_freemem>
    + *    memsize - function pointer to the memory size function <d0_fp_memsize>
    + *    ctrlblk - points to the control data of the memory manager
    + ****************************************************************************/
    +typedef struct {
    +  d0_fp_allocmem allocmem;
    +  d0_fp_freemem  freemem;
    +  d0_fp_memsize  memsize;
    +  void* ctrlblk;
    +} d0_memmanager;
    +
    +
    +
    +/******************************************************************************
    + * function: d0_preparememorymanager
    + *  Initalize a heapmanager.
    + *
    + * parameters:
    + *  mgr             - pointer to a d0_memmanager structure to be initialized
    + *
    + *  memmanagertype  - defines which kind of memorymangment will be used
    + *
    + *  base            - baseaddress of the addressrange( not used for
    + *                    d0_mm_dynamic memorymanager)
    + *
    + *  size            - size of the memory in bytes( not used for
    + *                    d0_mm_dynamic memorymanager)
    + *
    + *  ctrlblk         - startaddress of memory block used for controlstructure
    + *                    this block must have a size of:
    + *                    2*blockcnt*sizeof( d0_fixed_range_fixed_blk_memblock )
    + *                    +sizeof(d0_fixed_range_fixed_blkcnt_heap)
    + *
    + *  blockcnt        - amount of allocatable blocks in memoryrange( only used
    + *                    for d0_mm_fixed_range_fixed_blkcnt memorymanager)
    + *****************************************************************************/
    +extern void d0_preparememorymanager( d0_memmanager *mgr, d0_memmanager_type memmanagertype, void *base,
    +                                     unsigned int size, void *ctrlblk, unsigned int blkcnt );
    +
    +
    +/******************************************************************************
    + * function: d0_initheapmanager
    + *  Initialize the memory managers for the local heap memory and one for the
    + *  video memory.
    + *
    + * parameters:
    + *  heapaddress   - start address of the local heap memory
    + *  heapsize      - size of the local heap in bytes
    + *  heapmgrtype   - type of the memory manager use for the local heap memory (see above)
    + *  vidmemaddress - start address of the video memory
    + *  vidmemsize    - size of the video memory
    + *  vidmemblkcnt  - amount of allocatable blocks in video memory range
    + *  vidmemmgrtype - type of the memory manager use for the video memory (see above)
    + *  flags         - possible values (d0_ma_unified, d0_ma_separated)
    + *
    + * note:
    + *  If 'd0_ma_unified' is passed as flag, the video memory manager parameters
    + *  are ignored. The heap memory manager will also be used as video memory manager.
    + *
    + * returns:
    + *    1 on success otherwise 0
    + *****************************************************************************/
    +extern int d0_initheapmanager(  void* heapaddress, unsigned int heapsize,
    +                         d0_memmanager_type heapmgrtype, void* vidmemaddress,
    +                         unsigned int vidmemsize, unsigned int vidmemblkcnt,
    +                         d0_memmanager_type vidmemmgrtype,
    +                         d0_memarchitectures flags
    +                        );
    +
    +
    +/******************************************************************************
    + * function: d0_initdefaultheapmanager
    + *  Initialize 'd0_mm_dynamic' as default memory manager.
    + *
    + * returns:
    + *  This function returns 1
    + *****************************************************************************/
    +extern int d0_initdefaultheapmanager( void ) ;
    +
    +/******************************************************************************
    + * function: d0_allocvidmem
    + *  Allocate a block of video memory.
    + *  This is a wrapper for the memory allocation function of the video memory.
    + *
    + * parameters:
    + *  size    -   size of the memory block in bytes
    + *
    + * returns:
    + *  a pointer to the newly allocated memory block or NULL if an error occured
    + *****************************************************************************/
    +extern void* d0_allocvidmem( unsigned int size );
    +
    +/******************************************************************************
    + * function: d0_freevidmem
    + *  Free a block of video memory.
    + *  This is a wrapper for the memory freeing function of the video memory.
    + *
    + * parameters:
    + *  ptr     - pointer to the memory block
    + *****************************************************************************/
    +extern void  d0_freevidmem( void *ptr );
    +
    +/******************************************************************************
    + * function: d0_vidmemsize
    + *  Returns the size of a video memory block.
    + *  This is a wrapper for the memory size function of the video memory.
    + *
    + * parameters:
    + *  ptr     - points to the memory block
    + *
    + * returns:
    + *  the size of the memory block
    + *****************************************************************************/
    +extern unsigned int d0_vidmemsize( void *ptr );
    +
    +/******************************************************************************
    + * function: d0_allocmem
    + *  Allocate local heap memory.
    + *  This is a wrapper for the memory allocation function of the local heap memory.
    + *
    + * parameters:
    + *  size    -   size of the memory block in bytes
    + *
    + * returns:
    + *  a pointer to the newly allocated memoryblock or NULL if an error occured
    + *****************************************************************************/
    +extern void* d0_allocmem( unsigned int size );
    +
    +/******************************************************************************
    + * function: d0_freemem
    + *  Free a block of local heap memory.
    + *  This is a wrapper for the memory freeing function of the local heap memory.
    + *
    + * parameters:
    + *  ptr     - pointer to the memory block
    + *****************************************************************************/
    +extern void  d0_freemem( void *ptr );
    +
    +/******************************************************************************
    + * function: d0_memsize
    + *  Returns the size of a local memory block.
    + *  This is a wrapper for the memory size function of the local heap memory.
    + *
    + * parameters:
    + *  ptr     - pointer to the memory block
    + *
    + * returns:
    + *  the size of the memory block
    + *****************************************************************************/
    +extern unsigned int  d0_memsize( void *ptr );
    +
    +
    +/*--------------------------------------------------------------------------- */
    +#ifdef __cplusplus
    +}
    +#endif
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_dlist.h b/src/drivers/dave2d/include/dave_dlist.h
    new file mode 100644
    index 000000000..a9b707efa
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_dlist.h
    @@ -0,0 +1,258 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_dlist.h (%version: 20 %)
    + *          created Thu Feb 17 21:44:45 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jan 25 17:39:49 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + * 2005-12-22 CSe  - added d2_copydlist_vidmem_intern()
    + *                 - renamed block->vram to block->vidmem for consistency
    + *                 - big endian change + define for BIG_ENDIAN
    + * 2005-02-28 CSe  - added d2_cacheflushdlist_intern()
    + * 2006-05-10 CSe  - added d2_mapdlist_vidmem_intern()
    + * 2006-10-30 CSe  - removed counting of dlist used slots
    + * 2006-11-07 CSe  - changes for new 'd2_df_low_localmem' mode
    + * 2006-11-30 CSe  - fixed insertion of dlist special commands
    + * 2007-01-26 CSe  - made 'low localmem' mode configurable
    + * 2007-03-08 CSe  - optimized dlist copying and flushing
    + * 2008-01-14 ASc  - changed comments from C++ to C, removed tabs
    + * 2012-08-23 MRe  - extended dlist structure for dlist lists
    + * 2012-09-25 BSp  - MISRA cleanup
    + * 2017-07-27 HFu  - clearly commented and renamed d2_insertwait...dlist_intern functions
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_dlist_h_H
    +#define __1_dave_dlist_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +#define D2_DLISTWRITES(x, y)  d2_add2dlist_intern( handle, x, y )             /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_DLISTWRITEU(x, y)  d2_add2dlist_intern( handle, x, (d2_s32) (y) )  /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +
    +/*-------------------------------------------------------------------------- */
    +#define D2_DLISTBLOCKSIZE 204    /* blocksize: initial number and number of entrys to grow when dlist is full (5*4*204 = approx. 4kBytes) */
    +#define D2_DLISTSCRATCH   64     /* number of scratch buffer entries */
    +#define D2_DLISTSHRINKDELAY 60   /* number of frames, the amount of display list blocks needs to be too large, before it is reduced */
    +
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef struct _d2_dlist_vidmem_blocks
    +{
    +   void **   blocks;          /* array of dlist blocks in vidmem */
    +   d2_u32    num_blocks;      /* number of entries in above array */
    +   d2_u32    block_size;      /* size of blocks in vidmem */
    +   void **   currentblock;    /* pointer into above array of vidmem blocks */
    +   d2_s8 *   currentaddress;  /* pointer into vidmem inside current block (multiple local blocks are copied into one vidmem block) */
    +   d2_u32    num_slices;      /* one vidmem blocks consists of multiple slices (see above) */
    +   d2_u32    slicesleft;      /* number of slices left */
    +   d2_u32    blocksleft;      /* number of vidmem blocks left */
    +} d2_dlist_vidmem_blocks;
    +
    +
    +typedef struct _d2_dlist_entry
    +{
    +   union d2_addresstag                 /* register tag field (4 reg indices) */
    +   {
    +      d2_u32 mask;
    +      d2_u8  array[4];
    +   } address;
    +
    +   d2_s32 value[4];                       /* register value field */
    +} d2_dlist_entry;
    +
    +
    +typedef struct _d2_dlist_block
    +{
    +   struct _d2_dlist_block *next;
    +
    +   d2_dlist_entry * block;              /* display list memory */
    +   d2_u32           quantity;           /* number of dlist_entries */
    +   d2_s32 *         jump;               /* pointer to addressentry of next display list or null */
    +   void *           vidmem;             /* address of memoryblock in videoram or null */
    +} d2_dlist_block ;
    +
    +
    +typedef struct _d2_dlist
    +{
    +   d2_device              *device;
    +   d2_dlist_block         *firstblock;
    +   d2_dlist_block         *currentblock;
    +   d2_dlist_block         *resumeblock;
    +   d2_dlist_entry         *position;
    +   d2_dlist_vidmem_blocks *vidmem_blocks;   /* used in low local memory mode only */
    +
    +   d2_u32                  tagindex;
    +   d2_u32                  blocksize;
    +   d2_u32                  stepsize;
    +   d2_s32                  busy;
    +   d2_u32                  shrinkcount;
    +   d2_u32                  count;
    +
    +   void *                  dlist_addresses;        /* list of dlist start addresses accessible by Dave */
    +   d2_s16                  dlist_addresses_max;    /* max number of dlist start addresses in dlist_addresses */
    +   d2_s16                  dlist_addresses_cur;    /* current number of dlist start addresses in dlist_addresses */
    +} d2_dlist;
    +
    +
    +typedef struct _d2_dlist_scratch_entry
    +{
    +   d2_u32             reg;
    +   d2_s32             value;
    +} d2_dlist_scratch_entry;
    +
    +
    +typedef struct _d2_lowlocalmem_mode
    +{
    +   d2_dlist_block *dlist_buffer; /* two dlist blocks linked as ring */
    +   d2_u32 vidmemblocksizefactor; /* factor for size of blocks in vidmem relative to local size */
    +   d2_u32 vidmemblocks;          /* maximum number of dlist blocks in vidmem */
    +} d2_lowlocalmem_mode;
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN void d2_paddlist_intern( d2_dlist *dlist );
    +
    +D2_EXTERN void d2_growdlist_intern( d2_dlist *dlist );
    +
    +D2_EXTERN d2_dlist_block * d2_alloc_dlistblock_intern( const d2_device *handle, d2_u32 size );
    +
    +D2_EXTERN void d2_free_dlistblock_intern( const d2_device *handle, d2_dlist_block *data );
    +
    +D2_EXTERN d2_s32 d2_initdlist_intern( d2_device *handle, d2_dlist *dlist, d2_u32 initialsize );
    +
    +D2_EXTERN void d2_deinitdlist_intern(const d2_dlist *dlist);
    +
    +D2_EXTERN void *d2_preparedlist_read_intern( const d2_device *handle, d2_dlist *dlist, d2_s32 reset );
    +
    +D2_EXTERN void d2_nextdlistblock_intern( d2_dlist *dlist );
    +
    +D2_EXTERN d2_u32 d2_executedlist_intern( const d2_device *handle, d2_dlist_entry *block );
    +
    +D2_EXTERN void d2_copydlist_vidmem_intern( const d2_dlist *dlist );
    +
    +D2_EXTERN void d2_mapdlist_vidmem_intern( const d2_dlist *dlist );
    +
    +D2_EXTERN void d2_cacheflushdlist_intern( const d2_dlist *dlist );
    +
    +D2_EXTERN d2_s32 d2_insertwaitpipedlist_intern( d2_device *handle );
    +
    +D2_EXTERN d2_s32 d2_insertwaitfulldlist_intern( d2_device *handle );
    +
    +D2_EXTERN void d2_resetdlist_intern( d2_dlist *dlist );
    +
    +D2_EXTERN void d2_scratch2dlist_intern( d2_device *handle );
    +
    +D2_EXTERN void d2_clear_dlistlist_intern( const d2_device *handle, d2_dlist *dlist );
    +
    +D2_EXTERN d2_s32* d2_add_dlistlist_intern( const d2_device *handle, d2_dlist *dlist, const void *dlistaddress );
    +
    +
    +/*--------------------------------------------------------------------------- */
    +
    +/* call only when usedslots>0
    + * assumes full dlist_entries. padded entries supported at end of list only */
    +static D2_INLINE d2_dlist_entry* d2_getdlist_intern( d2_dlist *dlist ) /* PRQA S 1527 */ /* $Misra: #PERF_INLINE_FUNC $*/ /* PRQA S 3219, 3450, 3480 */ /* $Misra: #UTIL_INLINE_FUNC $*/
    +{
    +   d2_dlist_entry *current;
    +
    +   current = dlist->position;
    +   dlist->position++;
    +   dlist->blocksize--;
    +
    +   if (dlist->blocksize < 1)
    +   {
    +      /* this block ran empty, setup for next read */
    +      d2_dlist_block *n = dlist->currentblock->next;
    +      if(NULL != n)
    +      {
    +         /* switch to next block */
    +         dlist->position     = n->block;
    +         dlist->blocksize    = n->quantity;
    +         dlist->currentblock = n;
    +      }
    +   }
    +
    +   return current;
    +}
    +
    +/* insert a jump into the dlist to target, return patch address */
    +static D2_INLINE d2_s32* d2_insertdlistjump_intern( d2_dlist *dlist, const void *target ) /* PRQA S 1527 */ /* $Misra: #PERF_INLINE_FUNC $*/ /* PRQA S 3219, 3450, 3480 */ /* $Misra: #UTIL_INLINE_FUNC $*/
    +{
    +   d2_s32 *patch;
    +
    +   /* this block ran empty. insert dlist-jump and mark end */
    +   dlist->position->address.mask = D2_DLISTSTART | 0x80808000u;
    +   dlist->position->value[0] = (d2_s32)target;
    +
    +   /* remember value offset for later patching */
    +   patch = & dlist->position->value[0];
    +   dlist->currentblock->jump = patch;
    +
    +   /* skip jump */
    +   dlist->position = (d2_dlist_entry*) (((d2_s32 *)dlist->position) + 2);
    +   dlist->tagindex = 0;
    +
    +   return patch;
    +}
    +
    +
    +/* store a end of dlist special word at current position */
    +static D2_INLINE void d2_insertdlistspecial_intern( d2_dlist *dlist, d2_u32 argument ) /* PRQA S 1527 */ /* $Misra: #PERF_INLINE_FUNC $*/ /* PRQA S 3219, 3450, 3480 */ /* $Misra: #UTIL_INLINE_FUNC $*/
    +{
    +   d2_u32 tagIndex = dlist->tagindex;
    +   d2_dlist_entry *pos = dlist->position;
    +
    +   switch(tagIndex)
    +   {
    +      case 0:
    +         /* list already closed -> the address word is not needed */
    +         pos->address.mask = 0xffu | (argument << 8);
    +         dlist->position = (d2_dlist_entry *) ((d2_s32*)pos + 1);
    +         break;
    +
    +      case 1:
    +         /* already one entry in list */
    +         pos->address.mask &= 0x000000ffu;
    +         pos->address.mask |= 0x80808000u;
    +         pos->value[tagIndex] = (d2_s32) (0xffu | (argument << 8));
    +         dlist->position = (d2_dlist_entry *) ((d2_s32*)pos + 3);
    +         break;
    +
    +      case 2:
    +         /* already two entries in list */
    +         pos->address.mask &= 0x0000ffffu;
    +         pos->address.mask |= 0x80800000u;
    +         pos->value[tagIndex] = (d2_s32) (0xffu | (argument << 8));
    +         dlist->position = (d2_dlist_entry *) ((d2_s32*)pos + 4);
    +         break;
    +
    +      case 3:
    +         /* already three entries in list */
    +         pos->address.mask &= 0x00ffffffu;
    +         pos->address.mask |= 0x80000000u;
    +         pos->value[tagIndex] = (d2_s32) (0xffu | (argument << 8));
    +         dlist->position++;
    +         break;
    +
    +      default:
    +         break;
    +   }
    +
    +   /* fix tag */
    +   dlist->tagindex = 0;
    +   dlist->blocksize--;
    +
    +   /* make sure not to go beyond end of block in case the list is not finished!! */
    +   if(0 == (argument & 1))
    +   {
    +      if(dlist->blocksize <= 1)
    +      {
    +         d2_nextdlistblock_intern(dlist);
    +      }
    +   }
    +}
    +/*--------------------------------------------------------------------------- */
    +#endif
    +
    diff --git a/src/drivers/dave2d/include/dave_driver.h b/src/drivers/dave2d/include/dave_driver.h
    new file mode 100644
    index 000000000..1a899647e
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_driver.h
    @@ -0,0 +1,696 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_driver.h (%version: 69 %)
    + *          created Mon Jan 10 13:38:57 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Apr 26 16:21:32 2007 %  (%derived_by:  hh74036 %)
    + *
    + * This is the only include file that should be read by driver applications
    + * See html documentation
    + *
    + * Changes:
    + *  2007-08-29 ASc  Include headers of level0/1 driver and math pkg,
    + *                  removed tabs, changed C++ to C comments
    + *  2007-09-20 ASc  Added blit flags for wrapping
    + *  2008-04-30 MRe  added RLE and subbyte formats
    + *  2008-06-12 MRe  added CLUT256 and color keying
    + *  2008-07-14 ASt  added additional performance counter values
    + *  2009-01-16 MRe  added defines for feature bits from dave_registermap.h 
    + *  2009-03-06 LBe  added enum constant for render buffer execute flags
    + *  2009-03-11 MRe  incremented version to 3.2
    + *  2010-02-18 MRe  incremented version to 3.3 for Alpha blending feature
    + *  2010-03-18 MRe  new enum d2_blendflags
    + *  2010-07-08 MRe  new device flag d2_df_no_registercaching
    + *  2010-09-13 MRe  incremented version to 3.4 beta (due to merge from branch)
    + *  2010-09-15 MRe  removed d0 memory functions, replaced by d1 memory functions 
    + *  2010-09-22 MRe  fixed typo of dc_cc_rgb, dc_cc_all
    + *  2011-03-11 MRe  improved/removed context backup for blit
    + *  2011-03-14 MRe  version 3.4
    + *  2011-05-30 MRe  version 3.5 beta
    + *  2011-06-16 MRe  added Alpha4, Alpha2, Alpha1 texture formats
    + *  2012-09-05 MRe  version 3.7
    + *  2012-09-25 BSp  MISRA cleanup
    + *  2012-10-19 MRe  version 3.8
    + *  2020-02-05 MRe  version 3.18 added d2_inithwburstlengthlimit
    +*-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_driver_h_H
    +#define __1_dave_driver_h_H
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +/*--------------------------------------------------------------------------- */
    +
    +#define D2_VERSION_MAJOR    3
    +#define D2_VERSION_MINOR    18
    +#define D2_VERSION_STATE    ""  /*"beta"*/
    +#define D2_VERSION_BRANCH   0
    +
    +#if (D2_VERSION_BRANCH == 0)
    +  #define D2_VERSION_BRANCH_STRING
    +#elif (D2_VERSION_BRANCH == 1)
    +  #define D2_VERSION_BRANCH_STRING Branch_1
    +#endif
    +
    +/*---------------------------------------------------------------------------
    + Title: Basic Types
    +
    +    Note that several types represent fixedpoint numbers. 
    +    The C compiler cannot directly create these from constants. 
    +    Therefore if you want to pass an integer value of 42 to a 
    +    function that expects an argument of e.g. type <d2_point> you would have to write :
    +    > function( 42 << 4 );    // conversion from integer to fixedpoint
    +    see also <D2_FIX4(x)>
    +*/
    +
    +#ifndef __1_dave_base_h_H
    +typedef void d1_device;
    +#endif
    +
    +#include <dave_types.h>
    +
    +
    +/*---------------------------------------------------------------------------*/
    +#define D2_EXTERN extern
    +
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_device
    +    void
    +
    +    Abstract type. The application uses pointers of this type to hold the address of a device structure
    +    without knowing its internal layout.
    +
    +    see for example : <d2_opendevice>
    +*/
    +typedef void d2_device;
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_context
    +    void
    +
    +    Abstract type. The application uses pointers of this type to hold the address of a context structure
    +    without knowing its internal layout.
    +
    +    see for example : <d2_newcontext>
    +*/
    +typedef void d2_context;
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_renderbuffer
    +    void
    +
    +    Abstract type. The application uses pointers of this type to hold the address of a renderbuffer structure
    +    without knowing its internal layout.
    +
    +    see for example : <d2_newrenderbuffer>
    +*/
    +typedef void d2_renderbuffer;
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_color
    +    unsigned long
    +
    +    32bit RGB value. Upper 8bits are ignored but should be set to zero.
    +    All colors are passed to the driver in this format regardless of the framebuffer format. 
    +
    +    see for example : <d2_setcolor>
    +*/
    +typedef d2_u32 d2_color;
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_alpha
    +    unsigned char
    +
    +    Alpha information is passed as 8bit values. 255 representing fully opaque and 0 totally 
    +    transparent colors.
    +
    +    see for example : <d2_setalpha>
    +*/
    +typedef d2_u8 d2_alpha;
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_width
    +    short (*fixedpoint*)
    +
    +    Width is defined as an unsigned 10:4 fixedpoint number (4 bits fraction). 
    +    So the maximum width is 1023 and the smallest nonzero width is 1/16.
    +*/
    +typedef d2_s16 d2_width;
    +   
    +/*---------------------------------------------------------------------------
    +  Type: d2_point
    +    short (*fixedpoint*)
    +
    +    Point defines a vertex component (e.g. the x coordinate of an endpoint) pixel position 
    +    and is specified as a signed 1:11:4 fixedpoint number (1bit sign, 11 bits integer, 4 bits fraction).
    +    So the integer range is 2047 to -2048 and the smallest positive value is 1/16.
    +
    +    Points are stored as 16bit quantities because they represent direct screen coordinates
    +    and therefor do not become larger than 2047 even for HDTV resolutions.
    +
    +    see for example : <d2_renderline>
    +*/
    +typedef d2_s16 d2_point;
    +
    +/*---------------------------------------------------------------------------
    +Type: d2_border
    +    short 
    +
    +    The border type is used only when setting clip borders. In contrast to points, borders do 
    +    not contain any fractional information (no subpixel clipping) and are simple 11bit signed
    +    integers.
    +
    +    see for example : <d2_cliprect>
    +*/
    +typedef d2_s16 d2_border;
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_pattern
    +    unsigned long
    +
    +    Patterns are Nbit bitmasks (N is 32 at most so they are passed as longs)
    +
    +    see for example : <d2_setpattern>
    +*/
    +typedef d2_u32 d2_pattern;
    +
    +/*---------------------------------------------------------------------------
    +  Type: d2_blitpos
    +      unsigned short
    +
    +      Blitpos defines an integer position in the source bitmap of a blit rendering operation. 
    +      The allowed range is 0 to 1023.
    +*/
    +typedef d2_u16 d2_blitpos;
    +
    +
    +/*---------------------------------------------------------------------------
    + * enums */
    +
    +typedef d2_u32 d2_rendermodes;
    +
    +#define d2_rm_solid           1u
    +#define d2_rm_outline         2u
    +#define d2_rm_solid_outlined  ((d2_u32)(1 + 2))
    +#define d2_rm_shadow          4u
    +#define d2_rm_solid_shadow    ((d2_u32)(1 + 4))
    +#define d2_rm_postprocess     8u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_blendmodes;
    +
    +#define d2_bm_zero             0u
    +#define d2_bm_one              1u
    +#define d2_bm_alpha            2u
    +#define d2_bm_one_minus_alpha  3u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_alphamodes;
    +
    +#define d2_am_opaque      0u
    +#define d2_am_constant    1u
    +#define d2_am_gradient1   2u
    +#define d2_am_gradient2   4u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_fillmodes;
    +
    +#define d2_fm_color     0u
    +#define d2_fm_twocolor  1u
    +#define d2_fm_pattern   2u
    +#define d2_fm_texture   3u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_edgeflags;
    +
    +#define d2_edge0_shared   1u
    +#define d2_edge1_shared   2u
    +#define d2_edge2_shared   4u
    +#define d2_edge3_shared   8u
    +#define d2_edge4_shared  16u
    +#define d2_edge5_shared  32u
    +
    +#define d2_all_shared    63u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_wedgeflags;
    +
    +#define d2_wf_concave  (d2_all_shared + 1)
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_linecapflags;
    +
    +#define d2_lc_butt    0u
    +#define d2_lc_square  1u
    +#define d2_lc_round   2u
    +
    +#define d2_lc_max     3u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_linejoinflags;
    +
    +#define d2_lj_none    0u
    +#define d2_lj_miter   1u
    +#define d2_lj_round   2u
    +#define d2_lj_bevel   4u
    +
    +#define d2_lj_max     7u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_lineendflags;
    +
    +#define d2_le_exclude_none   0u
    +#define d2_le_exclude_start  1u
    +#define d2_le_exclude_end    2u
    +#define d2_le_exclude_both   3u
    +#define d2_le_closed         4u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_segmentflags;
    +
    +#define d2_sf_none  0u
    +#define d2_sf_skip  1u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_modeflags;
    +
    +#define d2_mode_alpha8      0u
    +#define d2_mode_rgb565      1u
    +
    +#define d2_mode_argb8888    2u
    +#define d2_mode_argb4444    3u
    +#define d2_mode_argb1555    4u
    +   
    +#define d2_mode_ai44        5u
    +
    +#define d2_mode_rgba8888    6u
    +#define d2_mode_rgba4444    7u
    +#define d2_mode_rgba5551    8u
    +   
    +#define d2_mode_i8          9u
    +#define d2_mode_i4          10u
    +#define d2_mode_i2          11u
    +#define d2_mode_i1          12u
    +   
    +#define d2_mode_alpha4      13u
    +#define d2_mode_alpha2      14u
    +#define d2_mode_alpha1      15u
    +   
    +#define d2_mode_rgb888      64u /* used driver internally */
    +#define d2_mode_rgb444      65u /* used driver internally */
    +#define d2_mode_rgb555      66u /* used driver internally */
    +   
    +   /* following additional flags can be ored together with previous modes: */
    +#define d2_mode_rle         16u     /* RLE decoder is used */
    +#define d2_mode_clut        32u     /* CLUT 256 is used */
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_getcontextmodes;
    +
    +#define d2_context_default   0u
    +#define d2_context_selected  1u
    +#define d2_context_solid     2u
    +#define d2_context_outline   3u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_textureoperations;
    +
    +#define d2_to_zero         0u
    +#define d2_to_one          1u
    +#define d2_to_replace      2u
    +#define d2_to_copy         3u
    +#define d2_to_invert       4u
    +#define d2_to_multiply     5u
    +#define d2_to_invmultiply  6u
    +#define d2_to_blend        7u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_colorchannels;
    +
    +#define d2_cc_alpha   1u
    +#define d2_cc_red     2u
    +#define d2_cc_green   4u
    +#define d2_cc_blue    8u
    +#define d2_cc_rgb    14u
    +#define d2_cc_all    15u
    +#define dc_cc_rgb    d2_cc_rgb /* backward compatibility */ 
    +#define dc_cc_all    d2_cc_all /* backward compatibility */ 
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_texturemodes;
    +
    +#define d2_tm_wrapu     1u
    +#define d2_tm_wrapv     2u
    +#define d2_tm_filteru   4u
    +#define d2_tm_filterv   8u
    +#define d2_tm_filter   12u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_patternmodes;
    +
    +#define d2_pm_filter     1u
    +#define d2_pm_autoalign  2u
    +#define d2_pm_advance    4u
    +#define d2_pm_orthogonal 8u   /* TES unsupported parameter */
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_blitflags;
    +
    +#define d2_bf_filteru           d2_tm_filteru
    +#define d2_bf_filterv           d2_tm_filterv
    +#define d2_bf_filter            d2_tm_filter
    +#define d2_bf_wrapu             d2_tm_wrapu
    +#define d2_bf_wrapv             d2_tm_wrapv
    +#define d2_bf_wrap              (d2_tm_wrapu | d2_tm_wrapv)
    +#define d2_bf_colorize          (d2_bf_filterv * 2)
    +#define d2_bf_usealpha          (d2_bf_colorize * 2)
    +#define d2_bf_colorize2         (d2_bf_usealpha * 2)
    +#define d2_bf_invertalpha       (d2_bf_colorize2 * 2)
    +#define d2_bf_no_blitctxbackup  (d2_bf_invertalpha * 2)
    +#define d2_bf_mirroru           (d2_bf_no_blitctxbackup * 2)
    +#define d2_bf_mirrorv           (d2_bf_mirroru * 2)
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_deviceflags;
    +
    +#define d2_df_no_dlist             1u
    +#define d2_df_no_irq               2u
    +#define d2_df_no_fbcache           4u
    +#define d2_df_no_texcache          8u
    +#define d2_df_no_dwclear          16u
    +#define d2_df_no_registercaching  32u
    +#define d2_df_no_blitctxbackup    64u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +enum d2_perfcountevents
    +{
    +  d2_pc_disable            =  0,
    +  d2_pc_davecycles         =  1,
    +  d2_pc_fbreads            =  2,
    +  d2_pc_fbwrites           =  3,
    +  d2_pc_texreads           =  4,
    +  d2_pc_invpixels          =  5,
    +  d2_pc_invpixels_miss     =  6,
    +  d2_pc_dlrcycles          =  7,
    +  d2_pc_fbreadhits         =  8,
    +  d2_pc_fbreadmisses       =  9,
    +  d2_pc_fbwritehits        = 10,
    +  d2_pc_fbwritemisses      = 11,
    +  d2_pc_texreadhits        = 12,
    +  d2_pc_texreadmisses      = 13,
    +  d2_pc_cpudatareads       = 14,
    +  d2_pc_cpudatawrites      = 15,
    +  d2_pc_cpuinstrreads      = 16,
    +
    +  d2_pc_dlrburstreads      = 17,
    +  d2_pc_dlrwordsread       = 18,
    +
    +  d2_pc_rlerewinds         = 20,
    +  d2_pc_texburstreads      = 21,
    +  d2_pc_texwordsread       = 22,
    +  d2_pc_fbburstreads       = 23,
    +  d2_pc_fbwordsread        = 24,
    +  d2_pc_fbburstwrites      = 25,
    +  d2_pc_fbwordswritten     = 26,
    +
    +  d2_pc_fbrwconflicts      = 28,
    +  d2_pc_fbrwconflictcycles = 29,
    +  d2_pc_noevent            = 30,
    +  d2_pc_clkcycles          = 31
    +};
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_executeflags;
    +
    +#define d2_ef_default           0u
    +#define d2_ef_execute_once      0u
    +#define d2_ef_execute_multiple  1u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_blendflags;
    +
    +#define d2_blendf_default      0u
    +#define d2_blendf_blenddst     0u
    +#define d2_blendf_blendcolor2  1u
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_adddlistflags;
    +
    +#define d2_al_default  0u  /* default behavior                   */
    +#define d2_al_copy     0u  /* content will be copied             */
    +#define d2_al_no_copy  1u  /* jump to the dlist will be added    */
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_busburstlength;
    +
    +#define d2_bbl_1   0u  /* single cycle bus access       */
    +#define d2_bbl_2   1u  /* max bus burst length = 2      */
    +#define d2_bbl_4   2u  /* max bus burst length = 4      */
    +#define d2_bbl_8   3u  /* max bus burst length = 8      */
    +#define d2_bbl_16  4u  /* max bus burst length = 16     */
    +#define d2_bbl_32  5u  /* max bus burst length = 32     */
    +
    +/*---------------------------------------------------------------------------
    + * basic functions */
    +
    +D2_EXTERN d2_s32         d2_getversion( void );
    +D2_EXTERN const d2_char *d2_getversionstring( void );
    +D2_EXTERN d2_device *    d2_opendevice( d2_u32 flags );
    +D2_EXTERN d2_s32         d2_closedevice( d2_device *handle );
    +D2_EXTERN d2_s32         d2_geterror( const d2_device *handle );
    +D2_EXTERN const d2_char *d2_geterrorstring( const d2_device *handle );
    +D2_EXTERN const d2_char *d2_translateerror( d2_s32 errorcode );
    +D2_EXTERN d2_s32         d2_inithw( d2_device *handle, d2_u32 flags );
    +D2_EXTERN d2_s32         d2_deinithw( d2_device *handle );
    +D2_EXTERN d2_s32         d2_inithwburstlengthlimit(d2_device *handle, d2_busburstlength burstlengthFBread, d2_busburstlength burstlengthFBwrite, d2_busburstlength burstlengthTX, d2_busburstlength burstlengthDL);
    +D2_EXTERN d1_device *    d2_level1interface( const d2_device *handle );
    +D2_EXTERN d2_u32         d2_getrevisionhw( const d2_device *handle );
    +D2_EXTERN const d2_char* d2_getrevisionstringhw( const d2_device *handle);
    +D2_EXTERN d2_s32         d2_setdlistblocksize(d2_device *handle, d2_u32 size);
    +D2_EXTERN d2_u32         d2_getdlistblocksize(const d2_device *handle);
    +D2_EXTERN d2_u32         d2_getdlistblockcount(d2_device *handle);
    +D2_EXTERN d2_s32         d2_commandspending(d2_device *handle);
    +D2_EXTERN d2_s32         d2_lowlocalmemmode(d2_device *handle, d2_u32 dlistblockfactor, d2_u32 dlistblocks);
    +
    +/*---------------------------------------------------------------------------
    + * context management */
    +
    +D2_EXTERN d2_context * d2_newcontext( d2_device *handle );
    +D2_EXTERN d2_s32       d2_freecontext( d2_device *handle, d2_context *ctx );
    +D2_EXTERN d2_s32       d2_selectcontext( d2_device *handle, d2_context *ctx );
    +D2_EXTERN d2_s32       d2_solidcontext( d2_device *handle, d2_context *ctx );
    +D2_EXTERN d2_s32       d2_outlinecontext( d2_device *handle, d2_context *ctx );
    +D2_EXTERN d2_context * d2_getcontext( d2_device *handle, d2_s32 mode );
    +
    +/*---------------------------------------------------------------------------
    + * device */
    +
    +D2_EXTERN d2_s32 d2_framebuffer( d2_device *handle, void *ptr, d2_s32 pitch, d2_u32 width, d2_u32 height, d2_s32 format );
    +D2_EXTERN d2_s32 d2_cliprect( d2_device *handle, d2_border xmin, d2_border ymin, d2_border xmax, d2_border ymax );
    +D2_EXTERN d2_s32 d2_flushframe( d2_device *handle );
    +D2_EXTERN d2_s32 d2_startframe( d2_device *handle );
    +D2_EXTERN d2_s32 d2_endframe( d2_device *handle );
    +D2_EXTERN d2_s32 d2_relocateframe( d2_device *handle, const void *ptr );
    +D2_EXTERN d2_s32 d2_clear( d2_device *handle, d2_color color );
    +D2_EXTERN d2_s32 d2_getcliprect( d2_device *handle, d2_border *xmin, d2_border *ymin, d2_border *xmax, d2_border *ymax );
    +D2_EXTERN d2_s32 d2_getframebuffer( d2_device *handle, void** ptr, d2_s32* pitch, d2_u32* width, d2_u32* height, d2_s32* format);
    +
    +/*---------------------------------------------------------------------------
    + * device global attributes */
    +
    +D2_EXTERN d2_s32 d2_selectrendermode( d2_device *handle, d2_u32 mode );
    +D2_EXTERN d2_s32 d2_outlinewidth( d2_device *handle, d2_width width );
    +D2_EXTERN d2_s32 d2_shadowoffset( d2_device *handle, d2_point x, d2_point y );
    +D2_EXTERN d2_u32 d2_getrendermode( const d2_device *handle );
    +D2_EXTERN d2_s32 d2_layermerge( d2_device *handle );
    +
    +/*---------------------------------------------------------------------------
    + * renderbuffer management */
    +
    +D2_EXTERN d2_renderbuffer * d2_newrenderbuffer( d2_device *handle, d2_u32 initialsize, d2_u32 stepsize );
    +D2_EXTERN d2_s32            d2_freerenderbuffer( d2_device *handle, d2_renderbuffer *buffer );
    +D2_EXTERN d2_s32            d2_selectrenderbuffer( d2_device *handle, d2_renderbuffer *buffer );
    +D2_EXTERN d2_s32            d2_executerenderbuffer( d2_device *handle, d2_renderbuffer *buffer, d2_u32 flags );
    +D2_EXTERN d2_renderbuffer * d2_getrenderbuffer( d2_device *handle, d2_s32 index );
    +D2_EXTERN d2_s32            d2_dumprenderbuffer( d2_device *handle, d2_renderbuffer *buffer, void **rdata, d2_s32 *rsize );
    +D2_EXTERN d2_u32            d2_getrenderbuffersize(d2_device *handle, d2_renderbuffer *rb);
    +D2_EXTERN d2_s32            d2_freedumpedbuffer( d2_device *handle, void *data );
    +
    +/*---------------------------------------------------------------------------
    + * context attribute writes */
    +
    +D2_EXTERN d2_s32 d2_setcolor( d2_device *handle, d2_s32 index, d2_color color );
    +D2_EXTERN d2_s32 d2_setalpha( d2_device *handle, d2_alpha alpha );
    +D2_EXTERN d2_s32 d2_setalphaex( d2_device *handle, d2_s32 index, d2_alpha alpha );
    +D2_EXTERN d2_s32 d2_setblur( d2_device *handle, d2_width blur );
    +D2_EXTERN d2_s32 d2_setblendmode( d2_device *handle, d2_u32 srcfactor, d2_u32 dstfactor );
    +D2_EXTERN d2_s32 d2_setalphablendmode( d2_device *handle, d2_u32 srcfactor, d2_u32 dstfactor );
    +D2_EXTERN d2_s32 d2_setalphablendmodeex( d2_device *handle, d2_u32 srcfactor, d2_u32 dstfactor, d2_u32 blendflags );
    +D2_EXTERN d2_s32 d2_setalphagradient( d2_device *handle, d2_s32 index, d2_point x, d2_point y, d2_point dx, d2_point dy );
    +D2_EXTERN d2_s32 d2_setclipgradient( d2_device *handle, d2_s32 index, d2_point x, d2_point y, d2_s32 nx, d2_s32 ny, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_setalphamode( d2_device *handle, d2_u32 mode );
    +D2_EXTERN d2_s32 d2_setantialiasing( d2_device *handle, d2_s32 enable );
    +D2_EXTERN d2_s32 d2_setpatternalpha( d2_device *handle, d2_s32 index, d2_alpha alpha );
    +D2_EXTERN d2_s32 d2_setfillmode( d2_device *handle, d2_u32 mode );
    +D2_EXTERN d2_s32 d2_setpattern( d2_device *handle, d2_pattern pattern );
    +D2_EXTERN d2_s32 d2_setpatternparam( d2_device *handle, d2_point x, d2_point y, d2_width dx, d2_width dy );
    +D2_EXTERN d2_s32 d2_setpatternmode( d2_device *handle, d2_u32 mode );
    +D2_EXTERN d2_s32 d2_setpatternsize( d2_device *handle, d2_s32 size );
    +D2_EXTERN d2_s32 d2_setlinecap( d2_device *handle, d2_u32 mode );
    +D2_EXTERN d2_s32 d2_setlinejoin( d2_device *handle, d2_u32 mode );
    +D2_EXTERN d2_s32 d2_setlinepattern( d2_device *handle, d2_width scale, d2_s32 offset );
    +D2_EXTERN d2_s32 d2_setmiterlimit( d2_device *handle, d2_width miter );
    +D2_EXTERN d2_s32 d2_settexture( d2_device *handle, void *ptr, d2_s32 pitch, d2_s32 width, d2_s32 height, d2_u32 format );
    +D2_EXTERN d2_s32 d2_settexturemode( d2_device *handle, d2_u32 mode );
    +D2_EXTERN d2_s32 d2_settextureoperation( d2_device *handle, d2_u8 amode, d2_u8 rmode, d2_u8 gmode, d2_u8 bmode );
    +D2_EXTERN d2_s32 d2_settexopparam( d2_device *handle, d2_u32 index, d2_u32 p1, d2_u32 p2 );
    +D2_EXTERN d2_s32 d2_settexturemapping( d2_device *handle, d2_point x, d2_point y, d2_s32 u0, d2_s32 v0, d2_s32 dxu, d2_s32 dyu, d2_s32 dxv, d2_s32 dyv );
    +D2_EXTERN d2_s32 d2_settexelcenter( d2_device *handle, d2_point x, d2_point y );
    +D2_EXTERN d2_s32 d2_settexclut( d2_device *handle, d2_color* clut );
    +D2_EXTERN d2_s32 d2_settexclut_part( d2_device *handle, const d2_color* clut_part, d2_u32 start_index, d2_u32 length );
    +D2_EXTERN d2_s32 d2_writetexclut_direct( d2_device *handle, const d2_color* clut_part, d2_u32 start_index, d2_u32 length );
    +D2_EXTERN d2_s32 d2_settexclut_offset( d2_device *handle, d2_u32 offset );
    +D2_EXTERN d2_s32 d2_settexclut_format(  d2_device *handle, d2_u32 format );
    +D2_EXTERN d2_s32 d2_setcolorkey( d2_device *handle, d2_s32 enable, d2_color color_key );
    +D2_EXTERN d2_s32 d2_setcircleextend( d2_device *handle, d2_width offset );
    +
    +/*---------------------------------------------------------------------------
    + * context attritbute reads */
    +
    +D2_EXTERN d2_color d2_getcolor( d2_device *handle, d2_s32 index );
    +D2_EXTERN d2_alpha d2_getalpha( d2_device *handle );
    +D2_EXTERN d2_alpha d2_getalphaex( d2_device *handle, d2_s32 index );
    +D2_EXTERN d2_width d2_getblur( d2_device *handle );
    +D2_EXTERN d2_u32 d2_getblendmodesrc( d2_device *handle );
    +D2_EXTERN d2_u32 d2_getblendmodedst( d2_device *handle );
    +D2_EXTERN d2_u32 d2_getalphablendmodesrc( d2_device *handle );
    +D2_EXTERN d2_u32 d2_getalphablendmodedst( d2_device *handle );
    +D2_EXTERN d2_u8  d2_getalphablendmodeflags( d2_device *handle );
    +D2_EXTERN d2_u8  d2_getalphamode( d2_device *handle );
    +D2_EXTERN d2_s32 d2_getantialiasing( d2_device *handle );
    +D2_EXTERN d2_alpha d2_getpatternalpha( d2_device *handle, d2_s32 index );
    +D2_EXTERN d2_u8  d2_getfillmode( d2_device *handle );
    +D2_EXTERN d2_pattern d2_getpattern( d2_device *handle );
    +D2_EXTERN d2_u32 d2_getpatternmode( d2_device *handle );
    +D2_EXTERN d2_s32 d2_getpatternsize( d2_device *handle );
    +D2_EXTERN d2_u8  d2_getlinecap( d2_device *handle );
    +D2_EXTERN d2_u8  d2_getlinejoin( d2_device *handle );
    +D2_EXTERN d2_u8  d2_gettextureoperationa( d2_device *handle );
    +D2_EXTERN d2_u8  d2_gettextureoperationr( d2_device *handle );
    +D2_EXTERN d2_u8  d2_gettextureoperationg( d2_device *handle );
    +D2_EXTERN d2_u8  d2_gettextureoperationb( d2_device *handle );
    +D2_EXTERN d2_alpha d2_gettexopparam1( d2_device *handle, d2_u32 index );
    +D2_EXTERN d2_alpha d2_gettexopparam2( d2_device *handle, d2_u32 index );
    +
    +/*---------------------------------------------------------------------------
    + * rendering commands */
    +
    +D2_EXTERN d2_s32 d2_renderbox( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h );
    +D2_EXTERN d2_s32 d2_renderline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_rendertri( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderquad( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_rendercircle( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w );
    +D2_EXTERN d2_s32 d2_renderwedge( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderline2(  d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderpolyline( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline2( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_rendertrilist( d2_device *handle, const d2_point *data, const d2_u32 *flags, d2_u32 count);
    +D2_EXTERN d2_s32 d2_rendertrifan( d2_device *handle, const d2_point *data, const d2_u32 *flags, d2_u32 count);
    +D2_EXTERN d2_s32 d2_rendertristrip( d2_device *handle, const d2_point *data, const d2_u32 *flags, d2_u32 count);
    +D2_EXTERN d2_s32 d2_renderpolygon( d2_device *handle, const d2_point *data, d2_u32 count, d2_u32 flags);
    +
    +/*---------------------------------------------------------------------------
    + * blit attributes write */
    +
    +D2_EXTERN d2_s32 d2_setblitsrc( d2_device *handle, void *ptr, d2_s32 pitch, d2_s32 width, d2_s32 height, d2_u32 format );
    +
    +/*---------------------------------------------------------------------------
    + * blit rendering functions */
    +
    +D2_EXTERN d2_s32 d2_blitcopy( d2_device *handle, d2_s32 srcwidth, d2_s32 srcheight, d2_blitpos srcx, d2_blitpos srcy, d2_width dstwidth, d2_width dstheight, d2_point dstx, d2_point dsty, d2_u32 flags );
    +
    +/*---------------------------------------------------------------------------
    + * performance measurement */
    +D2_EXTERN d2_s32 d2_setperfcountevent( d2_device *handle, d2_u32 counter, d2_u32 event );
    +D2_EXTERN d2_s32 d2_setperfcountvalue( d2_device *handle, d2_u32 counter, d2_slong value );
    +D2_EXTERN d2_slong d2_getperfcountvalue( d2_device *handle, d2_u32 counter );
    +
    +/*---------------------------------------------------------------------------
    + * Utility Functions */
    +
    +d2_s32 d2_utility_maptriangle    ( d2_device *handle, const d2_f32 *points, const d2_f32 *uvs );
    +d2_s32 d2_utility_perspectivewarp( d2_device *handle, d2_u16 srcwidth, d2_u16 srcheight, d2_s16 srcx, d2_s16 srcy, d2_s16 dstwidth, d2_s16 dstheight, d2_s16 dstx, d2_s16 dsty, d2_u16 wt );
    +d2_s32 d2_utility_fbblitcopy     ( d2_device *handle, d2_u16 width, d2_u16 height, d2_blitpos srcx, d2_blitpos srcy, d2_blitpos dstx, d2_blitpos dsty, d2_u32 flags);
    +void d2_rendercircle_no_hilimiterprecision( d2_device *handle, d2_u32 flag );
    +
    +
    +
    +/*---------------------------------------------------------------------------
    + * Dlist Functions */
    +
    +d2_s32 d2_executedlist( d2_device *handle, const void *address, d2_u32 flags );
    +d2_s32 d2_adddlist( d2_device *handle, void *address, d2_s32 size, d2_u32 flags );
    +
    +/*---------------------------------------------------------------------------
    + * assign errorcode IDs */
    +
    +#define ERR(x,y) x,
    +enum d2_errorcodes {
    +#include "dave_errorcodes.h"
    +D2_ERROR_QUANTITY };
    +#undef ERR
    +
    +/*---------------------------------------------------------------------------
    + * include header files of level0 and level1 driver */
    +
    +#include "dave_base.h"
    +#include "dave_math.h"
    +
    +/*---------------------------------------------------------------------------
    +* define feature bits of hardware revision */
    +#ifndef BIT
    +#define BIT(x)                         (1u<<(x))
    +#endif
    +#define D2FB_SWDAVE                    BIT(16)
    +#define D2FB_DLR                       BIT(17)
    +#define D2FB_FBCACHE                   BIT(18)
    +#define D2FB_TXCACHE                   BIT(19)
    +#define D2FB_PERFCOUNT                 BIT(20)
    +#define D2FB_TEXCLUT                   BIT(21)
    +#define D2FB_FBPREFETCH                BIT(22)
    +#define D2FB_RLEUNIT                   BIT(23)
    +#define D2FB_TEXCLUT256                BIT(24)
    +#define D2FB_COLORKEY                  BIT(25)
    +#define D2FB_HILIMITERPRECISION        BIT(26)
    +#define D2FB_ALPHACHANNELBLENDING      BIT(27)
    +
    +/*--------------------------------------------------------------------------- */
    +#ifdef __cplusplus
    +}
    +#endif
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_edge.h b/src/drivers/dave2d/include/dave_edge.h
    new file mode 100644
    index 000000000..a2805098e
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_edge.h
    @@ -0,0 +1,72 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_edge.h (%version: 14 %)
    + *          created Mon Jan 31 18:40:01 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jan 04 13:51:46 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2010-09-28 MRe  use 64bit arithmetic for blurring calculation
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_edge_h_H
    +#define __1_dave_edge_h_H
    +/*-------------------------------------------------------------------------- */
    +
    +/*--------------------------------------------------------------------------
    + * line length may not be zero.
    + * */
    +D2_EXTERN void d2_lineedge_setup3blur_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 flags, const d2_contextdata *ctx, d2_s32 *length );
    +
    +
    +/*--------------------------------------------------------------------------
    + * line length may not be zero.
    + * */
    +D2_EXTERN void d2_lineedge_setup3sqrt_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 flags, d2_s32 *length );
    +
    +
    +/*--------------------------------------------------------------------------
    + * note use for thin lines (w<2) only (due to l1 norm approximation)
    + * line length may not be zero.
    + * */
    +D2_EXTERN void d2_lineedge_setup3_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 flags, d2_s32 *length );
    +
    +
    +/*--------------------------------------------------------------------------
    + * edge deltas may not both be zero. centering of start value (+0.5) is
    + * omitted here. this was necessary to allow highler level to change center
    + * for non shared edges.
    + * */
    +D2_EXTERN void d2_triedge_setup_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 rightedge );
    +
    +/*--------------------------------------------------------------------------
    + * note should use sqrtsetup when bluring long distance
    + * edge deltas may not both be zero.
    + * */
    +D2_EXTERN void d2_triedge_setupblur_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, const d2_contextdata *ctx );
    +
    +
    +/*--------------------------------------------------------------------------
    + * warning: will overflow earlier than aa version. might blow 11bit border
    + * edge deltas may not both be zero.
    + * */
    +D2_EXTERN void d2_triedge_setupnoaa_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_s32 rightedge );
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +D2_EXTERN void d2_triedge_setupsqrt_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_s32 rightedge );
    +
    +
    +/*--------------------------------------------------------------------------
    + * used to setup bottom-up rendering
    + * */
    +D2_EXTERN void d2_invertlimiter_intern(d2_limdata *lim, d2_s32 ystep);
    +
    +
    +/*-------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_errorcodes.h b/src/drivers/dave2d/include/dave_errorcodes.h
    new file mode 100644
    index 000000000..1825fe552
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_errorcodes.h
    @@ -0,0 +1,72 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_errorcodes.h (%version: 9 %)
    + *          created Tue Jan 11 13:41:35 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Feb 19 15:59:15 2007 %  (%derived_by:  hh74036 %)
    + *
    + * Changes:
    + * 2007-08-31 ASc  - removed tabs, changed C++ to C comments,
    + *-------------------------------------------------------------------------- */
    +
    +/* Title: Errorcodes
    + * List of all dave driver errorcodes.
    + *
    + * Every device stores the errorcode returned by the last function executed
    + * for this device. Successfull operations reset this code to D2_OK.
    + *
    + * Latest errorcode can be queried by <d2_geterror> / <d2_geterrorstring> functions
    + *
    + * Errorcodes:
    + *
    + *   D2_OK - success
    + *   D2_NOMEMORY - memory allocation failed
    + *   D2_INVALIDDEVICE - invalid device
    + *   D2_INVALIDCONTEXT - invalid rendering context
    + *   D2_INVALIDBUFFER - invalid renderbuffer context
    + *   D2_HWINUSE   - hardware device already in use
    + *   D2_DEVASSIGNED - device already assigned
    + *   D2_DEFCONTEXT - cannot operate on default context
    + *   D2_INVALIDINDEX - index is out of bounds
    + *   D2_ILLEGALMODE  - rendermode not supported
    + *   D2_INVALIDWIDTH - width out of legal range
    + *   D2_INVALIDHEIGHT - height out of legal range
    + *   D2_NOVIDEOMEM - illegal framebuffer address
    + *   D2_VALUETOOSMALL - parameter too close to zero
    + *   D2_VALUENEGATIVE - parameter is negative
    + *   D2_VALUETOOBIG - parameter value is too large
    + *   D2_INVALIDENUM  - unsupported mode
    + *   D2_NULLPOINTER  - source pointer may not be null
    + *   D2_DEVICEBUSY - operation cannot execute while hardware is busy
    + *   D2_DEFBUFFER -  cannot operate on default buffer
    + *   D2_NO_DISPLAYLIST  - usage of displaylists a mandatory in d2_low_localmemmode
    + *   D2_NOT_ENOUGH_DLISTBLOCKS - amount of displaylist blocks as specified in <d2_lowlocalmemmode> is not sufficient
    + * */
    +
    +/*--------------------------------------------------------------------------- */
    +
    +   ERR(  D2_OK                      , "success" )
    +   ERR(  D2_NOMEMORY                , "memory allocation failed" )
    +   ERR(  D2_INVALIDDEVICE           , "invalid device" )
    +   ERR(  D2_INVALIDCONTEXT          , "invalid rendering context" )
    +   ERR(  D2_INVALIDBUFFER           , "invalid renderbuffer context" )
    +   ERR(  D2_HWINUSE                 , "hardware device already in use" )
    +   ERR(  D2_DEVASSIGNED             , "device already assigned" )
    +   ERR(  D2_DEFCONTEXT              , "cannot operate on default context" )
    +   ERR(  D2_INVALIDINDEX            , "index is out of bounds" )
    +   ERR(  D2_ILLEGALMODE             , "rendermode not supported" )
    +   ERR(  D2_INVALIDWIDTH            , "width out of legal range" )
    +   ERR(  D2_INVALIDHEIGHT           , "height out of legal range" )
    +   ERR(  D2_NOVIDEOMEM              , "illegal framebuffer address" )
    +   ERR(  D2_VALUETOOSMALL           , "parameter too close to zero" )
    +   ERR(  D2_VALUENEGATIVE           , "parameter is negative" )
    +   ERR(  D2_VALUETOOBIG             , "parameter value is too large" )
    +   ERR(  D2_INVALIDENUM             , "unsupported mode" )
    +   ERR(  D2_NULLPOINTER             , "source pointer may not be null" )
    +   ERR(  D2_DEVICEBUSY              , "operation cannot execute while hardware is busy" )
    +   ERR(  D2_DEFBUFFER               , "cannot operate on default buffer" )
    +   ERR(  D2_NO_DISPLAYLIST          , "d2_df_no_dlist is not supported in low_localmemmode")
    +   ERR(  D2_NOT_ENOUGH_DLISTBLOCKS  , "not enough dlistblocks. please adjust in d2_lowlocalmemmode(...)")
    +
    +/*--------------------------------------------------------------------------- */
    diff --git a/src/drivers/dave2d/include/dave_gradient.h b/src/drivers/dave2d/include/dave_gradient.h
    new file mode 100644
    index 000000000..440dbe806
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_gradient.h
    @@ -0,0 +1,47 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_gradient.h (%version: 6 %)
    + *          created Mon Jan 24 13:14:23 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jul 13 18:25:49 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_gradient_h_H
    +#define __1_dave_gradient_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_u32 d2_gradient_modes;
    +
    +#define d2_grad_none        0u
    +#define d2_grad_linear      1u
    +#define d2_grad_circular    2u
    +#define d2_grad_threshold   4u
    +#define d2_grad_rightedge   8u
    +#define d2_grad_offset     16u
    +#define d2_grad_aapattern  32u
    +#define d2_grad_concave    64u
    +
    +/*---------------------------------------------------------------------------
    + * Gradient structure */
    +
    +typedef struct _d2_gradientdata
    +{
    +   d2_u32   mode;
    +   d2_s32   xadd;
    +   d2_s32   yadd;
    +   d2_s32   xadd2;
    +   d2_s32   yadd2;
    +   d2_point x1,y1;
    +} d2_gradientdata;
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN void d2_initgradient_intern( d2_gradientdata *grad );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_hardware.h b/src/drivers/dave2d/include/dave_hardware.h
    new file mode 100644
    index 000000000..411605a1e
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_hardware.h
    @@ -0,0 +1,35 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_hardware.h (%version: 6 %)
    + *          created Tue Jan 11 14:52:38 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Aug 30 16:02:19 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_hardware_h_H
    +#define __1_dave_hardware_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d1_device * d2hw_acquire( d2_device *handle, d2_u32 flags );
    +D2_EXTERN d2_s32 d2hw_release( d1_device * hwid );
    +
    +D2_EXTERN void d2hw_set(d1_device * hwid, d2_u32 index, d2_s32 value);
    +D2_EXTERN d2_s32 d2hw_get(d1_device * hwid, d2_u32 index);
    +
    +D2_EXTERN void d2hw_wait(d1_device * hwid);
    +
    +/*--------------------------------------------------------------------------- */
    +
    +/* return after rendering has finished */
    +D2_EXTERN void d2hw_finish(const d2_device *handle);
    +
    +/* start rendering primitives */
    +D2_EXTERN void d2hw_start(d2_device *handle, const d2_dlist *dlist, d2_s32 startnoblk);
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_intern.h b/src/drivers/dave2d/include/dave_intern.h
    new file mode 100644
    index 000000000..afba1bae9
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_intern.h
    @@ -0,0 +1,335 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_intern.h (%version: 29 %)
    + *          created Tue Jan 11 12:57:48 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jan 25 18:12:54 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + *  2005-12-22 CSe  removed transfermode field, added flags field in _d2_devicedata
    + *  2006-02-16 CSe  added performance counter support
    + *  2006-10-30 CSe  removed waitdlist flag
    + *  2006-11-07 CSe  removed waitdlist flag
    + *  2006-11-07 CSe  added dlist_buffer to device struct for 'd2_df_low_localmem' mode
    + *  2007-01-26 CSe  made 'low localmem' mode configurable
    + *  2007-05-23 MGe  added delayed_errorcode to context
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2008-11-24 AJ   Added support for IAR compiler
    + *  2011-09-05 MRe  added cr2 register to device structure
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_intern_h_H
    +#define __1_dave_intern_h_H
    +/*---------------------------------------------------------------------------
    + * define inline modifier if available */
    +#ifdef _MSC_VER
    +#define D2_INLINE __forceinline
    +#else
    +#ifdef __CA850__
    +#define D2_INLINE
    +#elif defined(__ICCV850__)
    +#define D2_INLINE _Pragma("inline")
    +#else
    +#define D2_INLINE inline
    +#endif
    +#endif
    +
    +/*---------------------------------------------------------------------------
    + * define null to become independent of stdlib */
    +#ifndef NULL
    +#ifdef __cplusplus
    +#define NULL    0
    +#else
    +#define NULL    ((void *)0)
    +#endif
    +#endif
    +
    +/*---------------------------------------------------------------------------
    + * internally used types */
    +
    +#ifdef _MSC_VER
    +typedef __int64 d2_int64;
    +#elif (defined(__CA850__) || defined(__ICC850__))
    +#define _NO_LL_
    +typedef struct {
    +   d2_u32 low32;
    +   d2_s32 high32;
    +} d2_int64;
    +#else
    +typedef long long d2_int64;
    +#endif
    +
    +/*---------------------------------------------------------------------------
    + * use separate context for blit 
    + see also d2_df_no_blitctxbackup and d2_bf_no_blitctxbackup*/
    +
    +/*
    +#define D2_USEBLITBACKUPCONTEXT 
    +*/
    +
    +
    +/*---------------------------------------------------------------------------
    + * force register cache usage
    + see also d2_df_no_registercaching */
    +
    +#define D2_USEREGCACHE 
    +
    +/*---------------------------------------------------------------------------
    + * set initial size of list of dlist start address */
    +
    +#define DLIST_ADRESSES_NUMBER 16
    +
    +
    +/*---------------------------------------------------------------------------
    + * Register Cache */
    +
    +#include "dave_registermap.h"
    +
    +typedef struct _d2_cacheddata
    +{
    +   d2_s32    data[  D2_QUANTITY ];
    +   d2_s8     valid[ D2_QUANTITY ];
    +} d2_cacheddata;
    +
    +#ifdef D2_USEREGCACHE
    +D2_EXTERN const d2_u8 d2_cacheableregs[D2_QUANTITY];
    +#endif
    +
    +typedef void (*d2_fp_scratchfull)( void *handle );
    +
    +/*--------------------------------------------------------------------------- */
    +#include "dave_base.h"
    +#include "dave_dlist.h"
    +#include "dave_rbuffer.h"
    +#include "dave_hardware.h"
    +#include "dave_context.h"
    +#include "dave_math.h"
    +
    +/*---------------------------------------------------------------------------
    + * use higher precision of qlimiters */
    +
    +#define LIMITER_HIPRECISION 6 
    +
    +
    +/*---------------------------------------------------------------------------
    + * These helper macros are used to stringify a given macro */
    +#define D2_STR(s)           # s
    +#define D2_XSTR(s)          D2_STR(s)  /* PRQA S 3453 */ /* $Misra: #MISRA_BUG_MACRO_HASH $*/
    +
    +
    +/*---------------------------------------------------------------------------
    + * Define the D2_VERSION and D2_VERSION_STRING macros */
    +
    +/* Build up the D2_VERSION macro */
    +#define D2_VERSION ((D2_VERSION_BRANCH << 24) | (D2_VERSION_MAJOR << 16) | D2_VERSION_MINOR )
    +
    +/* Create the D2_VERSION_STRING macro */
    +#define D2_VERSION_STRING  D2_VERSION_BRANCH_STRING " V" D2_XSTR(D2_VERSION_MAJOR) "." D2_XSTR(D2_VERSION_MINOR)
    +
    +/*---------------------------------------------------------------------------
    + * Internal device structure */
    +
    +typedef struct _d2_devicedata
    +{
    +   struct _d2_devicedata *next;        /* to chain devices [must be index 0] */
    +
    +   d2_dlist *readlist;                 /* read (executing) dlist */
    +   d2_dlist *writelist;                /* write (under construction) dlist */
    +   d2_rbuffer *selectedbuffer;         /* currently selected renderbuffer */
    +   d2_rbuffer *renderbuffer[2];        /* default renderbuffers */
    +
    +   d1_device      *hwid;               /* lowlevel access handle */
    +   d2_contextdata *ctxchain;           /* context chain (list of all contexts for this device) */
    +   d2_contextdata *ctxdef;             /* default context (cannot be removed by application) */
    +   d2_contextdata *ctxselected;        /* selected context (used as target of context write/read ops) */
    +   d2_contextdata *ctxsolid;           /* solid context (used as source for rendering solid geometry) */
    +   d2_contextdata *ctxoutline;         /* outline context (used as source for rendering outlines) */
    +#ifdef D2_USEBLITBACKUPCONTEXT
    +   d2_contextdata *blitcontext;        /* internal context used only for blits */
    +#else
    +   d2_contextdata_backup *blitcontext_b; /* internal context backup used only for blits */
    +#endif
    +   d2_contextdata *srccontext;         /* last context that acted as source for display list (for dirtybit checks) */
    +   d2_color       *srcclut;            /* last clut that was loaded  */
    +
    +   void *   framebuffer;               /* rendering baseaddress */
    +   d2_s32   pitch, bpp;                /* framebuffer pitch and bytes per pixel */
    +   d2_s32   fbformat;                  /* framebuffer format */
    +   d2_u32   fbwidth,fbheight;          /* framebuffer size */
    +   d2_u32   fbstylemask;               /* dave ctrl1 bitmask for framebuffer format */
    +   d2_u32   cr2;                       /* control register 2 */
    +
    +   d2_u32   cachectlmask;              /* dave cache ctrl register bitmask */
    +   d2_u32   perftriggermask;           /* dave performance counter trigger source register bitmask */
    +
    +   d2_u32   rendermode;                /* see 'enum d2_rendermodes' */
    +   d2_u32   flags;                     /* see 'enum d2_deviceflags' */
    +   d2_width outlinewidth;
    +   d2_point soffx, soffy;
    +   d2_point clipxmin, clipymin;
    +   d2_point clipxmax, clipymax;
    +
    +   d2_lowlocalmem_mode *lowlocalmem_mode;       /* only used in 'low localmem' mode */
    +
    +   d2_u32 hwrevision;
    +   d2_u32 hwmemarchitecture;
    +
    +   d2_u32 dlistblocksize;              /* specify number of entries to grow when dlist is full */
    +#ifdef D2_USEREGCACHE
    +   d2_cacheddata cache;                 /* register cache for this device */
    +#endif
    +   /* display list assembly buffer */
    +   d2_dlist_scratch_entry *dlscratch_base;
    +   d2_dlist_scratch_entry *dlscratch_pos;
    +   d2_s32                  dlscratch_cnt;
    +   d2_fp_scratchfull       dlscratch_hook;
    +
    +   d2_s8   lasttextwasrle;               /* last texture format was RLE */
    +   d2_s8   maxpatlen;                    /* maximum size of pattern bitvector supported by the hardware */
    +   d2_s8   errorcode;                    /* last actions detaild result code */
    +   d2_s8   delayed_errorcode;            /* errorcondition that exists until the renderbuffer gets executed. This errorcode is used for errors that occure while the scratchbuffer is written to the displaylist */
    +   d2_s8   hilimiterprecision_supported; /* is set to 1 when the hilimiterprecision feature is supported by the hardware */
    +
    +   d2_s8   dlist_indirect_supported;     /* is set to 1 when lists of dlist addresses are supported by d1 driver */
    +   d2_s32* dlist_list_single[2];         /* for d2_executedlist we need an extra dlist list with just one entry   */
    +
    +} d2_devicedata;
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef struct _d2_bbox
    +{
    +   d2_point xmin, ymin;
    +   d2_point xmax, ymax;
    +} d2_bbox;
    +
    +typedef struct _d2_limdata
    +{
    +   d2_s32 start;
    +   d2_s32 xadd;
    +   d2_s32 yadd;
    +} d2_limdata;
    +
    +/*---------------------------------------------------------------------------
    + * Internal flags */
    +
    +typedef d2_u32 d2_lineendflags_intern;
    +
    +#define d2_lei_base                256u
    +
    +#define d2_lei_ext_first_edge     (d2_lei_base *  2)
    +#define d2_lei_ext_last_edge      (d2_lei_base *  4)
    +#define d2_lei_buffer_first_edge  (d2_lei_base *  8)
    +#define d2_lei_buffer_last_edge   (d2_lei_base * 16)
    +#define d2_lei_miter_edge         (d2_lei_base * 32)
    +#define d2_lei_miter1_flip        (d2_lei_base * 64)
    +#define d2_lei_miter2_flip        (d2_lei_base *128)
    +
    +/*---------------------------------------------------------------------------
    + * Internal macros */
    +
    +#define D2_DEV(d)           ((d2_devicedata *) (d))           /* PRQA S 3453 */ /* $Misra: #MACRO_TYPECAST_OVERKILL $*/
    +#define D2_CTX(c)           ((d2_contextdata *) (c))          /* PRQA S 3453 */ /* $Misra: #MACRO_TYPECAST_OVERKILL $*/
    +#define D2_FNC(r)           ((d2_renderfunctions *) (r))      /* PRQA S 3453 */ /* $Misra: #MACRO_TYPECAST_OVERKILL $*/
    +#define D2_DRB(r)           ((d2_rbuffer *) (r))              /* PRQA S 3453 */ /* $Misra: #MACRO_TYPECAST_OVERKILL $*/
    +
    +static D2_INLINE d2_s32 d2_seterr(d2_device *handle, d2_s32 err); /* to satisfy MISRA rule 3450 */
    +static D2_INLINE d2_s32 d2_seterr(d2_device *handle, d2_s32 err) /* PRQA S 3219, 3480 */ /* $Misra: #UTIL_INLINE_FUNC $*/
    +{
    +   D2_DEV(handle)->errorcode = (d2_s8)(err);
    +
    +   return err;
    +}
    +
    +#define D2_SETERR(d,e)      d2_seterr(d, e)                   /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_SETOK(d)         D2_SETERR(d, D2_OK)               /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_RETERR(d,e)      return D2_SETERR(d,e)             /* PRQA S 3453 */ /* $Misra: #MISRA_BUG_MACRO_RETURN_STATEMENT $*/ /* PRQA S 3412 */ /* $Misra: #MACRO_RETURN $*/
    +#define D2_RETERRU(d,e)     return (d2_u32) (D2_SETERR(d,e))  /* PRQA S 3412 */ /* $Misra: #MACRO_RETURN $*/
    +#define D2_RETOK(d)         return D2_SETOK(d)                /* PRQA S 3412 */ /* $Misra: #MACRO_RETURN $*/
    +
    +#ifdef _DEBUG
    +#define D2_VALIDATE(x,e)    if (0 == (x)) \
    +   {                                      \
    +      return (e);                         \
    +   }(void)0                                                   /* PRQA S 3412 */ /* $Misra: #COMPILER_WARNING $*/
    +#define D2_CHECKERR(x,e)    if (! (x))    \
    +   {                                      \
    +      D2_RETERR(handle, (e));             \
    +   }(void)0                                                   /* PRQA S 3412 */ /* $Misra: #COMPILER_WARNING $*/
    +#define D2_VALIDATEP(x,e)   if (0 == (x)) \
    +   {                                      \
    +      return 0;                           \
    +   }(void)0                                                   /* PRQA S 3412 */ /* $Misra: #COMPILER_WARNING $*/
    +#define D2_CHECKERRP(x,e)   if (! (x)) \
    +   {                                   \
    +      (void)D2_SETERR(handle, (e));    \
    +      return 0;                        \
    +   } (void)0                                                  /* PRQA S 3412 */ /* $Misra: #COMPILER_WARNING $*/
    +#define D2_CHECKRANGE( v, min, max ) if( ((min) > (v)) || ( (v) > (max)) ) \
    +   {                                                                       \
    +      (void)D2_SETERR( handle, D2_INVALIDINDEX);                           \
    +      return D2_INVALIDINDEX;                                              \
    +   }(void)0                                                   /* PRQA S 3412 */ /* $Misra: #COMPILER_WARNING $*/
    +#else
    +#define D2_VALIDATE(x,e)(void)0              /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#define D2_CHECKERR(x,e)(void)0              /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#define D2_VALIDATEP(x,e)(void)0             /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#define D2_CHECKERRP(x,e)(void)0             /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#define D2_CHECKRANGE( v, min, max )(void)0  /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#endif
    +
    +D2_EXTERN void d2_cast32to64(d2_s32 par, d2_int64 *res);
    +D2_EXTERN d2_s32  d2_cast64to32(const d2_int64 *par);
    +D2_EXTERN void d2_add64(const d2_int64 *a, const d2_int64 *b, d2_int64 *res);
    +D2_EXTERN void d2_sub64(const d2_int64 *a, const d2_int64 *b, d2_int64 *res);
    +D2_EXTERN void d2_mul3232to64(d2_s32 a, d2_s32 b, d2_int64 *res);
    +D2_EXTERN void d2_mul3264(d2_s32 a, d2_int64 *b, d2_int64 *res);
    +D2_EXTERN void d2_div6432(const d2_int64 *dividend, d2_s32 divisor, d2_int64 *res);
    +D2_EXTERN void d2_shiftleft64(const d2_int64 *var, d2_s32 index, d2_int64 *res);
    +D2_EXTERN void d2_shiftright64(const d2_int64 *var, d2_s32 index, d2_int64 *res);
    +
    +#ifdef _NO_LL_
    +#define D2_CAST32TO64(PAR, RES)    d2_cast32to64(PAR, RES)     /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_CAST64TO32(PAR)         d2_cast64to32(PAR)          /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_ADD64(A, B, RES)        d2_add64(A, B, RES)         /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_SUB64(A, B, RES)        d2_sub64(A, B, RES)         /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_MUL3232TO64(A, B, RES)  d2_mul3232to64(A, B, RES)   /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_MUL3264(A, B, RES)      d2_mul3264(A, B, RES)       /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_DIV6432(DVD, DVS, RES)  d2_div6432(DVD, DVS, RES)   /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_SHIFTLEFT64(V, I, RES)  d2_shiftleft64(V, I, RES)   /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#define D2_SHIFTRIGHT64(V, I, RES) d2_shiftright64(V, I, RES)  /* PRQA S 3453 */ /* $Misra: #MACRO_FXN_FORWARD $*/
    +#else
    +#define D2_CAST32TO64(PAR, RES)    *(RES) = (PAR)              /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_CAST64TO32(PAR)         ((d2_s32)*(PAR))            /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_ADD64(A, B, RES)        *(RES) = (*(A)) + (*(B))    /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_SUB64(A, B, RES)        *(RES) = (*(A)) - (*(B))    /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_MUL3232TO64(A, B, RES)  *(RES) = ((A)) * (*(B))     /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_MUL3264(A, B, RES)      *(RES) = ((A)) * (*(B))     /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_DIV6432(DVD, DVS, RES)  *(RES) = (*(DVD)) / ((DVS)) /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_SHIFTLEFT64(V, I, RES)  *(RES) = ((*(V)) << (I))    /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#define D2_SHIFTRIGHT64(V, I, RES) *(RES) = ((*(V)) >> (I))    /* PRQA S 3453 */ /* $Misra: #MACRO_TYPE_SAFE_FXN_REPL $*/
    +#endif
    +
    +
    +/*---------------------------------------------------------------------------
    + * Display List entry macro (moved from dlist.h because of include dependencies) */
    +
    +static D2_INLINE void d2_add2dlist_intern( d2_devicedata *handle, d2_u32 regIdx, d2_s32 value )  /* PRQA S 3450, 3480, 3219 */ /* $Misra: #UTIL_INLINE_FUNC $*/
    +{
    +   d2_dlist_scratch_entry *entry = handle->dlscratch_pos;
    +
    +   entry->reg   = regIdx;
    +   entry->value = value;
    +
    +   handle->dlscratch_pos++;
    +   handle->dlscratch_cnt--;
    +   if(handle->dlscratch_cnt <= 0)
    +   {
    +      handle->dlscratch_hook( (d2_device*) handle );
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_line.h b/src/drivers/dave2d/include/dave_line.h
    new file mode 100644
    index 000000000..c09a0ede9
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_line.h
    @@ -0,0 +1,54 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_line.h (%version: 8 %)
    + *          created Mon Jan 31 16:49:01 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Mar 17 11:23:54 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2011-01-20 SSt  made lines and polylines thread safe (eliminated globals)
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_line_h_H
    +#define __1_dave_line_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_renderline_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags, d2_limdata *edge_buffer, d2_bbox *edge_bbox, const d2_s32 *connectors );
    +
    +D2_EXTERN d2_s32 d2_renderline2_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags, d2_limdata *edge_buffer, d2_bbox *edge_bbox );
    +
    +D2_EXTERN d2_s32 d2_renderlinedot_intern( d2_devicedata *handle, const d2_contextdata *ctx, d2_point x, d2_point y, d2_width w, d2_u32 edges, const d2_limdata *edge_buffer, const d2_bbox *edge_bbox );
    +
    +D2_EXTERN d2_s32 d2_renderline_intern_split( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags, d2_limdata *edge_buffer, d2_bbox *edge_bbox, const d2_s32 *connectors );
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_renderline_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline_outline_I( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags );
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_renderline2_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline2_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline2_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline2_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_renderline2_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_math.h b/src/drivers/dave2d/include/dave_math.h
    new file mode 100644
    index 000000000..afed0a7e6
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_math.h
    @@ -0,0 +1,111 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_math.h (%version: 4 %)
    + *          created Thu Jan 13 09:41:58 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jul 14 14:56:48 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2007-08-29 ASc  - remove tabs, add ndoc comments, change C++ to C comments
    + *  2007-12-06 ASc  - fixed macro name in description of D2_FIX4
    + *-------------------------------------------------------------------------- */
    +
    +/*--------------------------------------------------------------------------
    + * Title: Math Functions
    + * Package of useful macros and functions e.g. for fixedpoint operations.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +
    +#ifndef __1_dave_math_h_H
    +#define __1_dave_math_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +
    +
    +/* Group: Fixedpoint Macros */
    +
    +
    +/* Function: D2_FIX4(x) 
    + * Integer to n:4 fixedpoint conversion */
    +#define D2_FIX4(x)      ((x) << 4)                          /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +                 
    +/* Macro: D2_INT4(x) 
    + * n:4 to integer conversion  */
    +#define D2_INT4(x)      ((x) >> 4)                          /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +/* Macro: D2_FLOOR4(x)
    + * n:4 fixedpoint unsigned floor (round towards -inf) */
    +#define D2_FLOOR4(x)    (((d2_u32)(x)) & ~15u)                
    +
    +/* Macro: D2_CEIL4(x)
    + * n:4 fixedpoint unsigned ceil (round towards +inf) */
    +#define D2_CEIL4(x)     ((((d2_u32)(x)) + 15u) & ~15u)
    +
    +/* Macro: D2_FRAC4(x)
    + * n:4 fixedpoint fractional part only */
    +#define D2_FRAC4(x)     (((d2_u32)(x)) & 15u)
    +
    +/* Macro: D2_FIX16(x)
    + * integer to n:16 fixedpoint conversion */
    +#define D2_FIX16(x)     ((x) << 16)                         /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +/* Macro: D2_INT16(x)
    +n:16 to integer conversion */
    +#define D2_INT16(x)     ((x) >> 16)                         /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +/* Macro: D2_FLOOR16(x)
    + * n:16 fixedpoint unsigned floor (round towards -inf) */
    +#define D2_FLOOR16(x)   (((d2_u32)(x)) & ~65535u)
    +
    +/* Macro: D2_CEIL16(x)
    + * n:16 fixedpoint unsigned ceil (round towards +inf) */
    +#define D2_CEIL16(x)    ((((d2_u32)(x)) + 65535u) & ~65535u)
    +
    +/* Macro: D2_FRAC16(x)
    + * n:16 fixedpoint fractional part only */
    +#define D2_FRAC16(x)    (((d2_u32)(x)) & 65535u)
    +
    +/* Macro: D2_EPSILON
    + * Smallest representable positive number (all fixedpoint formats) */
    +#define D2_EPSILON      1                          
    +
    +/*--------------------------------------------------------------------------- */
    +
    +
    +/* Group: Math Functions */
    +
    +/*--------------------------------------------------------------------------
    + * Function: d2_sqrt
    + * Minimalistic 32->16 bit integer square root (no hw divide/multiply needed)
    + * unrolled for speed.
    + *
    + * parameters:
    + *   x - fixedpoint number
    + *
    + * returns:
    + *   the square root of x
    + *
    + * */
    +D2_EXTERN d2_s32 d2_sqrt(d2_u32 x);
    +
    +
    +/*--------------------------------------------------------------------------
    + * Function: d2_pow2mask
    + * Find next larger power of two minus 1
    + *
    + * E.g. given number x=73 -> next larger power of two is 128,
    + * the result is 128 minus 1 = 127 (number with all bits set)
    + *
    + * parameters:
    + *   x - positive number
    + *
    + * returns:
    + *   the next larger number of two minus 1 of x
    + *
    + * */
    +D2_EXTERN d2_u32 d2_pow2mask(d2_u32 x);
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_memory.h b/src/drivers/dave2d/include/dave_memory.h
    new file mode 100644
    index 000000000..143873499
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_memory.h
    @@ -0,0 +1,28 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_memory.h (%version: 5 %)
    + *          created Tue Jan 11 13:12:00 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jan 04 10:37:31 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_memory_h_H
    +#define __1_dave_memory_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +
    +D2_EXTERN void *d2_getmem_p( d2_u32 size );
    +D2_EXTERN void *d2_reallocmem_p( d2_u32 newsize, void *oldadr, d2_s32 keep );
    +D2_EXTERN void d2_freemem_p( void *adr );
    +
    +D2_EXTERN void *d2_getmem_d( const d2_device *handle, d2_u32 size );
    +D2_EXTERN void d2_freemem_d( const d2_device *handle, void *adr );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_pattern.h b/src/drivers/dave2d/include/dave_pattern.h
    new file mode 100644
    index 000000000..145f688b6
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_pattern.h
    @@ -0,0 +1,21 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_pattern.h (%version: 2 %)
    + *          created Tue Feb 15 12:45:43 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Feb 18 16:28:01 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_pattern_h_H
    +#define __1_dave_pattern_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN void d2_setuppattern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox, d2_s32 flip );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_polyline.h b/src/drivers/dave2d/include/dave_polyline.h
    new file mode 100644
    index 000000000..819e2f51d
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_polyline.h
    @@ -0,0 +1,33 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_polyline.h (%version: 3 %)
    + *          created Wed Mar 15 13:47:56 2006 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Jun 30 11:43:18 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_polyline_h_H
    +#define __1_dave_polyline_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_renderpolyline_intern( d2_devicedata *handle, d2_contextdata *ctx, const d2_point *data, const d2_u32 *sflags, d2_u32 count, d2_width w, d2_u32 flags, d2_point soffx, d2_point soffy);
    +
    +D2_EXTERN d2_s32 d2_renderpolyline_solid( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline_shadow( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline_outline( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline_solidshadow( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline_solidoutline( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags);
    +
    +D2_EXTERN d2_s32 d2_renderpolyline2_solid( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline2_shadow( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline2_outline( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline2_solidshadow( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags);
    +D2_EXTERN d2_s32 d2_renderpolyline2_solidoutline( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags);
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_quad.h b/src/drivers/dave2d/include/dave_quad.h
    new file mode 100644
    index 000000000..ecac9f569
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_quad.h
    @@ -0,0 +1,26 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_quad.h (%version: 2 %)
    + *          created Fri Feb 11 14:14:25 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Feb 11 15:35:29 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2010-09-09 MRe: added renderquad functions for solidoutlined etc. 
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_quad_h_H
    +#define __1_dave_quad_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_renderquad_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderquad_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderquad_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderquad_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderquad_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_rbuffer.h b/src/drivers/dave2d/include/dave_rbuffer.h
    new file mode 100644
    index 000000000..dabdfc071
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_rbuffer.h
    @@ -0,0 +1,52 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_rbuffer.h (%version: 4 %)
    + *          created Tue May 10 09:42:33 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Jan 02 14:33:37 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2009-03-06 LBe  added closed flag for renderbuffer struct d2_rbuffer
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_rbuffer_h_H
    +#define __1_dave_rbuffer_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +#include "dave_dlist.h"
    +
    +/*--------------------------------------------------------------------------- */
    +
    +typedef struct _d2_rb_layer
    +{
    +   /* layer data */
    +   d2_dlist_scratch_entry *scratch;
    +   d2_u32                  fullsize;
    +   d2_u32                  freesize;
    +   /* backup data used during target buffer switch */
    +   d2_dlist_scratch_entry *backup_base;
    +   d2_dlist_scratch_entry *backup_pos;
    +   d2_s32                  backup_cnt;
    +   d2_fp_scratchfull       backup_hook;
    +} d2_rb_layer;
    +
    +typedef struct _d2_rbuffer
    +{
    +   d2_dlist    baselist;
    +   d2_rb_layer layer[1];
    +   d2_s32      closed; 
    +} d2_rbuffer;
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_initrblayer_intern( const d2_device *handle, d2_rb_layer *layer, d2_u32 size );
    +
    +D2_EXTERN void d2_rendertolayer_intern( d2_device *handle );
    +D2_EXTERN void d2_rendertobase_intern( d2_device *handle );
    +D2_EXTERN void d2_layer2dlist_intern( d2_device *handle );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_registermap.h b/src/drivers/dave2d/include/dave_registermap.h
    new file mode 100644
    index 000000000..d5074a1ab
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_registermap.h
    @@ -0,0 +1,248 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_registermap.h (%version: 18 %)
    + *          created Wed Jan 19 11:12:21 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Oct 30 09:37:29 2006 %  (%derived_by:  hh74036 %)
    + *
    + * Changes:
    + *  2006-02-16 CSe  added cache control bits for burstmodes
    + *  2006-02-28 CSe  removed cache control bits for burstmodes + big endian
    + *  2006-03-08 CSe  extended texture format selection from 2 to 3 bits
    + *  2006-04-13 CSe  added bitmasks for hardware feature bits
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2008-05-26 MRe  changed bitnumbering (now starting at 0); new texture formats
    + *  2009-01-16 MRe  moved defines for feature bits to dave_driver.h 
    + *  2010-02-18 MRe  added Control2 bits for Alpha channel blending
    + *  2012-09-25 BSp  MISRA cleanup
    + *  2029-02-05 MRe  added Control3 register for max burst lengths
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_registermap_h_H
    +#define __1_dave_registermap_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +#define D2_STATUS     0
    +#define D2_HWREVISION 1
    +
    +
    +#define D2_CONTROL    0u      /* controlword1 */
    +#define D2_CONTROL2   1u      /* controlword2 */
    +#define D2_CONTROL3   2u      /* controlword3 */
    +
    +#define D2_L1START    4       /* limiter 1-4 */
    +#define D2_L2START    5
    +#define D2_L3START    6
    +#define D2_L4START    7
    +#define D2_L5START    8
    +#define D2_L6START    9
    +#define D2_L1XADD    10
    +#define D2_L2XADD    11
    +#define D2_L3XADD    12
    +#define D2_L4XADD    13
    +#define D2_L5XADD    14
    +#define D2_L6XADD    15
    +#define D2_L1YADD    16
    +#define D2_L2YADD    17
    +#define D2_L3YADD    18
    +#define D2_L4YADD    19
    +#define D2_L5YADD    20
    +#define D2_L6YADD    21
    +
    +#define D2_L1BAND    22       /* fixedpoint bandfilter1 value */
    +#define D2_L2BAND    23       /* fixedpoint bandfilter2 value */
    +
    +#define D2_COLOR1    25       /* constant color1 & constant alpha1 */
    +#define D2_COLOR2    26       /* constant color2 & constant alpha2 */
    +#define D2_PATTERN   29       /* pattern (0bit=color1, 1bit=color2) */
    +
    +#define D2_SIZE      30       /* highword : height in pixels,  lowword : width in pixels */
    +#define D2_PITCH     31       /* highword : spanstore delay in lines,   lowword : pitch in bytes */
    +#define D2_ORIGIN    32       /* framebffer address of first enum pixel */
    +
    +   /* reserved 33 - framebuffer minimum address
    +    * reserved 34 - framebuffer maximum address */
    +
    +#define D2_LUSTART      36       /* texture limiter1 */
    +#define D2_LUXADD       37
    +#define D2_LUYADD       38
    +#define D2_LVSTARTI     39       /* texture limiter2 */
    +#define D2_LVSTARTF     40
    +#define D2_LVXADDI      41
    +#define D2_LVYADDI      42
    +#define D2_LVYXADDF     43       /* highword : fractionpart for vyadd , lowword : fractionpart for vxadd */
    +
    +#define D2_TEXPITCH     45       /* texels per texture line */
    +                                 /* bits 31-11 : (height-1) * pitch,   bits 10-0 : (width-1) */
    +#define D2_TEXMASK      46       /* bits 31-11 : Vcordinate mask,   bits 10-0 : Ucordinate mask */
    +#define D2_TEXORIGIN    47       /*  address of first texture pixel (writing can trigger texturecache flush) */
    +
    +#define D2_IRQCTL       48        /* dave interrupt control */
    +
    +#define D2_CACHECTL     49       /* dave cache control (flush) */
    +#define D2_DLISTSTART   50       /* display list start (writing triggers dlist execution) */
    +
    +#define D2_PERFCOUNT1   51       /* performance counter 1 (read/reset) */
    +#define D2_PERFCOUNT2   52       /* performance counter 2 (read/reset) */
    +#define D2_PERFTRIGGER  53       /* performance counter source */
    +
    +#define D2_TEXCLUT      54       /* AI44 write index and data */
    +#define D2_TEXCLUT_ADDR 55       /* clut write address for CLUT256*/
    +#define D2_TEXCLUT_DATA 56       /* clut write data for CLUT256*/
    +#define D2_TEXCLUT_OFFSET 57     /* clut offset for CLUT256*/
    +
    +#define D2_COLKEY       58       /* color for color keying*/
    +
    +#define D2_QUANTITY     59       /* end of registermap (must be < 128)*/
    +
    +
    +/*---------------------------------------------------------------------------
    + * control word bits */
    +
    +#ifndef BIT
    +#define BIT(x)          (1u<<(x))
    +#endif
    +
    +#define D2C_LIM1ENABLE     BIT(0)      /* limiter 1 enable */
    +#define D2C_LIM2ENABLE     BIT(1)      /* limiter 2 enable */
    +#define D2C_LIM3ENABLE     BIT(2)      /* limiter 3 enable */
    +#define D2C_LIM4ENABLE     BIT(3)      /* limiter 4 enable */
    +#define D2C_LIM5ENABLE     BIT(4)      /* limiter 5 enable */
    +#define D2C_LIM6ENABLE     BIT(5)      /* limiter 6 enable */
    +
    +#define D2C_QUAD1ENABLE    BIT(6)      /* quadratic coupling 1 enable */
    +#define D2C_QUAD2ENABLE    BIT(7)      /* quadratic coupling 2 enable */
    +#define D2C_QUAD3ENABLE    BIT(8)      /* quadratic coupling 3 enable */
    +
    +#define D2C_LIM1THRESHOLD  BIT(9)      /* limiter 1 threshold enable */
    +#define D2C_LIM2THRESHOLD  BIT(10)     /* limiter 2 threshold enable */
    +#define D2C_LIM3THRESHOLD  BIT(11)     /* limiter 3 threshold enable */
    +#define D2C_LIM4THRESHOLD  BIT(12)     /* limiter 4 threshold enable */
    +#define D2C_LIM5THRESHOLD  BIT(13)     /* limiter 5 threshold enable */
    +#define D2C_LIM6THRESHOLD  BIT(14)     /* limiter 6 threshold enable */
    +
    +#define D2C_BAND1ENABLE    BIT(15)     /* bandfilter 1 enable */
    +#define D2C_BAND2ENABLE    BIT(16)     /* bandfilter 2 enable */
    +
    +#define D2C_UNION12        BIT(17)     /* combine 1/2 as union (+) otherwise intersect (*) */
    +#define D2C_UNION34        BIT(18)     /* combine 3/4 as union (+) otherwise intersect (*) */
    +#define D2C_UNION56        BIT(19)     /* combine 5/6 as union (+) otherwise intersect (*) */
    +#define D2C_UNIONAB        BIT(20)     /* combine (12)/(34) as union */
    +#define D2C_UNIONCD        BIT(21)     /* combine (12)/(34) as union */
    +
    +#define D2C_SPANABORT      BIT(22)     /* enable span abort */
    +#define D2C_SPANSTORE      BIT(23)     /* enable span store (does not work without span abort) */
    +
    +#define D2C_LIMITERPRECISION  BIT(24)     /* limiter precision is increased by 6 (10.22) */
    +
    +/* controlword2 bits */
    +
    +#define D2C_PATTERNENABLE    BIT(0)    /* render using pattern */
    +#define D2C_TEXTUREENABLE    BIT(1)    /* render using texture */
    +#define D2C_PATTERNSOURCEL5  BIT(2)    /* pattern source limiter 5 */
    +
    +#define D2C_BSF            BIT(9)      /* Blend Source Factor (alpha when set, 1 otherwise) */
    +#define D2C_BDF            BIT(10)     /* Blend Destination Factor (alpha when set, 1 otherwise) */
    +#define D2C_BSI            BIT(11)     /* Blend Source Invert (a = 1-a when set) */
    +#define D2C_BDI            BIT(12)     /* Blend Destination Invert (a = 1-a when set) */
    +#define D2C_BC2            BIT(13)     /* Blend Color2 (Blend using Color2 as Dest when set) */
    +
    +#define D2C_TEXTURECLAMPX  BIT(14)     /* texture u axis clamping */
    +#define D2C_TEXTURECLAMPY  BIT(15)     /* texture v axis clamping */
    +
    +#define D2C_TEXTUREFILTERX BIT(16)     /* Bilinear filtering */
    +#define D2C_TEXTUREFILTERY BIT(17)     /* Bilinear filtering */
    +
    +#define D2C_READFORMAT1    BIT(18)     /* Textureformat bit0 */
    +#define D2C_READFORMAT2    BIT(19)     /* Textureformat bit1 */
    +#define D2C_READFORMAT3    BIT(4)      /* Textureformat bit2 ( 0 = alpha8, 1 = rgb565, 2 = argb8888, 3 = argb4444, 4 = argb1555 ) */
    +#define D2C_READFORMAT4    BIT(5)      /* Textureformat bit3 ( more formats )  */
    +
    +#define D2C_WRITEFORMAT1   BIT(20)     /* Framebuffer format bit0 */
    +#define D2C_WRITEFORMAT2   BIT(21)     /* Framebuffer format bit1 ( 00 = alpha8, 01 = rgb565, 10 = argb8888, 11=argb4444) */
    +#define D2C_WRITEFORMAT3   BIT(8)      /* Framebuffer format bit2 ( 110 = rgba8888, 111=rgba4444) */
    +
    +#define D2C_USE_ACB        BIT(3)     /* use alpha-blending instead of write-alpha for alpha channel (see D2C_WRITEALPHA) */
    +                                       /* the following bits are used if D2C_USE_ACB is not set: */
    +#define D2C_WRITEALPHA1    BIT(22)     /* Write framebuffer alpha (see also D2C_BSIA and D2C_BDIA)*/
    +#define D2C_WRITEALPHA2    BIT(23)     /* ( 11 = framebuffer.a, 00 = color2.a, 01 = coverage, 10 = ?) */
    +                                       /* the following bits are used if D2C_USE_ACB is set: */
    +#define D2C_BSIA           BIT(28)     /* Alpha channel blending: Blend Source Invert (a = 1-a when set */
    +#define D2C_BDIA           BIT(29)     /* Alpha channel blending: Blend Destination Invert (a = 1-a when set */
    +#define D2C_BSFA           BIT(6)      /* Alpha channel blending: Blend Source Factor (alpha when set, 1 otherwise) */
    +#define D2C_BDFA           BIT(7)      /* Alpha channel blending: Blend Destination Factor (alpha when set, 1 otherwise) */
    +/*#define D2C_BC2A           BIT(3)*/      /* Alpha channel blending: Blend Color2 (Blend using Alpha of Color2 as Dest when set) */
    +
    +#define D2C_RLE_ENABLE     BIT(24)     /* enable RLE decoder */
    +#define D2C_CLUT_ENABLE    BIT(25)     /* enable looking up of indices */
    +#define D2C_COLKEY_ENABLE  BIT(26)     /* enable color keying */
    +
    +#define D2C_CLUTFORMAT1    BIT(27)     /* CLUT entry format bit0 */
    +
    +
    +#define D2C_RFU_0          BIT(29)      /* reserved for future use */
    +
    +#define D2C_RLEFORMAT1     BIT(30)     /* RLE format bit0 */
    +#define D2C_RLEFORMAT2     BIT(31)     /* RLE format bit1 00=1 byte per pixel; 01=2 byte per pixel; 10=3 byte per pixel; 11=4 byte per pixel */
    +
    +
    +/* Controlword1 bits */
    +#define D2C_BUSY_ENUM     BIT(0)    /* enumeration unit busy, cant start new primitive */
    +#define D2C_BUSY_WRITE    BIT(1)    /* framebuffer writeback busy, cant change fb type */
    +#define D2C_CACHE_DIRTY   BIT(2)    /* framebuffer cache dirty, cant flip frame */
    +#define D2C_DLISTACTIVE   BIT(3)    /* display list active, cant direct access hwregs */
    +#define D2C_IRQ_ENUM      BIT(4)    /* IRQ on enumeration finish (bit0 low) */
    +#define D2C_IRQ_DLIST     BIT(5)    /* IRQ on display list finish (bit3 low) */
    +
    +/* Interruptbits */
    +#define D2IRQCTL_ENABLE_FINISH_ENUM  BIT(0) /* Interruptmask enable "Enumeration is finished" */
    +#define D2IRQCTL_ENABLE_FINISH_DLIST BIT(1) /* Interruptmask enable "Displaylist is finished" */
    +#define D2IRQCTL_CLR_FINISH_ENUM     BIT(2) /* Clear Interrupt "Enumeration is finished" */
    +#define D2IRQCTL_CLR_FINISH_DLIST    BIT(3) /* Clear Interrupt "Displaylist is finished" */
    +
    +/* Cache control bits */
    +#define D2C_CACHECTL_ENABLE_FB       BIT(0)
    +#define D2C_CACHECTL_FLUSH_FB        BIT(1)
    +#define D2C_CACHECTL_ENABLE_TX       BIT(2)
    +#define D2C_CACHECTL_FLUSH_TX        BIT(3)
    +
    +/* Performance counter source enum (D2_PERFTRIGGER) */
    +#define D2PC_NONE     0
    +#define D2PC_DAVECYCLES     1
    +#define D2PC_FBREADS        2
    +#define D2PC_FBWRITES       3
    +#define D2PC_TXREADS        4
    +#define D2PC_INVPIXELS      5
    +#define D2PC_INVPIXELS_MISS 6
    +#define D2PC_DLRCYCLES      7
    +#define D2PC_FBREADHITS     8
    +#define D2PC_FBREADMISSES   9
    +#define D2PC_FBWRITEHITS   10
    +#define D2PC_FBWRITEMISSES 11
    +#define D2PC_TXREADHITS    12
    +#define D2PC_TXREADMISSES  13
    +#define D2PC_CPUDATAREADS  14
    +#define D2PC_CPUDATAWRITES 15
    +#define D2PC_CPUINSTRREADS 16
    +#define D2PC_RLEREWINDS    20
    +#define D2PC_CYCLES        31
    +
    +/* Hardware revision feature bits */
    +/*
    +#define D2FB_SWDAVE     BIT(16)
    +#define D2FB_DLR        BIT(17)
    +#define D2FB_FBCACHE    BIT(18)
    +#define D2FB_TXCACHE    BIT(19)
    +#define D2FB_PERFCOUNT  BIT(20)
    +#define D2FB_TEXCLUT    BIT(21)
    +#define D2FB_FBPREFETCH BIT(22)
    +#define D2FB_RLEUNIT    BIT(23)
    +#define D2FB_TEXCLUT256 BIT(24)
    +#define D2FB_COLORKEY   BIT(25)
    +#define D2FB_HILIMITERPRECISION   BIT(26)
    +#define D2FB_ALPHACHANNELBLENDING   BIT(27)
    +*/
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_render.h b/src/drivers/dave2d/include/dave_render.h
    new file mode 100644
    index 000000000..d78fbce97
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_render.h
    @@ -0,0 +1,35 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_render.h (%version: 14 %)
    + *          created Wed Jan 19 13:18:44 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Jun 30 11:46:09 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_render_h_H
    +#define __1_dave_render_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +typedef d2_s32 (*d2_fp_triangle)( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags );
    +
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN void d2_startrender_intern( d2_devicedata *handle, const d2_bbox *bbox, d2_u32 delay );
    +
    +D2_EXTERN void d2_startrender_bottom_intern( d2_devicedata *handle, const d2_bbox *bbox, d2_u32 delay );
    +
    +D2_EXTERN void d2_setupmaterial_intern( d2_devicedata *handle, d2_contextdata *ctx );
    +
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_u32 d2_initgradients_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox, d2_u32 limindex, d2_u32 control );
    +
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_texture.h b/src/drivers/dave2d/include/dave_texture.h
    new file mode 100644
    index 000000000..4e31df48d
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_texture.h
    @@ -0,0 +1,35 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_texture.h (%version: 2 %)
    + *          created Wed Jul 06 14:57:30 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Jul 29 13:23:57 2005 %  (%derived_by:  hh04019 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_texture_h_H
    +#define __1_dave_texture_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +#define MAX_CLUT16_ENTRIES 16
    +#define MAX_CLUT256_ENTRIES 256
    +
    +D2_EXTERN void d2_setuptextureblend_intern( const d2_devicedata *handle, d2_contextdata *ctx );
    +
    +D2_EXTERN void d2_calctexturealpha_intern( d2_contextdata *ctx );
    +
    +D2_EXTERN void d2_setuptexture( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox, d2_s32 flip );
    +
    +D2_EXTERN void d2_calctexturemask_intern( d2_contextdata *ctx );
    +
    +/*D2_EXTERN d2_s32 d2_settexclut( d2_device *handle, d2_color* clut );*/ /* defined in dave_driver.h */
    +
    +D2_EXTERN d2_s32 d2_settexclutentry( d2_device *handle, d2_s32 index, d2_color color ) ;
    +
    +D2_EXTERN d2_s32 d2_refreshclut( d2_device *handle );
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_triangle.h b/src/drivers/dave2d/include/dave_triangle.h
    new file mode 100644
    index 000000000..1447d4755
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_triangle.h
    @@ -0,0 +1,29 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_triangle.h (%version: 4 %)
    + *          created Mon Jan 24 16:23:01 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Wed Feb 09 13:41:12 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_triangle_h_H
    +#define __1_dave_triangle_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_rendertri_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_rendertri_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_rendertri_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_rendertri_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags );
    +
    +D2_EXTERN d2_s32 d2_rendertri_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_triarray.h b/src/drivers/dave2d/include/dave_triarray.h
    new file mode 100644
    index 000000000..400e6213b
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_triarray.h
    @@ -0,0 +1,22 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_triarray.h (%version: 1 %)
    + *          created Tue May 23 12:19:25 2006 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue May 23 12:19:27 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_triarray_h_H
    +#define __1_dave_triarray_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +/* (note) implemented in dave_render.c */
    +D2_EXTERN void d2_rendertrifan_intern( d2_device *handle, d2_fp_triangle rtri, const d2_point *vert, const d2_u32 *flags, d2_u32 count);
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_types.h b/src/drivers/dave2d/include/dave_types.h
    new file mode 100644
    index 000000000..cf5c8acbb
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_types.h
    @@ -0,0 +1,33 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_types.h (%version: 69 %)
    + *          created Tue Sep 25 17:31:44 2012 by hh04044
    + *
    + * Description:
    + *  %date_modified: Thu Apr 26 16:21:32 2007 %  (%derived_by:  hh74036 %)
    + *
    + * Definition of common basic types.
    + *
    + * Changes:
    + *  2012-09-25 BSp  MISRA cleanup
    + *
    +*-------------------------------------------------------------------------- */
    +
    +#ifndef __DAVE_TYPES_H__
    +#define __DAVE_TYPES_H__
    +
    +
    +typedef char           d2_char;   /* character */
    +typedef signed char    d2_s8;     /* signed byte */
    +typedef unsigned char  d2_u8;     /* unsigned byte */
    +typedef unsigned short d2_u16;
    +typedef signed short   d2_s16;
    +typedef signed int     d2_s32;
    +typedef unsigned int   d2_u32;
    +typedef unsigned long  d2_ulong;  /* platform-dependent: usually 32bit, sometimes 48bit. */
    +typedef signed long    d2_slong;
    +typedef float          d2_f32;    /* IEE754 single precision float */
    +typedef double         d2_f64;    /* IEE754 double precision float */
    +
    +
    +#endif /* __DAVE_TYPES_H__ */
    diff --git a/src/drivers/dave2d/include/dave_utility.h b/src/drivers/dave2d/include/dave_utility.h
    new file mode 100644
    index 000000000..ef8d6b3d8
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_utility.h
    @@ -0,0 +1,30 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_utility.h (%version: 3 %)
    + *          created Tue Jul 19 12:52:55 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Oct 24 11:30:35 2006 %  (%derived_by:  hh74040 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_utility_h_H
    +#define __1_dave_utility_h_H
    +#ifdef __cplusplus
    +extern "C" {
    +#endif
    +/*--------------------------------------------------------------------------- */
    +
    +#if 0 /* already declared in dave_driver.h */
    +D2_EXTERN d2_s32 d2_utility_maptriangle( d2_device *handle, const d2_f32 *points, const d2_f32 *uvs );
    +D2_EXTERN d2_s32 d2_utility_perspectivewarp( d2_device *handle, d2_u16 srcwidth, d2_u16 srcheight, d2_s16 srcx, d2_s16 srcy, d2_s16 dstwidth, d2_s16 dstheight, d2_s16 dstx, d2_s16 dsty, d2_u16 wt );
    +#endif /* 0 */
    +
    +/*--------------------------------------------------------------------------- */
    +#ifdef __cplusplus
    +}
    +#endif
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_videomodes.h b/src/drivers/dave2d/include/dave_videomodes.h
    new file mode 100644
    index 000000000..a30786dc5
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_videomodes.h
    @@ -0,0 +1,59 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_videomodes.h (%version: 8 %)
    + *          created Tue Aug 23 10:32:45 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Oct 27 11:24:15 2006 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + *  2006-01-04 CSe  - changed defines for video modes (now using struct)
    + *  2006-01-13 NSc  - combined ID and descriptor for video modes
    + *  2007-10-18 ASc  - move structs to dave_base to allow compilation 
    + *                    without display driver
    + *  2008-01-14 ASc  - removed tabs, changed C++ to C comments, added
    + *                    new videomode for Ravin platform (320x240)
    + * */
    +
    +/*--------------------------------------------------------------------------
    + * Video modes for display controller.
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_videomodes_h_H
    +#define __1_dave_videomodes_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +#define D1_VIDEO_OFF                0
    +#define D1_VIDEO_DEFAULT            1
    +#define D1_VIDEO_640_400_60         2
    +#define D1_VIDEO_640_480_60         3
    +#define D1_VIDEO_800_600_60         4
    +#define D1_VIDEO_480_234_60         5
    +#define D1_VIDEO_800_480_60         6
    +#define D1_VIDEO_320_240_60         7
    +#define D1_VIDEO_1024_1024_60       8
    +#define D1_VIDEO_1280_1024_60       9
    +#define D1_VIDEO_1920_1080_60      10
    +#define D1_VIDEO_1920_1200_60      11
    +#define D1_VIDEO_480_480_60        12
    +
    +/*---------------------------------------------------------------------------
    + * each entry fills a d1_videomode struct (see below) */
    +
    +#define D1_VIDEODESC_OFF               { D1_VIDEO_OFF, 0, 0, 0 }
    +#define D1_VIDEODESC_640_400_60        { D1_VIDEO_640_400_60, 640, 400, 60 }
    +#define D1_VIDEODESC_640_480_60        { D1_VIDEO_640_480_60, 640, 480, 60 }
    +#define D1_VIDEODESC_800_600_60        { D1_VIDEO_800_600_60, 800, 600, 60 }
    +#define D1_VIDEODESC_480_234_60        { D1_VIDEO_480_234_60, 480, 234, 60 }
    +#define D1_VIDEODESC_800_480_60        { D1_VIDEO_800_480_60, 800, 480, 60 }
    +#define D1_VIDEODESC_320_240_60        { D1_VIDEO_320_240_60, 320, 240, 60 }
    +#define D1_VIDEODESC_1024_1024_60      { D1_VIDEO_1024_1024_60, 1024, 1024, 60 }
    +#define D1_VIDEODESC_1280_1024_60      { D1_VIDEO_1280_1024_60, 1280, 1024, 60 }
    +#define D1_VIDEODESC_1920_1080_60      { D1_VIDEO_1920_1080_60, 1920, 1080, 60 }
    +#define D1_VIDEODESC_1920_1200_60      { D1_VIDEO_1920_1200_60, 1920, 1200, 60 }
    +#define D1_VIDEODESC_480_480_60        { D1_VIDEO_480_480_60, 480, 480, 60 }
    +
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    +
    diff --git a/src/drivers/dave2d/include/dave_viewport.h b/src/drivers/dave2d/include/dave_viewport.h
    new file mode 100644
    index 000000000..7dba3a64e
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_viewport.h
    @@ -0,0 +1,21 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_viewport.h (%version: 3 %)
    + *          created Thu Jan 13 10:19:50 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Jan 23 16:34:02 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_viewport_h_H
    +#define __1_dave_viewport_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_clipbbox_intern( const d2_devicedata *handle, d2_bbox *box );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/include/dave_wedge.h b/src/drivers/dave2d/include/dave_wedge.h
    new file mode 100644
    index 000000000..ca794775e
    --- /dev/null
    +++ b/src/drivers/dave2d/include/dave_wedge.h
    @@ -0,0 +1,25 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_wedge.h (%version: 2 %)
    + *          created Mon Feb 14 14:47:04 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Feb 15 17:46:43 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#ifndef __1_dave_wedge_h_H
    +#define __1_dave_wedge_h_H
    +/*--------------------------------------------------------------------------- */
    +
    +D2_EXTERN d2_s32 d2_renderwedge_solid( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderwedge_outline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderwedge_shadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderwedge_solidoutline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags );
    +D2_EXTERN d2_s32 d2_renderwedge_solidshadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags );
    +
    +/*--------------------------------------------------------------------------- */
    +#endif
    diff --git a/src/drivers/dave2d/src/dave_64bitoperation.c b/src/drivers/dave2d/src/dave_64bitoperation.c
    new file mode 100644
    index 000000000..8ea530847
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_64bitoperation.c
    @@ -0,0 +1,482 @@
    +/*
    +****************************************************************************
    +PROJECT : D/AVE
    +FILE    : $Id: dave_64bitoperation.c 23623 2011-08-19 12:01:17Z nan.wang $
    +============================================================================ 
    +DESCRIPTION
    +D/AVE driver
    +============================================================================
    +C O P Y R I G H T                                    
    +============================================================================
    +Copyright (c) 2011
    +by 
    +Renesas Electronics (Europe) GmbH. 
    +Arcadiastrasse 10
    +D-40472 Duesseldorf
    +Germany
    +All rights reserved.
    +============================================================================
    +Purpose: only for testing
    +
    +Warranty Disclaimer
    +
    +Because the Product(s) is licensed free of charge, there is no warranty 
    +of any kind whatsoever and expressly disclaimed and excluded by Renesas, 
    +either expressed or implied, including but not limited to those for 
    +non-infringement of intellectual property, merchantability and/or 
    +fitness for the particular purpose. 
    +Renesas shall not have any obligation to maintain, service or provide bug 
    +fixes for the supplied Product(s) and/or the Application.
    +
    +Each User is solely responsible for determining the appropriateness of 
    +using the Product(s) and assumes all risks associated with its exercise 
    +of rights under this Agreement, including, but not limited to the risks 
    +and costs of program errors, compliance with applicable laws, damage to 
    +or loss of data, programs or equipment, and unavailability or 
    +interruption of operations.
    +
    +Limitation of Liability
    +
    +In no event shall Renesas be liable to the User for any incidental, 
    +consequential, indirect, or punitive damage (including but not limited 
    +to lost profits) regardless of whether such liability is based on breach 
    +of contract, tort, strict liability, breach of warranties, failure of 
    +essential purpose or otherwise and even if advised of the possibility of 
    +such damages. Renesas shall not be liable for any services or products 
    +provided by third party vendors, developers or consultants identified or
    +referred to the User by Renesas in connection with the Product(s) and/or the 
    +Application.
    +
    +****************************************************************************
    +*/
    +/*--------------------------------------------------------------------------
    + *
    + * Title: functions for 64bit operations
    + * 
    + * This module contains all the necessary function for 64bit operation in case
    + * the chosen compiler does not support long long. Per default this module is
    + * linked. 
    + * This module is excluded only when the compiler supports long long
    + * 
    + *
    + *-------------------------------------------------------------------------- */
    +
    +
    +/***********************************************************
    + *
    + *                       Includes
    + *
    + ************************************************************
    + */
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +
    +
    +#ifdef _NO_LL_
    +
    +#ifdef __CA850__
    +#elif defined(__ICCV850__)
    +#include "intrinsics.h"
    +#else
    +#include "v800_ghs.h"
    +D2_EXTERN d2_s32 __MULSH(d2_s32 a, d2_s32 b);
    +D2_EXTERN d2_s32 __MULUH(d2_u32 a, d2_u32 b);
    +#endif
    +
    +
    +/***********************************************************
    + *
    + *    Function: d2_cast32to64
    + *    
    + *    Cast an 32bit integer to 64bit variable
    + *
    + *    Parameters:
    + *
    + *        par   - 32bit integer to be casted
    + *
    + *    Return:
    + *
    + *        d2_int64 - a 64bit value
    + */
    +void d2_cast32to64(d2_s32 par, d2_int64 *res)
    +{
    +   res->low32  = (d2_u32)par;
    +   
    +   /* Check sign*/
    +   if(par < 0)
    +   {
    +      res->high32 = 0xffffffffu;
    +   }
    +   else
    +   {
    +      res->high32 = 0;
    +   }   
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_cast64to32
    + *    
    + *    Cast an 64bit variable to a32bit variable
    + *
    + *    Parameters:
    + *
    + *        par   - 64bit variable of type d2_int64
    + *
    + *    Return:
    + *
    + *        int - a 32bit value
    + */
    +d2_s32 d2_cast64to32(const d2_int64 *par)
    +{
    +   return ((d2_s32)par->low32);
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_add64
    + *    
    + *    Addition of 2 64bit value
    + *
    + *    Parameters:
    + *
    + *        a   - 64bit variable of type d2_int64
    + *        b   - pointer to a 64bit variable of type d2_int64
    + *        res - pointer to a 64bit variable of type d2_int64.
    + *              The result will be stored in that variable.
    + *
    + *    Return:
    + *
    + *        none
    + */
    +void d2_add64(const d2_int64 *a, const d2_int64 *b, d2_int64 *res)
    +{
    +   d2_u32 tmp;
    +   
    +   res->low32   = a->low32  + b->low32;
    +   res->high32  = a->high32 + b->high32;
    +
    +#ifdef __CA850__
    +   tmp = (d2_u32) __satadd(a->low32, b->low32);        /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#elif defined(__ICCV850__)
    +   tmp = __upper_mul64(a->low32, b->low32);   /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#else
    +   tmp = ADD_SAT(a->low32, b->low32);         /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#endif
    +
    +   if( (0x7FFFFFFFu == tmp) || (0x80000000u == tmp) )
    +   {
    +      res->high32++;
    +   }
    +   
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_sub64
    + *    
    + *    Substraction of 2 64bit value
    + *
    + *    Parameters:
    + *
    + *        a   - 64bit variable of type d2_int64
    + *        b   - pointer to a 64bit variable of type d2_int64
    + *        res - pointer to a 64bit variable of type d2_int64.
    + *              The result will be stored in that variable.
    + *
    + *    Return:
    + *
    + *        none
    + */
    +void d2_sub64(const d2_int64 *a, const d2_int64 *b, d2_int64 *res)
    +{
    +   res->low32   = a->low32  - b->low32;
    +   res->high32  = a->high32 - b->high32;
    +
    +   if(a->low32 < b->low32)
    +   {
    +      res->high32  -= 1;
    +   }
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_mul3232to64
    + *    
    + *    multiply two 32-bit variables and return a 64bit value
    + *
    + *    Parameters:
    + *
    + *        a   - int
    + *        b   - int
    + *        res - pointer to a variable of type d2_int64
    + *              The result will be stored in that variable.
    + *
    + *    Return:
    + *
    + *        none
    + */
    +
    +#ifdef __CA850__
    +#elif defined(__ICCV850__)
    +#include "intrinsics.h"
    +#else
    +D2_EXTERN d2_s32 __MULSH(d2_s32 a, d2_s32 b); 
    +#endif
    +
    +void d2_mul3232to64(d2_s32 a, d2_s32 b, d2_int64 *res)
    +{
    +   res->low32  = (d2_u32)a * (d2_u32)b;
    +#ifdef __CA850__
    +   res->high32 = __mul32(a, b);         /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#elif defined(__ICCV850__)
    +   res->high32 = __upper_mul64(a, b);   /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#else
    +   res->high32 = __MULSH(a, b);         /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#endif
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_mul3264
    + *    
    + *    multiply two a 32bit varibales with a 64bit one and 
    + *    return a 64bit result
    + *
    + *    Parameters:
    + *
    + *        a   - int
    + *        b   - pointer to a 64bit variable of type d2_int64
    + *        res - pointer to a 64bit variable of type d2_int64.
    + *              The result will be stored in that variable.
    + *
    + *    Return:
    + *
    + *        None
    + */
    +void d2_mul3264(d2_s32 a, const d2_int64 *b, d2_int64 *res)
    +{
    +   d2_u32 negative = 0;
    +   d2_u32 ui_b_high32;
    +   d2_u32 ui_b_low32;
    +   d2_u32 ui_a;
    +   
    +   /* get sign */
    +   if(b ->high32 < 0)
    +   {
    +      negative = 1u;
    +      ui_b_high32 = ((d2_u32)b->high32 ^ 0xFFFFFFFFu);
    +      ui_b_low32  = (d2_u32)((b->low32 ^ 0xFFFFFFFFu) + 1u); 
    +   }
    +   else
    +   {
    +      ui_b_high32 = (d2_u32) b->high32;
    +      ui_b_low32  = (d2_u32) b->low32; 
    +   }
    +
    +   if(a < 0)
    +   {
    +      negative ^= 1u;
    +      ui_a = (d2_u32) (-a);
    +   }
    +   else
    +   {
    +      ui_a = (d2_u32) a;
    +   }
    +      
    +   res->low32  = (ui_a) * (ui_b_low32);
    +#ifdef __CA850__
    +   res->high32 = __mul32u(ui_a, ui_b_low32);      /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#elif defined(__ICCV850__)
    +   res->high32 = __upper_mul64(ui_a, ui_b_low32); /* !!!!! Wrong should be unsigned mul!!!*/  /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#else
    +   res->high32 = __MULUH(ui_a, ui_b_low32);      /* PRQA S 3335 */ /* $Misra: #COMPILER_INTRINSIC $*/
    +#endif
    +   res->high32 += (d2_s32) (ui_a * ui_b_high32);
    +   
    +   /* restore sign*/
    +   if(0 != negative)
    +   {
    +      if(0 != res->low32)
    +      {
    +         res->high32 = (d2_s32)((d2_u32)res->high32 ^ 0xFFFFFFFFu);
    +         res->low32  = (res->low32 ^ 0xFFFFFFFFu) + 1u;
    +      }
    +      else
    +      {
    +         if(0 != res->high32)
    +         {
    +            res->high32 = -res->high32;
    +         }
    +      }
    +   }
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_div6432
    + *    
    + *    division of 64bit value by a 32bit. The return result 
    + *    is a 64bit value.
    + *
    + *    Parameters:
    + *
    + *        dividend   - pointer to a 64bit variable of type d2_int64
    + *        divisor    - 32bit variable of type int
    + *        res        - pointer to a 64bit variable of type d2_int64
    + *                     The result will be stored in this variable
    + *  
    + *    Return:
    + *
    + *        None
    + */
    +void d2_div6432(const d2_int64 *dividend, d2_s32 divisor, d2_int64 *res)
    +{
    +   d2_u32 remainder;
    +   d2_u32 shift           = 0u;
    +   d2_u32 negative        = 0u;
    +   d2_s32 dividend_high32 = dividend->high32; 
    +   d2_u32 dividend_low32  = dividend->low32; 
    +   
    +   
    +   res->high32 = 0;
    +   res->low32  = 0;
    +   
    +   /* Test for division by 0*/
    +   if(0 == divisor)
    +   {
    +      return; /* return 0*/
    +   }
    +   
    +   /* Test for sign*/
    +   if(dividend_high32 < 0)
    +   {
    +      dividend_high32 = -dividend_high32 - 1; /*  invert sign */
    +      dividend_low32  = (dividend_low32 ^ 0xFFFFFFFFu) + 1u; /*  invert sign */
    +      negative = 1;
    +   }
    +
    +   if(divisor < 0)
    +   {
    +      divisor   = -divisor; /*  invert sign */
    +      negative ^= 1u;
    +   }
    +      
    +   /*if divisor > dividend  return 0*/
    +   if( (0 == dividend_high32) && ((d2_u32)divisor > dividend_low32))
    +   {
    +      return; /* return 0*/
    +   }
    +   
    +   res->high32 = dividend_high32 / divisor;
    +   res->low32  = dividend_low32  / (d2_u32)divisor;
    +   
    +   remainder = (d2_u32) (dividend_high32 - (res->high32 * divisor));
    +
    +   if(0 != remainder)
    +   {
    +      d2_int64 tmp64;
    +      d2_u32 tmp32;
    +      d2_u32 remMask  = 0x80000000u;
    +      shift = 0;
    +      for(;;)
    +      {
    +         if(0 != (remainder & remMask))
    +         {
    +            tmp32 = remainder << shift;
    +            tmp32 = tmp32 / (d2_u32)divisor;
    +            res->low32 += tmp32 << (32u - shift);
    +            d2_mul3232to64((d2_s32)res->low32, divisor, &tmp64);
    +
    +            if(0 == tmp64.high32)
    +            {
    +               /* result is 32-bit */
    +               remainder = dividend_low32 - (res->low32 * (d2_u32)divisor);
    +               res->low32 += remainder / (d2_u32)divisor;
    +            }
    +            else
    +            {
    +               /* result is 64-bit */
    +               d2_int64 tmp64_2;
    +               d2_int64 tmp64_3;
    +               tmp64_3.low32  = dividend_low32;
    +               tmp64_3.high32 = dividend_high32;
    +               d2_sub64(&tmp64_3, &tmp64, &tmp64_2);
    +               d2_div6432(&tmp64_2, divisor, &tmp64);    /* PRQA S 3670 */ /* $Misra: #DIV64_RECURSION $*/
    +               d2_add64(&tmp64, res, &tmp64_2);
    +               res->low32 = tmp64_2.low32;
    +               res->high32 = tmp64_2.high32;
    +            }
    +            break;
    +         }
    +
    +         shift++;   
    +         remMask >>= 1u;
    +      }
    +   }
    +         
    +   /* restore sign*/
    +   if(0 != negative)
    +   {
    +      if(0 != res->low32)
    +      {
    +         res->high32 = -res->high32 - 1;
    +         res->low32  = (res->low32 ^ 0xFFFFFFFFu) + 1u;
    +      }
    +      else
    +      {
    +         if(0 != res->high32)
    +         {
    +            res->high32 = -res->high32;
    +         }
    +      }
    +   }
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_shiftleft64
    + *    
    + *    Shift left a variable of type d2_int64
    + *
    + *    Parameters:
    + *
    + *        var   - pointer to a 64bit variable of type d2_int64
    + *        index - integer, number of bit to shift
    + *        res   - pointer to a 64bit variable of type d2_int64
    + *                The result will be stored in this variable
    + *  
    + *    Return:
    + *
    + *        None
    + */
    +void d2_shiftleft64(const d2_int64 *var, d2_s32 index, d2_int64 *res)
    +{
    +   res->low32  = var->low32 << index;
    +   res->high32 = (var->high32 << index) + (d2_s32)(var->low32 >> (32 - index));  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +}
    +
    +/***********************************************************
    + *
    + *    Function: d2_shiftright64
    + *    
    + *    Shift right a variable of type d2_int64
    + *
    + *    Parameters:
    + *
    + *        var   - pointer to a 64bit variable of type d2_int64
    + *        index - integer, number of bit to shift
    + *        res   - pointer to a 64bit variable of type d2_int64
    + *                The result will be stored in this variable
    + *  
    + *    Return:
    + *
    + *        None
    + */
    +void d2_shiftright64(const d2_int64 *var, d2_s32 index, d2_int64 *res)
    +{
    +   res->low32  = (d2_u32)(var->high32 << (32 - index)) + (var->low32 >> index);   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   res->high32 = var->high32 >> index;                                            /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +}
    +
    +#endif /* end _NO_LL_ */
    diff --git a/src/drivers/dave2d/src/dave_blit.c b/src/drivers/dave2d/src/dave_blit.c
    new file mode 100644
    index 000000000..4b9f73eb3
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_blit.c
    @@ -0,0 +1,623 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_blit.c (%version: 15 %)
    + *          created Wed Jan 19 13:09:06 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Feb 13 17:14:11 2007 %  (%derived_by:  hh74036 %)
    + *
    + * Changes:
    + *  2006-03-08 CSe  added argb1555 format
    + *  2007-09-18 ASc  fix: removed duplicate alpha calculation in d2_blitcopy
    + *  2007-09-20 ASc  changed comments from C++ to C, added wrapping for blits
    + *  2008-05-21 CSe  corrected documentation for d2_setblitsrc 
    + *  2008-06-13 MRe  RLE unit, CLUT256, subbyte formats, color keying
    + *  2008-07-17 MRe  added RGBA formats
    + *  2008-11-26 MRe  quick fix for texture width up to 2047 
    + *  2009-03-06 MRe  fix for texture width up to 2048 
    + *  2011-03-11 MRe  improved/removed context backup for blit
    + *  2011-06-16 MRe  added Alpha4, Alpha2, Alpha1 texture formats
    + *  2012-09-05 MRe  added check for Alpha4, Alpha2, Alpha1 texture formats
    + *  2012-09-25 BSp  MISRA cleanup
    + */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Blit Functions
    + * BLock Image Transfer operations
    + *
    + * Blit's are special <Rendering Functions> to copy one rectangle part of
    + * the video memory into another part of the video memory.
    + * The operation could be performed using texturemapping and boxrendering as
    + * well, but the blit interface avoids setting and restoring all necessary
    + * context states.
    + *
    + * Texel-to-pixel mapping:
    + * Conceptually textures are seen the same way as a raster display: 
    + * Each texel is defined at the exact center of a grid cell.
    + * The driver maps the left border of the left-most texel to the left border 
    + * of the left-most destination pixel and the right border of the right-most 
    + * texel to the right border of the right-most destination pixel.
    + *
    + * Example: 
    + * Find below an example of resizing a source texture with filtering enabled.
    + * - A source image (3x1) is stretched to a destination rectangle (5x1).
    + * - A source image (5x1) is downsized to a destination rectangle (3x1).
    + * (see blit_mapping.png)
    + *
    + * Please not that the texel-to-pixel mapping implementation has changed 
    + * for the magnification case since D2 Driver version 3.10.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_texture.h"
    +#include "dave_registermap.h"
    +#include "dave_box.h"
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +
    +#define D2_CHECKERR_BLITWIDTH(x) D2_CHECKERR( (x)<=(1024*2) , D2_INVALIDWIDTH )  /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#define D2_CHECKERR_BLITHEIGHT(y) D2_CHECKERR( (y)<=1024 , D2_INVALIDHEIGHT )    /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#define D2_CHECKERR_BLITPITCH(p) D2_CHECKERR( (p)<65536 , D2_VALUETOOBIG )       /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +#define D2_CHECKERR_BLITSRCPOSX(x) D2_CHECKERR( (p)<65536 , D2_VALUETOOBIG )     /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +
    +/*--------------------------------------------------------------------------
    + * Group: BLIT Attributes Writes */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setblitsrc
    + * Specify the source for blit operation.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ptr - address of the top left texel (coordinate 0,0)
    + *   pitch - number of pixels (*not bytes*) per scanline
    + *   width - width of bitmap in pixels (equal or less than pitch)
    + *   height - height of bitmap in pixels
    + *   format - pixel encoding type (bitmap format)
    + *
    + * bitmap formats:
    + *
    + *   d2_mode_alpha8   - monochrome 8bit per pixel
    + *   d2_mode_alpha4    - monochrome 4bit per pixel
    + *   d2_mode_alpha2    - monochrome 2bit per pixel
    + *   d2_mode_alpha1    - monochrome 1bit per pixel
    + *   d2_mode_rgb565   - colored 16bit per pixel (alpha is blue)
    + *   d2_mode_argb8888 - colored 32bit per pixel
    + *   d2_mode_rgba8888 - colored 32bit per pixel
    + *   d2_mode_rgb888   -  (same as d2_mode_argb8888, in case of RLE textures 24bit pixel are decoded to 32bit)
    + *   d2_mode_argb4444 - colored 16bit per pixel
    + *   d2_mode_rgba4444 - colored 16bit per pixel
    + *   d2_mode_rgb444   -  (same as d2_mode_argb4444)
    + *   d2_mode_argb1555 - colored 16bit per pixel
    + *   d2_mode_rgba5551 - colored 16bit per pixel
    + *   d2_mode_rgb555   -  (same as d2_mode_argb1555)
    + *   d2_mode_ai44     - colored, palletized 8bit per pixel, (4 bit alpha, 4 bit indexed RGB: see <d2_settexclut>)
    + *   d2_mode_i8        - colored, palletized 8bit per pixel (palette is used if d2_mode_clut is also set)
    + *   d2_mode_i4        - colored, palletized 4bit per pixel (palette is used if d2_mode_clut is also set)
    + *   d2_mode_i2        - colored, palletized 2bit per pixel (palette is used if d2_mode_clut is also set)
    + *   d2_mode_i1        - colored, palletized 1bit per pixel (palette is used if d2_mode_clut is also set)
    + *
    + * additional flags (can be combined with all above formats) :
    + *
    + *   d2_mode_rle      -  Enables the RLE unit (available if the feature bit D2FB_RLEUNIT is set (see <d2_getrevisionhw>)).
    + *   d2_mode_clut     -  Enables the color look up table (for d2_mode_i8 through d2_mode_i1) (see <d2_settexclut>).
    + *
    + * Modes d2_mode_rgb888, d2_mode_rgb444 and d2_mode_rgb555 can be used as well. Alpha information has to
    + * be ignored by not selecting the flag d2_bf_usealpha when calling <d2_blitcopy>.
    + *
    + * If the CLUT is not enabled with an indexed color format (d2_mode_i8 to d2_mode_i1), the index is written directly to the framebuffer.
    + * The index can be combined with the offset, see <d2_settexclut_offset>.
    + *
    + * In case of d2_mode_alpha4 to d2_mode_alpha1 bits are MSB aligned and replicated to the lower bits of the 8 bit format of the internal A, R, G and B channels.
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * note:
    + * width can be max 2048 pixel, height can be max 1024 pixel. 
    + *
    + *   Please notice that a cache flush using 'd1_cacheblockflush' might be necessary if memory contents were changed before!
    + *   To avoid problems you can use the d1 driver memory management functions 'd1_copytovidmem' or 'd1_copyfromvidmem',
    + *   which implicitly do a cache flush.
    + * */
    +d2_s32 d2_setblitsrc( d2_device *handle, void *ptr, d2_s32 pitch, d2_s32 width, d2_s32 height, d2_u32 format )
    +{
    +   d2_contextdata *ctx;
    +   d2_u32 format_noflags = format & ~d2_mode_rle & ~d2_mode_clut;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ptr, D2_NOVIDEOMEM );       /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR_BLITPITCH( pitch );          /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR_BLITWIDTH( width );          /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR_BLITHEIGHT( height );        /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +
    +   if ( (0 != (format & d2_mode_rle)) && (0 == ((D2_DEV(handle)->hwrevision) & D2FB_RLEUNIT)) )
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   if ( (0 != (format & d2_mode_clut)) && (0 == ((D2_DEV(handle)->hwrevision) & D2FB_TEXCLUT)) )
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   if ( (   (format_noflags == d2_mode_alpha4) 
    +            || (format_noflags == d2_mode_alpha2) 
    +            || (format_noflags == d2_mode_alpha1) )
    +        && ( (0 == (D2_DEV(handle)->hwrevision & D2FB_SWDAVE)) && ((D2_DEV(handle)->hwrevision & 0xff) < 0x0a) )   )
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   ctx->blit_src    = ptr;
    +   ctx->blit_pitch  = pitch;
    +   ctx->blit_width  = width;
    +   ctx->blit_height = height;
    +   ctx->blit_format = format;
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: BLIT Rendering Functions */
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_blitcopy
    + * Copy rectangle part of the source into destination.
    + *
    + * The source is set prior to the blit using <d2_setblitsrc> and the destination
    + * will be part of the framebuffer (see: <d2_framebuffer>) just as with any normal
    + * rendering function.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   srcwidth, srcheight - size of source rectangle in pixels (integer)
    + *   srcx,srcy  - position in source bitmap (integer)
    + *   dstwidth, dstheight - size of destination rectangle in pixels (fixedpoint)
    + *   dstx,dsty - position in destination bitmap (fixedpoint)
    + *   flags - any combination of blit flag bits (see below)
    + *
    + * blit flag bits:
    + *
    + *   d2_bf_filteru  - apply linear filter on U axis (x-direction)
    + *   d2_bf_filterv  - apply linear filter in V axis (y-direction)
    + *   d2_bf_filter - apply bilinear filter (both axis)
    + *   d2_bf_wrapu - wrap bitmap on U axis (x-direction)
    + *   d2_bf_wrapv - wrap bitmap on V axis (y-direction)
    + *   d2_bf_wrap - wrap bitmap on U and V axis (x/y-direction)
    + *   d2_bf_mirroru - mirror bitmap in U axis (x-direction)
    + *   d2_bf_mirrorv - mirror bitmap in V axis (y-direction)
    + *   d2_bf_colorize - bitmap colors are multiplied by color register index 0 (see: <d2_setcolor>)
    + *   d2_bf_colorize2 - bitmap colors are interpolated between color register index 0 and 1 (see: <d2_setcolor>)
    + *   d2_bf_usealpha - alpha value from bitmap is used
    + *   d2_bf_invertalpha - alpha value from bitmap is inverted before use (requires usealpha)
    + *   d2_bf_no_blitctxbackup   - for this blit don't backup context data for better performance; previous texture modes get lost and must be set again
    + *
    + *
    + * (start code)
    + *
    + *     blitsrc.src:+-------------------------------------+ 
    + *                 |           blitsrc.width             | 
    + *                 |<----------blitsrc.pitch------------>| 
    + *                 |                                     | 
    + *                 |    srcx/y:+-----------------+  ^   
    + *                 |           |                 |  |   
    + *                 |           |<---srcwidth---->|  |   
    + *                 |           |                 |  | srcheight  
    + *                 |           |                 |  |   
    + *                 |           +-------\\--------+  v  
    + *                 |                    \\ 
    + *                                       \\ 
    + *         Display:  +--------------------\\----------------------+ 
    + *                   |                     \\                     | 
    + *                   |         dstx/y:+-----\\-------------+  ^   
    + *                   |                |                    |  |   
    + *                   |                |<------dstwidth---->|  |   
    + *                   |                |                    |  | dstheight  
    + *                   |                |                    |  |   
    + *                   |                |                    |  |   
    + *                   |                +--------------------+  v   
    + *
    + * (end)
    + *
    + * <d2_setblitsrc> sets parameters for the texture buffer. 
    + * <d2_blitcopy> sets parameters for an area of the texture buffer and 
    + * an area of the framebuffer where the texture area will be mapped to.
    + * Both areas don't need to be the same size.
    + *
    + * note:
    + * Wrapping will work with source bitmap dimensions that are integer powers of two only (2,4,8,16,32,..)!
    + *
    + * texture pitch can be >= 2048 if (srcheight-1) * pitch < 2048*1024 and if srcheight is multiple of dstheight
    + *
    + * d2_bf_filterv cannot be used if the pitch of the texture is >= 2048
    + * 
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_blitcopy( d2_device *handle, d2_s32 srcwidth, d2_s32 srcheight, d2_blitpos srcx, d2_blitpos srcy, d2_width dstwidth, d2_width dstheight, d2_point dstx, d2_point dsty, d2_u32 flags )
    +{
    +   d2_s32 sw, sh;
    +   d2_s32 dxu, dyv, u0, v0;
    +   d2_s32 texWidth, texHeight;
    +   d2_contextdata *ctx;
    +   d2_color texmodecl1, texmodecl2;
    +   void *src = 0;
    +   d2_u32 format_noflags;
    +   d2_u32 isRLE = 0;
    +   d2_contextdata *blitcontext;
    +#ifdef D2_USEBLITBACKUPCONTEXT
    +   d2_contextdata *backup_context;
    +   d2_s32 i;
    +#else
    +   /* backup data for context content used by blit */
    +   d2_contextdata_backup *backup_context = D2_DEV(handle)->blitcontext_b;
    +   /* if d2_bf_no_blitctxbackup minimal backup on stack */
    +   d2_u32 fillmode_b = 0;
    +#endif
    +
    +   /* current active context (reading) */
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   isRLE = (ctx->blit_format & d2_mode_rle);
    +
    +   D2_VALIDATE( srcwidth>0, D2_INVALIDWIDTH );                                                   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( ((d2_u32)dstwidth>0) && ((d2_u32)dstwidth<=D2_FIX4(1024*2)), D2_INVALIDWIDTH );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/  /* PRQA S 3355 */ /* $Misra: #MISRA_BUG_LOGIC_COMP_TRUE_3355 $*/
    +   D2_VALIDATE( srcheight>0, D2_INVALIDHEIGHT );                                                 /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( (dstheight>0) && (dstheight<=D2_FIX4(1024)), D2_INVALIDHEIGHT );                 /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );                                                     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATEP( ctx->blit_src, D2_NULLPOINTER );                                                /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* no v filtering if pitch too large (11bit) */
    +   if(ctx->blit_pitch >= (1024 * 2))
    +   {
    +      flags &= ~ d2_tm_filterv;
    +   }
    +
    +   /* check if pitch > 11bits */
    +   /* pitch goes to fractional part of v limiter -> will not be used if srcheight is multiple of dstheight */
    +   D2_VALIDATE( (ctx->blit_pitch < (1024*2)) || ((ctx->blit_pitch >= (1024*2)) && (D2_FIX4(srcheight) >= dstheight)), D2_INVALIDHEIGHT); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/ /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +   /* check max value for ymask (21bit) */
    +   D2_VALIDATE( ((srcheight - 1) * ctx->blit_pitch) < (2048 * 1024), D2_INVALIDHEIGHT); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +
    +   /* check: wrapping will work with texture dimensions that are integer powers of two only */
    +   D2_VALIDATE( !( (0 != (d2_tm_wrapu & flags)) && (0 != ( (d2_u32)ctx->blit_width  & ((d2_u32)ctx->blit_width  - 1))) ), D2_INVALIDWIDTH);  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( !( (0 != (d2_tm_wrapv & flags)) && (0 != ( (d2_u32)ctx->blit_height & ((d2_u32)ctx->blit_height - 1))) ), D2_INVALIDHEIGHT); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* compute real texture width and height */
    +   texWidth  = srcwidth;
    +   texHeight = srcheight;
    +
    +   if( (texWidth + srcx)  > ctx->blit_width  ) 
    +   {
    +      texWidth  = (ctx->blit_width - srcx);
    +   }
    +
    +   if( (texHeight + srcy) > ctx->blit_height )
    +   {
    +      texHeight = (ctx->blit_height - srcy);
    +   }
    +
    +   /* check: wrapping will only work with rectangle dimensions that are integer powers of two only */
    +   D2_VALIDATE( !( (0 != (d2_tm_wrapu & flags)) && (0 != ((d2_u32)texWidth  & ((d2_u32)texWidth  - 1))) ), D2_INVALIDWIDTH);   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( !( (0 != (d2_tm_wrapv & flags)) && (0 != ((d2_u32)texHeight & ((d2_u32)texHeight - 1))) ), D2_INVALIDHEIGHT);  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +#ifdef D2_USEBLITBACKUPCONTEXT
    +   /* switch to blit context [hard switch] */
    +   blitcontext = D2_DEV(handle)->blitcontext;
    +   backup_context = D2_DEV(handle)->ctxselected;
    +   D2_DEV(handle)->ctxselected = blitcontext;
    +
    +   /* setup blit context */
    +   blitcontext->features       = ctx->features;
    +   blitcontext->blurring       = ctx->blurring;
    +   blitcontext->alphamode      = ctx->alphamode;
    +   blitcontext->constalpha     = ctx->constalpha;
    +   blitcontext->basealpha[0]   = ctx->basealpha[0];
    +   blitcontext->basealpha[1]   = ctx->basealpha[1];
    +   blitcontext->alphablendmask = ctx->alphablendmask;
    +   blitcontext->blendmask      = ctx->blendmask;
    +   blitcontext->tbstylemask    = ctx->tbstylemask;
    +   blitcontext->rlemask        = ctx->rlemask;
    +   blitcontext->clutmask       = ctx->clutmask;
    +   blitcontext->colkeymask     = ctx->colkeymask;
    +   blitcontext->cr2mask        = ctx->cr2mask;
    +   blitcontext->invblur        = ctx->invblur;
    +   blitcontext->internaldirty  = 0;
    +   blitcontext->texclut        = ctx->texclut;
    +   blitcontext->texclut_cached = ctx->texclut_cached;
    +   blitcontext->texclutupload  = ctx->texclutupload;
    +   blitcontext->texclutoffset  = ctx->texclutoffset;
    +   blitcontext->colorkey       = ctx->colorkey;
    +
    +   /* copy gradient data if necessary */
    +   blitcontext->gradients = ctx->gradients;
    +   if(0 != blitcontext->gradients)
    +   {
    +      for(i=0; i<4; i++)
    +      {
    +         blitcontext->gradient[i] = ctx->gradient[i];
    +      }
    +   }
    +#else
    +   blitcontext = D2_DEV(handle)->ctxselected;
    +
    +   /* backup to stack */
    +   if(backup_context && (0 == (d2_bf_no_blitctxbackup & flags)))
    +   {
    +      backup_context->fillmode          = ctx->fillmode;       
    +      backup_context->internaldirty     = ctx->internaldirty;
    +      backup_context->features          = ctx->features;
    +      backup_context->texcenterx        = ctx->texcenterx;
    +      backup_context->texcentery        = ctx->texcentery;
    +      backup_context->tbstylemask       = ctx->tbstylemask;
    +      backup_context->texbpp            = ctx->texbpp;
    +      backup_context->texwrapmask       = ctx->texwrapmask;
    +      backup_context->texmodemask       = ctx->texmodemask;
    +      backup_context->texmode           = ctx->texmode;
    +      backup_context->texpitch          = ctx->texpitch;
    +      backup_context->texwidth          = ctx->texwidth;
    +      backup_context->texheight         = ctx->texheight;
    +      backup_context->texbase           = ctx->texbase;
    +      backup_context->texsubppb         = ctx->texsubppb;
    +      backup_context->rlebpp            = ctx->rlebpp;
    +      backup_context->rlemask           = ctx->rlemask;
    +      backup_context->clutmask          = ctx->clutmask;
    +      backup_context->cr2mask           = ctx->cr2mask;
    +      backup_context->texmodecl[0]      = ctx->texmodecl[0];
    +      backup_context->texmodecl[1]      = ctx->texmodecl[1];
    +      backup_context->texlim[0].x1      = ctx->texlim[0].x1; 
    +      backup_context->texlim[0].y1      = ctx->texlim[0].y1;
    +      backup_context->texlim[0].xadd2   = ctx->texlim[0].xadd2;
    +      backup_context->texlim[0].yadd2   = ctx->texlim[0].yadd2;
    +      backup_context->texlim[0].xadd    = ctx->texlim[0].xadd;
    +      backup_context->texlim[0].yadd    = ctx->texlim[0].yadd;
    +      backup_context->texlim[1].xadd    = ctx->texlim[1].xadd;
    +      backup_context->texlim[1].yadd    = ctx->texlim[1].yadd;
    +   }
    +   else
    +   {
    +      fillmode_b = ctx->fillmode; 
    +   }
    +#endif
    +
    +   (void)d2_setfillmode( handle, d2_fm_texture );
    +   (void)d2_settexelcenter ( handle, 0, 0 );
    +
    +   /* find texture origin */
    +   if(0 != isRLE)
    +   {
    +      src = ctx->blit_src; /* rle textures can only be decoded from start */
    +    
    +      /* offset will be done using u0, v0 (see below) */
    +   }
    +   else
    +   {
    +      format_noflags = ctx->blit_format & ~d2_mode_rle & ~d2_mode_clut;
    +      switch (format_noflags)
    +      {
    +         case d2_mode_ai44 :
    +            if(0 == ((D2_DEV(handle)->hwrevision) & D2FB_TEXCLUT))
    +            {
    +               D2_RETERR( handle, D2_ILLEGALMODE );
    +            }
    +            blitcontext->tbstylemask = D2C_READFORMAT1 | D2C_READFORMAT3;
    +            blitcontext->texbpp = 1;
    +            /* run into next case */
    +         case d2_mode_alpha8 :
    +         case d2_mode_alpha4 :
    +         case d2_mode_alpha2 :
    +         case d2_mode_alpha1 :
    +         case d2_mode_i8 :
    +         case d2_mode_i4 :
    +         case d2_mode_i2 :
    +         case d2_mode_i1 :
    +            src = ((d2_s8 *)ctx->blit_src) + srcx + (srcy * ctx->blit_pitch);
    +            break;
    +
    +         case d2_mode_rgb565 :
    +         case d2_mode_rgb444 :
    +         case d2_mode_rgb555 :
    +         case d2_mode_argb4444 :
    +         case d2_mode_argb1555 :
    +         case d2_mode_rgba4444 :
    +         case d2_mode_rgba5551 :
    +            src = ((d2_s16 *)ctx->blit_src) + srcx + (srcy * ctx->blit_pitch);
    +            break;
    +
    +         case d2_mode_argb8888 :
    +         case d2_mode_rgba8888 :
    +         case d2_mode_rgb888 :
    +            src = ((d2_s32 *)ctx->blit_src) + srcx + (srcy * ctx->blit_pitch);
    +            break;
    +
    +         default:
    +            break;
    +      }
    +
    +   }
    +
    +   /* setup texture */
    +   (void)d2_settexturemode( handle, flags & (d2_bf_filter | d2_bf_wrap) );
    +   if(0 != isRLE)
    +   {
    +      (void)d2_settexture( handle, src, ctx->blit_pitch, ctx->blit_width, ctx->blit_height, ctx->blit_format );
    +   }
    +   else
    +   {
    +      (void)d2_settexture( handle, src, ctx->blit_pitch, texWidth, texHeight, ctx->blit_format );
    +   }
    +
    +   /* setup alpha channel operation */
    +   if(0 != (flags & d2_bf_usealpha))
    +   {
    +      if(0 != (flags & d2_bf_invertalpha))
    +      {
    +         /* invert alpha multiply */
    +         texmodecl1 = 0xff000000u; /* multiply by ctx->constalpha happens in d2_calctexturealpha_intern; */
    +         texmodecl2 = 0x00000000u;
    +      }
    +      else 
    +      {
    +         /* alpha multiply */
    +         texmodecl1 = 0x00000000u;
    +         texmodecl2 = 0xff000000u; /* multiply by ctx->constalpha happens in d2_calctexturealpha_intern; */
    +      }
    +   }
    +   else
    +   {
    +      /* alpha replace */
    +      texmodecl1 = 0xff000000u; /* multiply by ctx->constalpha happens in d2_calctexturealpha_intern; */
    +      texmodecl2 = 0xff000000u; /* multiply by ctx->constalpha happens in d2_calctexturealpha_intern; */
    +   }
    +
    +   /* setup color channel operation */
    +   if(0 != (flags & d2_bf_colorize))
    +   {
    +      if(0 != (flags & d2_bf_colorize2))
    +      {
    +         /* color blend */
    +         texmodecl1 |= ctx->basecolor[0];
    +         texmodecl2 |= ctx->basecolor[1];
    +      }
    +      else
    +      {
    +         /* color multiply */
    +         texmodecl2 |= ctx->basecolor[0];
    +      }
    +   }
    +   else
    +   {
    +      if(0 != (flags & d2_bf_colorize2))
    +      {
    +         /* color blend */
    +         texmodecl1 |= ctx->basecolor[0];
    +         texmodecl2 |= ctx->basecolor[1];
    +      }
    +      else
    +      {
    +         /* color copy */
    +         texmodecl2 |= 0x00ffffff;
    +      }
    +   }
    +
    +   /* write to context */
    +   blitcontext->texmodecl[0] = texmodecl1;
    +   blitcontext->texmodecl[1] = texmodecl2;
    +   blitcontext->internaldirty |= d2_dirty_premalpha_t | d2_dirty_material;
    +
    +   /* calc mapping parameters */
    +   dxu = 65536;
    +   dyv = 65536;
    +   u0  = 0;
    +   v0  = 0;
    +
    +   sw = D2_FIX4( srcwidth );      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   sh = D2_FIX4( srcheight );     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +   if( (d2_u16)dstwidth > D2_FIX4(1) )
    +   {
    +      dxu = (d2_s32) ( ((d2_u32)D2_FIX16(sw)) / ((d2_u16)dstwidth) );     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/   
    +      u0  = dxu / 2;  /* offset by half a pixel step, as we sample in the center of our pixels */
    +   }
    +   if(dstheight > D2_FIX4(1))
    +   {
    +      dyv = (d2_s32) ( ((d2_u32)D2_FIX16(sh)) / ((d2_u16)dstheight) );    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      v0  = dyv / 2;  /* offset by half a pixel step, as we sample in the center of our pixels */
    +   }
    +
    +   /* handle possible mirroring */
    +   if(0 != (flags & d2_bf_mirroru))
    +   {
    +	   dxu = -dxu;
    +	   u0 = D2_FIX16(srcwidth)-u0;     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   }
    +   if(0 != (flags & d2_bf_mirrorv))
    +   {
    +	   dyv = -dyv;
    +	   v0 = D2_FIX16(srcheight)-v0;    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   }
    +
    +   /* filtering: offset by -1/2 texel compared to nearest neighbour, to position the 2x2 kernel correctly */
    +   if(0 != (flags & d2_bf_filteru))
    +   {  
    +      u0 -= D2_FIX16(1)/2;     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   }
    +   if(0 != (flags & d2_bf_filterv))
    +   {  
    +      v0 -= D2_FIX16(1)/2;     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   }
    +
    +   /* apply possible shift in source */
    +   if(0 != isRLE)
    +   {
    +      u0 += D2_FIX16((d2_s32)srcx);    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      v0 += D2_FIX16((d2_s32)srcy);    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   }
    +
    +   /* setup mapping parameters */
    +   (void)d2_settexturemapping( handle, dstx, dsty, u0, v0, dxu, 0, 0, dyv );
    +
    +   /* do blit */
    +   (void)d2_renderbox_intern( (d2_devicedata*)handle, blitcontext, dstx, dsty, dstwidth, dstheight );
    +
    +   /* restore state */
    +#ifdef D2_USEBLITBACKUPCONTEXT
    +   D2_DEV(handle)->ctxselected = backup_context;
    +
    +   blitcontext->texclut_cached = NULL;
    +#else
    +   /* restore from stack */
    +   if(backup_context && (0 == (d2_bf_no_blitctxbackup & flags)))
    +   {
    +      ctx->fillmode        = backup_context->fillmode;       
    +      ctx->internaldirty   = backup_context->internaldirty;  
    +      ctx->features        = backup_context->features;       
    +      ctx->texcenterx      = backup_context->texcenterx;     
    +      ctx->texcentery      = backup_context->texcentery;     
    +      ctx->tbstylemask     = backup_context->tbstylemask;    
    +      ctx->texbpp          = backup_context->texbpp;         
    +      ctx->texwrapmask     = backup_context->texwrapmask;    
    +      ctx->texmodemask     = backup_context->texmodemask;    
    +      ctx->texmode         = backup_context->texmode;        
    +      ctx->texpitch        = backup_context->texpitch;       
    +      ctx->texwidth        = backup_context->texwidth;       
    +      ctx->texheight       = backup_context->texheight;      
    +      ctx->texbase         = backup_context->texbase;        
    +      ctx->texsubppb       = backup_context->texsubppb;      
    +      ctx->rlebpp          = backup_context->rlebpp;         
    +      ctx->rlemask         = backup_context->rlemask;        
    +      ctx->clutmask        = backup_context->clutmask;       
    +      ctx->cr2mask         = backup_context->cr2mask;        
    +      ctx->texmodecl[0]    = backup_context->texmodecl[0];   
    +      ctx->texmodecl[1]    = backup_context->texmodecl[1];   
    +      ctx->texlim[0].x1    = backup_context->texlim[0].x1;   
    +      ctx->texlim[0].y1    = backup_context->texlim[0].y1;   
    +      ctx->texlim[0].xadd2 = backup_context->texlim[0].xadd2;
    +      ctx->texlim[0].yadd2 = backup_context->texlim[0].yadd2;
    +      ctx->texlim[0].xadd  = backup_context->texlim[0].xadd; 
    +      ctx->texlim[0].yadd  = backup_context->texlim[0].yadd; 
    +      ctx->texlim[1].xadd  = backup_context->texlim[1].xadd; 
    +      ctx->texlim[1].yadd  = backup_context->texlim[1].yadd; 
    +   }
    +   else
    +   {
    +      (void)d2_setfillmode( handle, fillmode_b); 
    +   }
    +
    +#endif
    +
    +   return D2_OK;
    +}
    diff --git a/src/drivers/dave2d/src/dave_box.c b/src/drivers/dave2d/src/dave_box.c
    new file mode 100644
    index 000000000..eb3a17e84
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_box.c
    @@ -0,0 +1,413 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_box.c (%version: 17 %)
    + *          created Wed Jan 19 13:09:06 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Jan 05 13:49:37 2007 %  (%derived_by:  hh04027 %)
    + *
    + *  2008-01-10 ASc  removed tabs, changed C++ to C comments, fixed small
    + *                  bug when using clearing optimizations
    + *  2008-01-10 ASc  fixed bug in d2_clearbox_intern
    + *  2010-09-24 MRe  removed inline from function d2_renderbox_inline
    + *  2010-09-30 MRe  fix: optimized clear not allowed for unaligned fb start and width
    + *  2012-09-25 BSp  MISRA cleanup
    + *  2013-03-15 MRe  fix d2_clear: insert dlist waits
    + *  2017-07-27 HFu  clearly commented and renamed d2_insertwait...dlist_intern functions 
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_viewport.h"
    +#include "dave_render.h"
    +#include "dave_pattern.h"
    +#include "dave_box.h"
    +#include "dave_texture.h"
    +#include "dave_polyline.h"
    +
    +/*--------------------------------------------------------------------------*/
    +
    +static void d2_clearbox_intern( d2_devicedata *handle, const d2_contextdata *ctx, d2_color clearcol );
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderbox_inline( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +   d2_bbox bbox;
    +   d2_s32 xas,yas;
    +   d2_u32 control;
    +   d2_point x2,y2;
    +
    +   /* reject invisible */
    +   if (((d2_u16)w < D2_EPSILON) || (h < D2_EPSILON))
    +   {
    +      return 0;
    +   }
    +   w = (d2_width)(w-D2_FIX4(1));
    +   h = (d2_width)(h-D2_FIX4(1));
    +
    +   /* find endpoint */
    +   x2 = (d2_point)(x1 + w);
    +   y2 = (d2_point)(y1 + h);
    +
    +   /* find bounding box */
    +   bbox.xmin = (d2_s16) D2_FLOOR4( x1 );
    +   bbox.ymin = (d2_s16) D2_FLOOR4( y1 );
    +   bbox.xmax = (d2_s16) D2_CEIL4( x2 );
    +   bbox.ymax = (d2_s16) D2_CEIL4( y2 );
    +
    +   /* clipping */
    +   if (! d2_clipbbox_intern( handle, &bbox ) )
    +   {
    +      return 0;
    +   }
    +
    +   /* set register values (material parameters) */
    +   d2_setupmaterial_intern( handle, ctx );
    +
    +   /* check for xaxis/yaxis subpixels (0 if none) */
    +   if(0 != (ctx->features & d2_feat_aa))
    +   {
    +      xas = (d2_s32) D2_FRAC4( (d2_u32)x1 | (d2_u32)x2 );
    +      yas = (d2_s32) D2_FRAC4( (d2_u32)y1 | (d2_u32)y2 );
    +   }
    +   else
    +   {
    +      xas = 0;
    +      yas = 0;
    +   }
    +
    +   /* special case blurred boxes */
    +   if(0 != (ctx->features & d2_feat_blur))
    +   {
    +      D2_DLISTWRITES( D2_L1START, (d2_s32)( ((((d2_u32)(bbox.xmin - x1)) * ctx->invblur) >> 4) + ctx->invblur ) );
    +      D2_DLISTWRITES( D2_L1XADD , (d2_s32) ctx->invblur );
    +      D2_DLISTWRITES( D2_L1YADD , 0 );
    +
    +      D2_DLISTWRITES( D2_L2START, (d2_s32)( ((((d2_u32)(x2 - bbox.xmin)) * ctx->invblur) >> 4) + ctx->invblur ) );
    +      D2_DLISTWRITES( D2_L2XADD , -(d2_s32)ctx->invblur );
    +      D2_DLISTWRITES( D2_L2YADD , 0 );
    +
    +      D2_DLISTWRITES( D2_L3START, (d2_s32)( ((((d2_u32)(bbox.ymin - y1)) * ctx->invblur) >> 4) + ctx->invblur ) );
    +      D2_DLISTWRITES( D2_L3XADD , 0 );
    +      D2_DLISTWRITES( D2_L3YADD , (d2_s32) ctx->invblur );
    +
    +      D2_DLISTWRITES( D2_L4START, (d2_s32)( ((((d2_u32)(y2 - bbox.ymin)) * ctx->invblur) >> 4) + ctx->invblur ) );
    +      D2_DLISTWRITES( D2_L4XADD , 0 );
    +      D2_DLISTWRITES( D2_L4YADD , -(d2_s32)ctx->invblur );
    +
    +      control = d2_initgradients_intern( handle, ctx, &bbox, 4, D2C_LIM1ENABLE | D2C_LIM2ENABLE | D2C_LIM3ENABLE | D2C_LIM4ENABLE );
    +   }
    +   else
    +   {
    +      /* choose optimal limiter count */
    +      if(0 == xas)
    +      {
    +         if(0 == yas)
    +         {
    +            /* no subpixel positioning */
    +
    +            control = d2_initgradients_intern( handle, ctx, &bbox, 0, 0 );
    +         }
    +         else
    +         {
    +            /* yaxis subpixel only */
    +
    +            D2_DLISTWRITES( D2_L1START, (d2_s32)( ((((d2_u32)(bbox.ymin - y1)) << (16-4)) + D2_FIX16(1)) ) );
    +            D2_DLISTWRITES( D2_L1XADD , D2_FIX16(0) );
    +            D2_DLISTWRITES( D2_L1YADD , D2_FIX16(1) );
    +
    +            D2_DLISTWRITES( D2_L2START, (d2_s32)( ((((d2_u32)(y2 - bbox.ymin)) << (16-4)) + D2_FIX16(1)) ) );
    +            D2_DLISTWRITES( D2_L2XADD , D2_FIX16(0) );
    +            D2_DLISTWRITES( D2_L2YADD , D2_FIX16(-1) );   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +            control = d2_initgradients_intern( handle, ctx, &bbox, 2, D2C_LIM1ENABLE | D2C_LIM2ENABLE );
    +         }
    +      }
    +      else
    +      {
    +         if(0 == yas)
    +         {
    +            /* xaxis subpixel only */
    +            D2_DLISTWRITES( D2_L1START, (d2_s32)( ((((d2_u32)(bbox.xmin - x1)) << (16-4)) + D2_FIX16(1)) ) );
    +            D2_DLISTWRITES( D2_L1XADD , D2_FIX16(1) );   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            D2_DLISTWRITES( D2_L1YADD , D2_FIX16(0) );
    +
    +            D2_DLISTWRITES( D2_L2START, (d2_s32)( ((((d2_u32)(x2 - bbox.xmin)) << (16-4)) + D2_FIX16(1)) ) );
    +            D2_DLISTWRITES( D2_L2XADD , D2_FIX16(-1) );  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            D2_DLISTWRITES( D2_L2YADD , D2_FIX16(0) );
    +
    +            control = d2_initgradients_intern( handle, ctx, &bbox, 2, D2C_LIM1ENABLE | D2C_LIM2ENABLE );
    +         }
    +         else
    +         {
    +            /* full subpixel positioning */
    +
    +            D2_DLISTWRITES( D2_L1START, (d2_s32)( (((d2_u32)(bbox.xmin - x1)) << (16-4)) + D2_FIX16(1) ) );
    +            D2_DLISTWRITES( D2_L1XADD , D2_FIX16(1) );   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            D2_DLISTWRITES( D2_L1YADD , D2_FIX16(0) );
    +
    +            D2_DLISTWRITES( D2_L2START, (d2_s32)( (((d2_u32)(x2 - bbox.xmin)) << (16-4)) + D2_FIX16(1) ) );
    +            D2_DLISTWRITES( D2_L2XADD , D2_FIX16(-1) );  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            D2_DLISTWRITES( D2_L2YADD , D2_FIX16(0) );
    +
    +            D2_DLISTWRITES( D2_L3START, (d2_s32)( (((d2_u32)(bbox.ymin - y1)) << (16-4)) + D2_FIX16(1) ) );
    +            D2_DLISTWRITES( D2_L3XADD , D2_FIX16(0) );
    +            D2_DLISTWRITES( D2_L3YADD , D2_FIX16(1) );   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +            D2_DLISTWRITES( D2_L4START, (d2_s32)( (((d2_u32)(y2 - bbox.ymin)) << (16-4)) + D2_FIX16(1) ) );
    +            D2_DLISTWRITES( D2_L4XADD , D2_FIX16(0) );
    +            D2_DLISTWRITES( D2_L4YADD , D2_FIX16(-1) );  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ 
    +
    +            control = d2_initgradients_intern( handle, ctx, &bbox, 4, D2C_LIM1ENABLE | D2C_LIM2ENABLE | D2C_LIM3ENABLE | D2C_LIM4ENABLE );
    +         }
    +      }
    +   }
    +
    +   /* setup pattern/texture if used */
    +   d2_setuppattern( handle, ctx, &bbox, 0 );
    +   d2_setuptexture( handle, ctx, &bbox, 0 );
    +
    +   /* render */
    +   D2_DLISTWRITEU( D2_CONTROL, control );
    +   d2_startrender_intern( handle, &bbox, 0 );
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static void d2_clearbox_intern( d2_devicedata *handle, const d2_contextdata *ctx, d2_color clearcol )
    +{
    +   d2_bbox  bbox;
    +   d2_s32      s;
    +
    +   /* unused parameter */
    +   (void) ctx;   /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +
    +   /* always clear entier cliprect area */
    +   bbox.xmin = handle->clipxmin;
    +   bbox.xmax = handle->clipxmax;
    +   bbox.ymin = handle->clipymin;
    +   bbox.ymax = handle->clipymax;
    +
    +   /* find scaling for size in bpp4 */
    +   s = (4 / handle->bpp);
    +
    +   /* check if optimisation is applicable (no pitch) */
    +   if (((handle->flags & d2_df_no_dwclear) == 0) &&
    +       (handle->bpp < 4) &&
    +       (((handle->pitch / s) * s) == handle->pitch)  &&            /* pitch must be divisible by s without remainder */
    +       (((d2_u32)handle->framebuffer & (~3u)) == (d2_u32)handle->framebuffer) && /* fb start must be divisible by 4 */
    +       ((handle->fbwidth & (~3u)) == handle->fbwidth) &&   /* width must be divisible by 4 */
    +       ( D2_INT4(bbox.xmin) == 0 ) &&                          /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +       ( D2_INT4(bbox.xmax) == (d2_s32)(handle->fbwidth-1) ))  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   {
    +      d2_color dblcolor;
    +      d2_s32 w,h;
    +
    +      /* can fill using bpp4. convert color */
    +      switch (handle->fbformat)
    +      {
    +         case d2_mode_alpha8:
    +            clearcol = (clearcol & 0xff000000u) >> 24;
    +            dblcolor = (clearcol << 24) | (clearcol << 16) | (clearcol << 8) | (clearcol);
    +            break;
    +
    +         case d2_mode_argb4444:
    +         case d2_mode_rgb444:
    +            clearcol = (((clearcol & 0xf0000000u) >> 16) |
    +                        ((clearcol & 0x00f00000u) >> 12) |
    +                        ((clearcol & 0x0000f000u) >> 8) |
    +                        ((clearcol & 0x000000f0u) >> 4));
    +            dblcolor = (clearcol << 16) | (clearcol);
    +            break;
    +
    +         case d2_mode_rgba4444:
    +            clearcol = (((clearcol & 0xf0000000u) >> 28) |
    +                        ((clearcol & 0x00f00000u) >> 8) |
    +                        ((clearcol & 0x0000f000u) >> 4) |
    +                        ((clearcol & 0x000000f0u) >> 0));
    +            dblcolor = (clearcol << 16) | (clearcol);
    +            break;
    +
    +         case d2_mode_rgb565:
    +            clearcol = (((clearcol & 0x00f80000u) >> 8) |
    +                        ((clearcol & 0x0000fc00u) >> 5) |
    +                        ((clearcol & 0x000000f8u) >> 3));
    +            dblcolor = (clearcol << 16) | (clearcol);
    +            break;
    +
    +         case d2_mode_rgba8888:
    +            dblcolor = (clearcol<<8) | (clearcol>>24);
    +            break;
    +
    +         default:
    +            dblcolor = clearcol;
    +            break;
    +      }
    +
    +      /* find size */
    +      w = D2_INT4( bbox.xmax - bbox.xmin ) + 1;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      h = D2_INT4( bbox.ymax - bbox.ymin ) + 1;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +      /* insert dlist wait */
    +      (void)d2_insertwaitpipedlist_intern( handle );
    +
    +      /* start optimized clear */
    +      D2_DLISTWRITES( D2_COLOR1, (d2_s32) dblcolor );
    +      D2_DLISTWRITES( D2_CONTROL, 0 );
    +      D2_DLISTWRITES( D2_CONTROL2, D2C_WRITEFORMAT2 | D2C_BDI | D2C_WRITEALPHA1 | D2C_RLE_ENABLE );  /* D2C_RLE_ENABLE seems irrelevant here but is necessary for a HW issue: Mantis #1416 */
    +      D2_DLISTWRITES( D2_PITCH, (d2_s32)( ((d2_u32)(handle->pitch / s)) & 0xffffu ) );
    +      D2_DLISTWRITES( D2_SIZE,  (d2_s32)( ((d2_u32)h << 16) | ((d2_u32)w / (d2_u32)s) ) );
    +
    +      /* start rendering */
    +      switch (handle->bpp)
    +      {
    +         case 1:
    +            D2_DLISTWRITES(  D2_ORIGIN, (d2_s32) (((d2_s8*)handle->framebuffer) + D2_INT4(bbox.xmin) + (D2_INT4(bbox.ymin) * handle->pitch)) );  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            break;
    +
    +         case 2:
    +            D2_DLISTWRITES(  D2_ORIGIN, (d2_s32) (((d2_s16*)handle->framebuffer) + D2_INT4(bbox.xmin) + (D2_INT4(bbox.ymin) * handle->pitch)) ); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            break;
    +
    +         case 4:
    +            D2_DLISTWRITES(  D2_ORIGIN, (d2_s32) (((d2_s32*)handle->framebuffer) + D2_INT4(bbox.xmin) + (D2_INT4(bbox.ymin) * handle->pitch)) ); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            break;
    +
    +         default:
    +            break;
    +      }
    +
    +      /* insert dlist wait */
    +      (void)d2_insertwaitpipedlist_intern( handle );
    +   }
    +   else
    +   {
    +      (void)d2_insertwaitpipedlist_intern( handle );
    +      /* direct clear (special setup for clear material) */
    +      D2_DLISTWRITES( D2_COLOR1, (d2_s32) clearcol );
    +      D2_DLISTWRITES( D2_CONTROL, 0 );
    +      D2_DLISTWRITES( D2_CONTROL2, (d2_s32) (D2_DEV(handle)->fbstylemask | D2C_BDI | D2C_WRITEALPHA1 | D2C_RLE_ENABLE) );  /* D2C_RLE_ENABLE seems irrelevant here but is necessary for a HW issue: Mantis #1416 */
    +      d2_startrender_intern( handle, &bbox, 0 );
    +      (void)d2_insertwaitpipedlist_intern( handle );
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderbox_intern(  d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +   return d2_renderbox_inline( D2_DEV(handle), ctx, x1, y1, w, h );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderbox_solid( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +   (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, w, h );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderbox_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +   (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(D2_DEV(handle)->soffx + x1), (d2_point)(D2_DEV(handle)->soffy + y1), w, h );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderbox_outline( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +   d2_width wo = D2_DEV(handle)->outlinewidth;
    +   d2_contextdata *ctx = D2_DEV(handle)->ctxoutline;
    +   d2_point verts[4 * 2];
    +
    +   /* render outline */
    +   if (wo >= D2_EPSILON)
    +   {
    +      d2_width woh = wo / 2;
    +
    +      if( (wo == D2_FIX4(1)) || 
    +          (
    +             (ctx->linejoin == d2_lj_miter)       && 
    +             (ctx->miterlimit > wo )              && 
    +             (0 == (ctx->features & d2_feat_blur))
    +           )
    +          )
    +      {
    +         /* render outline with thin boxs (optimal performance) */
    +         (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 - wo), (d2_point)(y1 - wo), wo, (d2_width)(h + (2 * wo)) );  /*left */
    +         (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1, (d2_point)(y1 - wo), w, wo );                    /*top */
    +         (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 + w), (d2_point)(y1 - wo), wo, (d2_width)(h + (2*wo)) );     /*right */
    +         (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1, (d2_point)(y1 + h), w, wo );                     /*bottom */
    +      }
    +      else
    +      {
    +         /* render outline as polyline (supports linejoins) */
    +         verts[0] = (d2_point)((x1     - woh) - 8);    verts[1] = (d2_point)((y1     - woh) - 8);   /* (note) parentheses added for MISRA compliance.. */
    +         verts[2] = (d2_point)((x1 + w) + (woh - 8));  verts[3] = (d2_point)((y1     - woh) - 8);
    +         verts[4] = (d2_point)((x1 + w) + (woh - 8));  verts[5] = (d2_point)((y1 + h) + (woh - 8));
    +         verts[6] = (d2_point)((x1     - woh) - 8);    verts[7] = (d2_point)((y1 + h) + (woh - 8));
    +
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 4, wo, d2_le_closed, 0,0 );
    +      }
    +   }
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderbox_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +
    +   /* render outline part */
    +   (void)d2_renderbox_outline( D2_DEV(handle), x1, y1, w, h );
    +
    +   /* render solid [base part] extended by one pixel */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxsolid, (d2_point)(x1 - 16), (d2_point)(y1 - 16), (d2_width)(w + 32), (d2_width)(h + 32) );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderbox_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +   /* render shadow */
    +   (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(D2_DEV(handle)->soffx + x1), (d2_point)(D2_DEV(handle)->soffy + y1), w, h );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderbox_inline( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, w, h );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_clearbox_solid( d2_device *handle, d2_color clearcolor )
    +{
    +   d2_clearbox_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, clearcolor );
    +
    +   return D2_OK;
    +}
    diff --git a/src/drivers/dave2d/src/dave_circle.c b/src/drivers/dave2d/src/dave_circle.c
    new file mode 100644
    index 000000000..c9c665e63
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_circle.c
    @@ -0,0 +1,291 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_circle.c (%version: 15 %)
    + *          created Wed Jan 12 15:53:43 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jan 04 16:46:49 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2008-09-25 MRe  added  ctx->circleextendoffset
    + *  2008-10-02 MRe  fix of blurred circles
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_viewport.h"
    +#include "dave_render.h"
    +#include "dave_pattern.h"
    +#include "dave_circle.h"
    +#include "dave_curve.h"
    +#include "dave_texture.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendercircle_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x, d2_point y, d2_width r, d2_width w )
    +{
    +   d2_bbox bbox;
    +   d2_u32 delay;
    +   d2_u32 control;
    +   d2_u32 tmask;
    +   d2_s32 bbox_enlarge=0;
    +
    +   /* check for circle ring */
    +   if (w > 0)
    +   {
    +      /* ring bounding box */
    +      d2_width wh = w/2;
    +      d2_width wr = (d2_width)(wh + r);
    +      bbox.xmin = (d2_point) D2_FLOOR4( x - wr );
    +      bbox.ymin = (d2_point) D2_FLOOR4( y - wr );
    +      bbox.xmax = (d2_point) D2_CEIL4( x + wr );
    +      bbox.ymax = (d2_point) D2_CEIL4( y + wr );
    +
    +      if( (r - wh) <= (D2_FIX4(1)/2) )
    +      {
    +         /* invalid ring, use full circle */
    +         r = (d2_width)(r + wh);
    +         w = 0;
    +      }
    +   }
    +   else
    +   {
    +      /* solid circle bounding box */
    +      bbox.xmin = (d2_point) D2_FLOOR4( x - r );
    +      bbox.ymin = (d2_point) D2_FLOOR4( y - r );
    +      bbox.xmax = (d2_point) D2_CEIL4( x + r );
    +      bbox.ymax = (d2_point) D2_CEIL4( y + r );
    +   }
    +
    +   if(ctx->circleextendoffset > 0)
    +   { 
    +      /* enlarge bbox to avoid cropping due to insufficient accuracy for big circles */
    +      bbox_enlarge = ctx->circleextendoffset;
    +      /* bbox_enlarge = (bbox_enlarge > ((256 * 128) - 1)) ? ((256 * 128) - 1) : bbox_enlarge; */ /* (note) dead code since bbox_enlarge is a 16bit signed integer */
    +                      
    +      if( ((d2_s32)(bbox.xmin) - bbox_enlarge) < (d2_s32)(handle->clipxmin))
    +      {
    +         bbox.xmin = handle->clipxmin;
    +      }
    +      else
    +      {
    +         bbox.xmin = (d2_point)(bbox.xmin - (d2_point)bbox_enlarge);
    +      }
    +      
    +      if( ((d2_s32)(bbox.ymin) - bbox_enlarge) < (d2_s32)(handle->clipymin) )
    +      {
    +         bbox.ymin = handle->clipymin;
    +      }
    +      else
    +      {
    +         bbox.ymin = (d2_point)(bbox.ymin - (d2_point)bbox_enlarge);
    +      }
    +      
    +      if( ((d2_s32)(bbox.xmax)+bbox_enlarge) > (d2_s32)(handle->clipxmax) )
    +      {
    +         bbox.xmax = handle->clipxmax; 
    +      }
    +      else
    +      {
    +         bbox.xmax = (d2_point)(bbox.xmax + (d2_point)bbox_enlarge);
    +      }
    +
    +      if( ((d2_s32)(bbox.ymax) + bbox_enlarge) > (d2_s32)(handle->clipymax) )
    +      {
    +         bbox.ymax = handle->clipymax;
    +      }
    +      else
    +      {
    +         bbox.ymax = (d2_point)(bbox.ymax + (d2_point)bbox_enlarge);
    +      }
    +   }
    +
    +   /* clipping */
    +   if(0 == d2_clipbbox_intern( handle, &bbox ))
    +   {
    +      return 0;
    +   }
    +
    +   /* make relative */ 
    +   x = (d2_point)(x - bbox.xmin);
    +   y = (d2_point)(y - bbox.ymin);
    +
    +   /* set register values (material parameters) */
    +   d2_setupmaterial_intern( handle, ctx );
    +   tmask = ctx->thresholdmask;
    +
    +   if(0 == w)
    +   {
    +      /* solid circle */
    +
    +      /* set register values (geometric parameters) */
    +      d2_circlesetup_intern(handle, ctx, 0, x, y, r, 0, 0, 1);
    +
    +      control = D2C_LIM1ENABLE  | D2C_QUAD1ENABLE | D2C_SPANABORT | D2C_SPANSTORE | (tmask & D2C_LIM1THRESHOLD);
    +
    +      if(0 != (D2_DEV(handle)->hwrevision & D2FB_HILIMITERPRECISION))
    +      {
    +         control |= (0 != (ctx->features & d2_feat_blur)) ? D2C_LIMITERPRECISION : 0;
    +      }
    +
    +      control = d2_initgradients_intern( handle, ctx, &bbox, 2, control );
    +
    +      D2_DLISTWRITES( D2_CONTROL, (d2_s32)control );
    +
    +      delay = D2_CEIL4( r+bbox_enlarge ) >> 4;
    +   }
    +   else
    +   {
    +      /* circle ring */
    +
    +      /* determine whether we can use bandfilter (2lim) ring without distortion
    +       * this is the case if r/w is larger than sqrt(r) */
    +      if( (r > (w * w)) && (0 == (ctx->features & d2_feat_blur)) )
    +      {
    +         /* 2lim ring */
    +         r = (d2_width)(r+D2_EPSILON);
    +         /* set register values (geometric parameters) */
    +         d2_circlesetup_intern(handle, ctx, 0, x, y, r, (d2_s32) (((d2_u32)((w + D2_FIX4(1)) / 2)) << (16-4)), 0, 1 );
    +
    +         control = D2C_LIM1ENABLE | D2C_QUAD1ENABLE | D2C_BAND1ENABLE | (tmask & D2C_LIM1THRESHOLD);
    +         control = d2_initgradients_intern( handle, ctx, &bbox, 2, control );
    +
    +         D2_DLISTWRITES( D2_L1BAND, w * 4096 ); /* w << (16-4) */
    +         D2_DLISTWRITES( D2_CONTROL, (d2_s32)control );
    +
    +         delay = 0;
    +      }
    +      else
    +      {
    +         /* 4lim ring (more accurate)
    +          * set register values (geometric parameters) */
    +         d2_circlesetup_intern(handle, ctx, 0, x, y, (d2_width)(r + (w / 2)), 0, 0, 1 );
    +
    +         /* inner circle */
    +         d2_circlesetup_intern(handle, ctx, 2, x, y, (d2_width)(r - (w / 2)), (-D2_FIX16(1)) / 2, 1, 1 );
    +
    +         control = D2C_LIM1ENABLE | D2C_QUAD1ENABLE | D2C_LIM3ENABLE | D2C_QUAD2ENABLE | (tmask & (D2C_LIM1THRESHOLD|D2C_LIM3THRESHOLD));
    +
    +         if(0 != (D2_DEV(handle)->hwrevision & D2FB_HILIMITERPRECISION) )
    +         {
    +            control |= (0 != (ctx->features & d2_feat_blur)) ? D2C_LIMITERPRECISION : 0;
    +         }
    +
    +         control = d2_initgradients_intern( handle, ctx, &bbox, 4, control );
    +
    +         D2_DLISTWRITES( D2_CONTROL, (d2_s32)control );
    +
    +         delay = 0;
    +      }
    +   }
    +
    +   /* start rendering */
    +   d2_setuppattern( handle, ctx, &bbox, 0 );
    +   d2_setuptexture( handle, ctx, &bbox, 0 );
    +   d2_startrender_intern( handle, &bbox, delay );
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendercircle_solid( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w )
    +{
    +   (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x, y, r, w );
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendercircle_shadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w )
    +{
    +   (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline,
    +                                 (d2_point)(D2_DEV(handle)->soffx + x),
    +                                 (d2_point)(D2_DEV(handle)->soffy + y),
    +                                 r, w );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendercircle_outline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w )
    +{
    +   d2_width wo = D2_DEV(handle)->outlinewidth;
    +
    +   /* skip invisible cases */
    +   if(wo < D2_EPSILON)
    +   {
    +      return D2_OK;
    +   }
    +
    +   if(w > 0)
    +   {
    +      /* circle ring: we also need an outline at the inside */
    +      (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline,
    +                                    x, y, (d2_width)((r - (w / 2)) - (wo / 2)), wo
    +                                    );
    +   }
    +
    +   /* outline on the outside */
    +   (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline,
    +                                 x, y, (d2_width)((r + (w / 2)) + (wo / 2)), wo
    +                                 );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendercircle_solidoutline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w )
    +{
    +   d2_width wo = D2_DEV(handle)->outlinewidth;
    +
    +   /* render pre outline */
    +   if( (w > 0) && (wo > 0) )
    +   {
    +      /* circle rings only */
    +      (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x, y, r, (d2_width)((wo * 2) + w) );
    +   }
    +   if( (0 == w) && (wo > 0) )
    +   {
    +      /* solid circles only */
    +      (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x, y, (d2_width)(r + ((wo - 16) / 2)), (d2_width)(wo + (16 / 2)) );
    +   }
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x, y, r, w );
    +   d2_rendertobase_intern( handle );
    +
    +   /* render post outline */
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendercircle_solidshadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w )
    +{
    +   /* render shadow */
    +   (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline,
    +                                 (d2_point)(D2_DEV(handle)->soffx + x),
    +                                 (d2_point)(D2_DEV(handle)->soffy + y),
    +                                 r, w
    +                                 );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_rendercircle_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x, y, r, w );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    diff --git a/src/drivers/dave2d/src/dave_context.c b/src/drivers/dave2d/src/dave_context.c
    new file mode 100644
    index 000000000..68cfb1f9a
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_context.c
    @@ -0,0 +1,2193 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_context.c (%version: 42 %)
    + *          created Tue Jan 11 16:25:20 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Dec 12 13:43:03 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2007-12-05 ASc  bugfix: return correct value in d2_getlinejoin,
    + *                  fix description for d2_getpatternsize and d2_setpatternsize
    + *  2007-12-06 ASc  bugfix: d2_getcontext did not return outline context
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs 
    + *  2008-09-25 MRe  added d2_setcircleextend
    + *  2010-02-18 MRe  added true alpha blending to d2_setalphablendmode
    + *  2010-03-01 MRe  added d2_getalphablendmodesrc, d2_getalphablendmodedst,
    + *  2010-03-18 MRe  added d2_setalphablendmodeex, d2_getalphablendmodeflags
    + *  2011-09-22 MRe  fixed default for ctx->texmodemask
    + *  2012-09-25 BSp  MISRA cleanup
    + */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Context Functions
    + * Modify material settings
    + *
    + * Rendering attributes (like color, pattern, blendmodes) are stored inside a *context*.
    + * A context is a collection of material attributes and must not be mistaken with a device handle.
    + * A device handle (see: <Device management>) is the root of all process dependant data and is passed 
    + * as first parameter to every function. 
    + * This construct allows the driver functions to be reentrant in case of a multiple drawing engine units.
    + * 
    + * A device handle contains information about displaylists, framebuffers,etc... 
    + * Everything that the drawing engine will require. It also includes pointers to contexts.
    + *
    + * Each device has at all times pointers to three relevant context's :
    + *
    + *  selected context - This one is changed (written to) by the set commands shown below (see: <d2_selectcontext>)
    + *  solid context - Used as a source (read from) when rendering interior regions (see: <d2_solidcontext>)
    + *  outline context - Used as a source (read from) when rendering outlines or shadows (see: <d2_outlinecontext>)
    + *
    + * All three (selected, solid and outline) can point to the same context.
    + * Every driver function that starts with *get* or *set* will work on the currently selected context (with
    + * the obvious exception of geterror and getversion).
    + *
    + * There is always a *default context* that can not be freed by the application and is used for
    + * everything per default.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_memory.h"
    +#include "dave_texture.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + * Group: Context Management */
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_newcontext
    + * Create new context (used to store render settings).
    + *
    + * Note that every context is bound to the device it is created for and can not be
    + * used in another process or selected into any other device.
    + * Every new context is reset to a default state, it does not reflect the currently
    + * selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   context pointer or NULL in case of an error
    + * */
    +d2_context * d2_newcontext( d2_device *handle )
    +{
    +   d2_contextdata *ctx = (d2_contextdata *) d2_getmem_p( sizeof(d2_contextdata) );
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   if (!ctx)
    +   {
    +      (void)D2_SETERR(handle, D2_NOMEMORY);
    +      return NULL;
    +   }
    +
    +   /* initialize context */
    +   ctx->device = D2_DEV(handle);
    +   ctx->basecolor[0]    = 0xffffff;
    +   ctx->basecolor[1]    = 0xffffff;
    +   ctx->basealpha[0]    = 0xff;
    +   ctx->basealpha[1]    = 0xff;
    +   ctx->constalpha      = 0xff000000u;
    +   ctx->patternalpha[0] = 0xff;
    +   ctx->patternalpha[1] = 0xff;
    +   ctx->premalpha[0]    = 0xff000000u;
    +   ctx->premalpha[1]    = 0xff000000u;
    +   ctx->features        = d2_feat_aa;
    +   ctx->thresholdmask   = 0;
    +   ctx->internaldirty   = 0;
    +   ctx->blurring        = D2_FIX4( 1 );
    +   ctx->invblur         = D2_FIX16( 1u );
    +   ctx->blendmask       = D2C_BSF | D2C_BDF | D2C_BDI;
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_ALPHACHANNELBLENDING))
    +   {
    +      ctx->alphablendmask = D2C_WRITEALPHA1;
    +   }
    +   else
    +   {
    +      ctx->alphablendmask  = D2C_USE_ACB | D2C_BDIA;
    +      ctx->alphablendmask |= D2C_WRITEALPHA1;
    +   }
    +   ctx->texmodemask        = D2C_TEXTUREFILTERX | D2C_TEXTUREFILTERY | D2C_TEXTURECLAMPX | D2C_TEXTURECLAMPY;
    +   ctx->texbpp             = 4;
    +   ctx->tbstylemask        = D2C_READFORMAT2;
    +   ctx->rlemask            = 0;
    +   ctx->clutmask           = 0;
    +   ctx->colkeymask         = 0;
    +   ctx->cr2mask            = D2_DEV(handle)->fbstylemask | ctx->alphablendmask | ctx->blendmask | ctx->tbstylemask | ctx->rlemask | ctx->clutmask | ctx->colkeymask;
    +   ctx->gradients          = 0;
    +   ctx->alphamode          = d2_am_constant;
    +   ctx->fillmode           = d2_fm_color;
    +   ctx->alphablendflags    = d2_blendf_default;
    +   ctx->pattern            = 0xAA;
    +   ctx->orgpattern         = 0xAA;
    +   ctx->patmode            = d2_pm_filter;
    +   ctx->patmodemask        = D2C_TEXTUREFILTERX;
    +   ctx->patoffset          = 0;
    +   ctx->patscale           = D2_FIX4(1);
    +   ctx->invpatscale        = D2_FIX16( 1 );
    +   ctx->patlen             = 4;
    +   ctx->linecap            = d2_lc_square;
    +   ctx->linejoin           = d2_lj_miter;
    +   ctx->miterlimit         = D2_FIX4(4);
    +   ctx->circleextendoffset = 0;
    +   ctx->roundends          = 0;
    +   ctx->texcenterx         = 0;
    +   ctx->texcentery         = 0;
    +   ctx->texclut            = NULL;
    +   ctx->texclut_cached     = NULL;
    +   ctx->texclutupload      = 1;
    +   ctx->texclutoffset      = 0;
    +   ctx->colorkey           = 0;
    +
    +   d2_initgradient_intern( &ctx->gradient[0] );
    +   d2_initgradient_intern( &ctx->gradient[1] );
    +   d2_initgradient_intern( &ctx->gradient[2] );
    +   d2_initgradient_intern( &ctx->gradient[3] );
    +
    +   d2_initgradient_intern( &ctx->patulim[0] );
    +
    +   d2_initgradient_intern( &ctx->texlim[0] );
    +   d2_initgradient_intern( &ctx->texlim[1] );
    +
    +   /* setup initial texture blendmode */
    +   ctx->texmode = d2_tm_filter;
    +   ctx->texwrapmask = 0xffffffffu;
    +   ctx->texop_p1[0] = 0x00u;
    +   ctx->texop_p1[1] = 0x00u;
    +   ctx->texop_p1[2] = 0x00u;
    +   ctx->texop_p1[3] = 0x00u;
    +   ctx->texop_p2[0] = 0xffu;
    +   ctx->texop_p2[1] = 0xffu;
    +   ctx->texop_p2[2] = 0xffu;
    +   ctx->texop_p2[3] = 0xffu;
    +   ctx->texamode = d2_to_one;
    +   ctx->texrmode = d2_to_copy;
    +   ctx->texgmode = d2_to_copy;
    +   ctx->texbmode = d2_to_copy;
    +   d2_setuptextureblend_intern( handle, ctx );
    +
    +   /* attach to chain */
    +   ctx->next = D2_DEV(handle)->ctxchain;
    +   D2_DEV(handle)->ctxchain = ctx;
    +
    +   (void)D2_SETOK(handle);
    +   return ctx;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_freecontext
    + * Release Context.
    + *
    + * Free the memory associated with a context. If the context is still selected
    + * or an active source for rendering it is deselected (by selecting the default
    + * context instead) before destruction.
    + *
    + * All contexts assigned to a device are freed automatically when the device
    + * is closed.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ctx - context pointer
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_freecontext( d2_device *handle, d2_context *ctx )
    +{
    +   d2_contextdata **prev;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ctx, D2_INVALIDCONTEXT );   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* forbid removal of default context */
    +   if (D2_CTX(ctx) == D2_DEV(handle)->ctxdef) 
    +   {
    +      D2_RETERR( handle, D2_DEFCONTEXT );
    +   }
    +
    +   /* find in chain */
    +   prev = & D2_DEV(handle)->ctxchain;
    +   while ((prev) && (*prev != ctx))
    +   {
    +      prev = (d2_contextdata **) *prev;
    +   }
    +   if (!prev)
    +   {
    +      D2_RETERR( handle, D2_INVALIDCONTEXT );
    +   }
    +   /* remove from chain */
    +   *prev = D2_CTX(ctx)->next;
    +
    +   /* react to removal if context was active */
    +   if (D2_DEV(handle)->ctxselected == D2_CTX(ctx)) 
    +   {
    +      D2_DEV(handle)->ctxselected = D2_DEV(handle)->ctxdef;
    +   }
    +   if (D2_DEV(handle)->ctxoutline == D2_CTX(ctx))
    +   {
    +      D2_DEV(handle)->ctxoutline = D2_DEV(handle)->ctxdef;
    +   }
    +   if (D2_DEV(handle)->ctxsolid == D2_CTX(ctx))
    +   {
    +      D2_DEV(handle)->ctxsolid = D2_DEV(handle)->ctxdef;
    +   }
    +
    +   if (  D2_CTX(ctx)->texclut_cached != NULL)
    +   {
    +      d1_freemem(D2_CTX(ctx)->texclut_cached);       /*  checkit */
    +      D2_CTX(ctx)->texclut_cached = NULL;
    +   }
    +
    +   /* free context memory */
    +   d2_freemem_p( ctx );
    +   D2_RETOK(handle);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getcontext
    + * Get a pointer to an currently active context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   mode - getcontext mode determines what context should be returned
    + *
    + * getcontext modes:
    + *    d2_context_default - return the default context
    + *    d2_context_selected - return the currently selected context (see: <d2_selectcontext>)
    + *    d2_context_solid - return current solid context (see: <d2_solidcontext>)
    + *    d2_context_outline - return current outline context (see: <d2_outlinecontext>)
    + *
    + * returns:
    + *   context pointer or NULL in case of an error
    + * */
    +d2_context * d2_getcontext( d2_device *handle, d2_s32 mode )   /* PRQA S 3673 */ /* $Misra: #NOT_CONST_IN_DEBUG_BUILD $*/
    +{
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );                   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERRP( (((d2_u32)mode) < 4U), D2_INVALIDENUM );      /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch (mode)
    +   {
    +      case d2_context_default:
    +         return (d2_context*) D2_DEV(handle)->ctxdef;
    +
    +      case d2_context_selected:
    +         return (d2_context*) D2_DEV(handle)->ctxselected;
    +
    +      case d2_context_solid:
    +         return (d2_context*) D2_DEV(handle)->ctxsolid;
    +
    +      case d2_context_outline:
    +         return (d2_context*) D2_DEV(handle)->ctxoutline;
    +
    +      default:
    +         break;
    +   }
    +
    +   return NULL;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * debug inline code to verify that a given block is a valid context
    + * for the current device */
    +
    +#ifdef _DEBUG
    +#define VERIFY_CONTEXT(c)                                               \
    +   chain = D2_DEV(handle)->ctxchain;                                    \
    +   while (chain && (chain != D2_CTX(c)))                                \
    +   { chain = chain->next; }                                             \
    +   if ((!chain) || (D2_CTX(c)->device != D2_DEV(handle)))               \
    +   { D2_RETERR( handle, D2_INVALIDCONTEXT ); }(void)0 /* PRQA S 3412 */ /* $Misra: #COMPILER_WARNING $*/
    +#else
    +#define VERIFY_CONTEXT(c)                                               \
    +   chain = NULL;                                                        \
    +   (void) chain;                                                        \
    +   if (D2_CTX(c)->device != D2_DEV(handle))                             \
    +   { D2_RETERR( handle, D2_INVALIDCONTEXT ); }(void)0 /* PRQA S 3412 */ /* $Misra: #COMPILER_WARNING $*/
    +#endif
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_selectcontext
    + * Make a rendering context active (all following property set operations will use it)
    + *
    + * Selecting a context has no direct effect on how geometry is rendered (reading is done from
    + * solid and outline contexts) and is a very fast operation.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ctx - context pointer
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_solidcontext>, <d2_outlinecontext>, <d2_getcontext>
    + * */
    +d2_s32 d2_selectcontext( d2_device *handle, d2_context *ctx )
    +{
    +   d2_contextdata *chain;  /* required by 'VERIFY_CONTEXT' macro below */
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ctx, D2_INVALIDCONTEXT );   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   VERIFY_CONTEXT( ctx );                   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_DEV(handle)->ctxselected = D2_CTX(ctx);
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_solidcontext
    + * Define the solid rendering context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ctx - context pointer
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_selectcontext>, <d2_outlinecontext>, <d2_getcontext>
    + * */
    +d2_s32 d2_solidcontext( d2_device *handle, d2_context *ctx )
    +{
    +   d2_contextdata *chain;  /* required by 'VERIFY_CONTEXT' macro below */
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ctx, D2_INVALIDCONTEXT );   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   VERIFY_CONTEXT( ctx );                   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_DEV(handle)->ctxsolid = D2_CTX(ctx);
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_outlinecontext
    + * Define the outline rendering context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ctx - context pointer
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_solidcontext>, <d2_selectcontext>, <d2_getcontext>
    + * */
    +d2_s32 d2_outlinecontext( d2_device *handle, d2_context *ctx )
    +{
    +   d2_contextdata *chain;  /* required by 'VERIFY_CONTEXT' macro below */
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ctx, D2_INVALIDCONTEXT );   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   VERIFY_CONTEXT( ctx );                   /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_DEV(handle)->ctxoutline = D2_CTX(ctx);
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: Context Attribute Writes */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setfillmode
    + * Select fillmode (solid,patter,texture,..)
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   mode - fillmode
    + *
    + * fill modes:
    + *
    + *   d2_fm_color - single color (default)
    + *   d2_fm_twocolor - blending between color1 and color2 instead of color1 and background
    + *   d2_fm_pattern - fill with pattern
    + *   d2_fm_texture - fill with texture
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setfillmode( d2_device *handle, d2_u32 mode )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );               /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (((d2_u32)mode) < 256), D2_INVALIDENUM ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   ctx->fillmode       = (d2_u8) mode;
    +   ctx->internaldirty |= (d2_u8) d2_dirty_material;
    +
    +   switch (mode)
    +   {
    +      case d2_fm_color:
    +         ctx->features &= (d2_u8) (~((d2_u8)d2_feat_ulim | (d2_u8)d2_feat_vlim));
    +         break;
    +
    +      case d2_fm_twocolor:
    +         ctx->features &= (d2_u8) (~((d2_u8)d2_feat_ulim | (d2_u8)d2_feat_vlim));
    +         break;
    +
    +      case d2_fm_pattern:
    +         ctx->features |= (d2_u8) ( d2_feat_ulim);
    +         ctx->features &= (d2_u8) (~(d2_u8)d2_feat_vlim);
    +         break;
    +
    +      case d2_fm_texture:
    +         ctx->features |= (d2_u8) (d2_feat_ulim | d2_feat_vlim);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setcolor
    + * Set color registers.
    + *
    + * Set one of the two color registers, color1 and color2. Second register (index 1) is used for pattern
    + * rendering and during d2_fm_twocolor fillmode only.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - color register index (0 or 1)
    + *   color - 24bit rgb color value
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setcolor( d2_device *handle, d2_s32 index, d2_color color )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );                 /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (((d2_u32)index) < 2U), D2_INVALIDINDEX );  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_DEV(handle)->ctxselected->basecolor[ index ] = color & 0x00ffffff;
    +   D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setalpha
    + * set constant alpha value
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   alpha - alpha value (0 is totally transparent, 255 is fully opaque)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setalpha( d2_device *handle, d2_alpha alpha )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */  /*$Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +
    +   if (ctx->basealpha[0] != alpha)
    +   {
    +      ctx->internaldirty |= (d2_dirty_premalpha_p | d2_dirty_premalpha_t);
    +   }
    +
    +   ctx->basealpha[0] = alpha;
    +
    +   if(0 != (ctx->alphamode & d2_am_constant))
    +   {
    +      ctx->constalpha = ((d2_color)alpha) << 24;
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setalphaex
    + * set constant alpha value
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - alpha register index (0 or 1)
    + *   alpha - alpha value (0 is totally transparent, 255 is fully opaque)
    + *
    + * if index is 0 this function does the same as <d2_setalpha>.
    + * if index is 1 alpha is set for color register 2 (see: <d2_setalphablendmodeex>).
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setalphaex( d2_device *handle, d2_s32 index, d2_alpha alpha )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );                    /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERRP( (((d2_u32)index) < 2U), D2_INVALIDINDEX );    /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +
    +   if(0 == index)
    +   {
    +      return d2_setalpha(handle, alpha);
    +   }
    +   else
    +   {
    +      ctx->basealpha[index] = alpha;
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setalphamode
    + * Choose alpha source.
    + *
    + * Defines how alpha (transparency) is defined. As a constant value, a
    + * gradient or a mixture to both. Gradients are defined using <d2_setalphagradient>.
    + *
    + * Note that per pixel alpha (e.g. texture alpha channel) information is not disabled by
    + * setting the alphamode to opaque. To disable texture alpha look at <d2_settextureoperation>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   mode - alpha mode, several values can be or'ed together
    + *
    + * alpha modes:
    + *  d2_am_opaque - no transparency (equal to constant alpha of 0xff)
    + *  d2_am_constant - constant transparency   (see: <d2_setalpha>)
    + *  d2_am_gradient1 - alpha gradient1 is active
    + *  d2_am_gradient2 - alpha gradient2 is active
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setalphamode( d2_device *handle, d2_u32 mode )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );               /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (((d2_u32)mode) < 256), D2_INVALIDENUM ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +
    +   if(ctx->alphamode != mode)
    +   {
    +      ctx->internaldirty |= (d2_dirty_premalpha_p | d2_dirty_premalpha_t);
    +   }
    +
    +   ctx->alphamode = (d2_u8) mode;
    +
    +   if(0 != (mode & d2_am_constant))
    +   {
    +      ctx->constalpha = ((d2_color)ctx->basealpha[0]) << 24;
    +   }
    +   else 
    +   {
    +      ctx->constalpha = 0xff000000u;
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setalphagradient
    + * Define an alpha gradient.
    + *
    + * Instead or in addition to a constant alpha (transparency) value the hardware
    + * can also apply one or more alpha gradients to the rendered geometry.
    + * Gradients have to be enabled using <d2_setalphamode> in order to become visible.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - alpha gradient index (0 or 1)
    + *   x,y - startpoint of gradient (point of alpha 0) (fixedpoint)
    + *   dx,dy - direction and length of gradient (distance to point of alpha 255)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * */
    +d2_s32 d2_setalphagradient( d2_device *handle, d2_s32 index, d2_point x, d2_point y, d2_point dx, d2_point dy )
    +{
    +   d2_gradientdata *grad;
    +   d2_s32 xa,ya;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );                /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (((d2_u32)index) < 2U), D2_INVALIDINDEX ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +/* D2_CHECKERR( ((dx > D2_EPSILON) || (dx < -D2_EPSILON)), D2_VALUETOOSMALL );
    + * D2_CHECKERR( ((dy > D2_EPSILON) || (dy < -D2_EPSILON)), D2_VALUETOOSMALL ); */
    +   index+=2;
    +
    +   /* calc limiter values */
    +   if(0 != (dx | dy)) /* PRQA S 3344, 4130 */ /*$Misra: #PERF_LOGICOP $*/
    +   {
    +      /* using 64bit division to avoid fixedpoint overflow */
    +#ifdef _NO_LL_
    +      d2_int64 tmp, tmp2;
    +#endif
    +      d2_s32 idx = dx;
    +      d2_s32 idy = dy;
    +      d2_s32 l = (d2_s32)(((idx * idx) + (idy * idy)));
    +#ifndef _NO_LL_
    +      xa = (d2_s32)((idx * (d2_int64) 0x100000) / l);
    +      ya = (d2_s32)((idy * (d2_int64) 0x100000) / l);
    +#else
    +      d2_mul3232to64(idx, 0x100000, &tmp);
    +      d2_div6432(&tmp, l, &tmp2);
    +      xa  = d2_cast64to32(&tmp2);
    +      
    +      d2_mul3232to64(idy, 0x100000, &tmp);
    +      d2_div6432(&tmp, l, &tmp2);
    +      ya  = d2_cast64to32(&tmp2);
    +#endif
    +   } 
    +   else 
    +   {
    +      xa = 0;
    +      ya = 0;
    +   }
    +
    +   /* get access */
    +   grad = & D2_DEV(handle)->ctxselected->gradient[index];
    +   /* store parameters */
    +   grad->mode  = d2_grad_linear;
    +   grad->x1    = x;
    +   grad->y1    = y;
    +   grad->xadd  = xa;
    +   grad->yadd  = ya;
    +   grad->xadd2 = 0;
    +   grad->yadd2 = 0;
    +   /* mark as active */
    +   D2_DEV(handle)->ctxselected->gradients |= (d2_u8)BIT(index);
    +
    +   D2_RETOK(handle);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setblendmode
    + * Choose blendmode for RGB.
    + *
    + * Blendmode defines how the RGB channels of new pixels (source) are combined with already existing data
    + * in the framebuffer (destination). Blend modes for alpha channel are set by <d2_setalphablendmode>.
    + *
    + * The most common blending (and also the default) is a direct linear blend :
    + * > d2_bm_alpha , d2_bm_one_minus_alpha
    + *
    + * Additive blending is also pretty common :
    + * > d2_bm_alpha , d2_bm_one
    + *
    + * Note that antialiasing is not possible without blending (because partly covered
    + * pixels are represented by transparency). Therefore antialiasing is impossible
    + * with blendmodes that ignore alpha entirely.
    + *
    + * If d2_mode_alpha8 is used, alpha is treated as color.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   srcfactor - source blend factor (see available blend factors)
    + *   dstfactor - destination blend factor (see available blend factors)
    + *
    + * blend factors:
    + *     d2_bm_zero             - constant 0
    + *     d2_bm_one              - constant 1
    + *     d2_bm_alpha            - current alpha
    + *     d2_bm_one_minus_alpha  - inverted alpha
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setblendmode( d2_device *handle, d2_u32 srcfactor, d2_u32 dstfactor )
    +{
    +   d2_contextdata *ctx;
    +   d2_u32 blendMask;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +   blendMask = 0;
    +
    +   /* create blendunit bits */
    +   switch (srcfactor)
    +   {
    +      case d2_bm_one:
    +         break;
    +
    +      case d2_bm_zero:
    +         blendMask |= D2C_BSI;
    +         break;
    +
    +      case d2_bm_alpha:
    +         blendMask |= D2C_BSF;
    +         break;
    +
    +      case d2_bm_one_minus_alpha:
    +         blendMask |= (D2C_BSF | D2C_BSI);
    +         break;
    +
    +      default:
    +         D2_RETERR( handle, D2_INVALIDENUM );
    +   }
    +
    +   switch (dstfactor)
    +   {
    +      case d2_bm_one:
    +         break;
    +
    +      case d2_bm_zero:
    +         blendMask |= D2C_BDI;
    +         break;
    +
    +      case d2_bm_alpha:
    +         blendMask |= D2C_BDF;
    +         break;
    +
    +      case d2_bm_one_minus_alpha:
    +         blendMask |= (D2C_BDF | D2C_BDI);
    +         break;
    +
    +      default:
    +         D2_RETERR( handle, D2_INVALIDENUM );
    +   }
    +
    +   /* store */
    +   ctx->blendmask = blendMask;
    +   ctx->cr2mask = D2_DEV(handle)->fbstylemask | ctx->blendmask | ctx->tbstylemask | ctx->alphablendmask | ctx->rlemask | ctx->clutmask | ctx->colkeymask;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setalphablendmode
    + * Choose blendmode for alpha channel.
    + *
    + * Blendmode defines how new alpha values (source) are combined with already existing data
    + * in the framebuffer (destination).
    + *
    + * - The most common blending for alpha channel (and also the default) is write src alpha :
    + *
    + * > d2_bm_one, d2_bm_zero
    + *
    + * - Another possible mode is alpha blending:
    + *
    + * > d2_bm_one, d2_bm_one_minus_alpha
    + *
    + * - It is also possible to keep dst alpha :
    + *
    + * > d2_bm_zero, d2_bm_one
    + *
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   srcfactor - source blend factor (see available blend factors)
    + *   dstfactor - destination blend factor (see available blend factors)
    + *
    + * blend factors:
    + *     d2_bm_zero - constant 0
    + *     d2_bm_one  - constant 1
    + *     d2_bm_alpha            - current alpha
    + *     d2_bm_one_minus_alpha  - inverted alpha
    + *
    + * note:
    + *  If the framebuffer format is set to d2_mode_alpha8 (<d2_framebuffer>) then alpha blend mode should be set to write src alpha. 
    + *  For d2_mode_alpha8 the blend modes set by <d2_setblendmode> do apply.
    + *
    + * note:
    + *   the blend flags of the selected context is set to d2_blendf_default (see: <d2_setalphablendmodeex>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setalphablendmode( d2_device *handle, d2_u32 srcfactor, d2_u32 dstfactor )
    +{
    +   d2_contextdata *ctx;
    +   d2_u32 alphaBlendMask;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +
    +   ctx->alphablendflags = d2_blendf_default;
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_ALPHACHANNELBLENDING))
    +   {
    +      /* create write-alpha bits */
    +      alphaBlendMask = D2C_WRITEALPHA1;
    +
    +      if((srcfactor == d2_bm_one) && (dstfactor == d2_bm_zero))
    +      {
    +         alphaBlendMask &= ~D2C_WRITEALPHA2;
    +      }
    +      else if((srcfactor == d2_bm_zero) && (dstfactor == d2_bm_one))
    +      {
    +         alphaBlendMask |= D2C_WRITEALPHA2;
    +      }
    +      else
    +      {
    +         D2_RETERR( handle, D2_INVALIDENUM );
    +      }
    +   } 
    +   else 
    +   {
    +      /* create alpha-blendunit bits */
    +      alphaBlendMask  = D2C_USE_ACB;
    +      alphaBlendMask |= D2C_WRITEALPHA1;
    +
    +      switch (srcfactor)
    +      {
    +         case d2_bm_one:
    +            break;
    +
    +         case d2_bm_zero:
    +            alphaBlendMask |= D2C_BSIA;
    +            break;
    +
    +         case d2_bm_alpha:
    +            alphaBlendMask |= D2C_BSFA;
    +            break;
    +
    +         case d2_bm_one_minus_alpha:
    +            alphaBlendMask |= (D2C_BSFA | D2C_BSIA);
    +            break;
    +
    +         default:
    +            D2_RETERR( handle, D2_INVALIDENUM );
    +      }
    +
    +      switch (dstfactor)
    +      {
    +         case d2_bm_one:
    +            break;
    +
    +         case d2_bm_zero:
    +            alphaBlendMask |= D2C_BDIA;
    +            break;
    +
    +         case d2_bm_alpha:
    +            alphaBlendMask |= D2C_BDFA;
    +            break;
    +
    +         case d2_bm_one_minus_alpha:
    +            alphaBlendMask |= (D2C_BDFA | D2C_BDIA);
    +            break;
    +
    +         default:
    +            D2_RETERR( handle, D2_INVALIDENUM );
    +      }   
    +   }
    +
    +   /* store */
    +   ctx->alphablendmask = alphaBlendMask;
    +   ctx->cr2mask        = 
    +      D2_DEV(handle)->fbstylemask | 
    +      ctx->blendmask              | 
    +      ctx->tbstylemask            | 
    +      ctx->alphablendmask         | 
    +      ctx->rlemask                | 
    +      ctx->clutmask               | 
    +      ctx->colkeymask             ;
    +
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setalphablendmodeex
    + * Choose blendmode for alpha channel.
    + *
    + * Blendmode defines how new alpha values (source) are combined with already existing data
    + * in the framebuffer (destination).
    + *
    + * - The most common blending for alpha channel (and also the default) is write src alpha :
    + *
    + * > d2_bm_one, d2_bm_zero
    + *
    + * - Another possible mode is alpha blending:
    + *
    + * > d2_bm_one, d2_bm_one_minus_alpha
    + *
    + * - It is also possible to keep dst alpha :
    + *
    + * > d2_bm_zero, d2_bm_one
    + *
    + *
    + * parameters:
    + *   handle     - device pointer (see: <d2_opendevice>)
    + *   srcfactor  - source blend factor (see available blend factors)
    + *   dstfactor  - destination blend factor (see available blend factors)
    + *   blendflags - blend flags (see available blend flags)
    + *
    + * blend factors:
    + *     d2_bm_zero - constant 0
    + *     d2_bm_one  - constant 1
    + *     d2_bm_alpha            - current alpha
    + *     d2_bm_one_minus_alpha  - inverted alpha
    + *
    + * blend flags:
    + *     d2_blendf_blenddst    - use framebuffer alpha as dst alpha (is d2_blendf_default)
    + *     d2_blendf_blendcolor2 - use color2 alpha as dst alpha as input for the blending formula (see: <d2_setalphaex>)
    + *
    + * note:
    + *  If the framebuffer format is set to d2_mode_alpha8 (<d2_framebuffer>) the alpha blend mode should be set to write src alpha:
    + *  For d2_mode_alpha8 the blend modes set by <d2_setblendmode> do apply.
    + *
    + *  On older D/AVE 2D hardware revisions without alpha channel blending (see: <d2_getrevisionhw>, D2FB_ALPHACHANNELBLENDING)
    + *  only the following two blend combinations can be used for the alpha channel:
    + *  - (1/0): 1 * src + 0 * dst -> write source alpha
    + *  - (0/1): 0 * src + 1 * dst -> write framebuffer alpha or color2 alpha (depending on blendflags)
    + *
    + * These modes also require that the same source blend factor is configured for RGB and A.
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setalphablendmodeex( d2_device *handle, d2_u32 srcfactor, d2_u32 dstfactor, d2_u32 blendflags )
    +{
    +   d2_contextdata *ctx;
    +   d2_s32 ret;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );                      /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (((d2_u32)blendflags) < 256), D2_INVALIDENUM );  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_ALPHACHANNELBLENDING))
    +   {
    +      if ((srcfactor == d2_bm_one) && (dstfactor == d2_bm_zero))
    +      {
    +         blendflags = d2_blendf_default;
    +      }      
    +   }
    +
    +   ret = d2_setalphablendmode(handle, srcfactor, dstfactor);
    +   if (ret == D2_OK) 
    +   {
    +      ctx->alphablendflags = (d2_u8) blendflags;
    +   }
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setantialiasing
    + * Globally disable or enable antialiasing.
    + *
    + * When antialiasing is enabled all geometry is blended with the background
    + * according to its coverage value.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   enable - boolean value (set 1 to enable antialiasing)
    + *
    + * If antaliasing is disabled blurring will also be disabled (see: <d2_setblur>).
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setantialiasing( d2_device *handle, d2_s32 enable )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   if(0 != enable)
    +   {
    +      ctx->features      |= (d2_u8) d2_feat_aa;
    +      ctx->thresholdmask  = 0;
    +   } 
    +   else
    +   {
    +      ctx->features     &= (d2_u8) ~(d2_u8)d2_feat_aa;
    +      ctx->thresholdmask = D2C_LIM1THRESHOLD | D2C_LIM2THRESHOLD | D2C_LIM3THRESHOLD |
    +         D2C_LIM4THRESHOLD | D2C_LIM5THRESHOLD | D2C_LIM6THRESHOLD ;
    +      ctx->invblur       = D2_FIX16(1u);
    +      ctx->features     &= (d2_u8) ~(d2_u8)d2_feat_blur;
    +      ctx->blurring      = D2_FIX4(1);
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setblur
    + * Set global blurring factor.
    + *
    + * The blurring factor is a fixed point (4 bit fraction) number of pixels
    + * during which the edge opacity changes from 0 (no coverage) to 1 (fully covered).
    + * The intended use is a finetuning of the antialiasing. The default is a value of 1.0 
    + * equals a single pixel wide region around each primitive for antialiasing.
    + *
    + * A lower value is not useful (and not supported). A higher value will produce 
    + * results similar to an additional lowpass filter (hence the name).
    + * Extending the AA region above 2 or 3 pixels is not recommended and should be 
    + * used for special effects only. 
    + *
    + * Note that blurring will not work when antialiasing is disabled (see: <d2_setantialiasing>).
    + * If blurring factor is > 1 then antialiasing will be enabled (see: <d2_setantialiasing>).
    + *
    + * In order to disable blurring set a value of 1 (fixed point)
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   blur - fixed point
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setblur( d2_device *handle, d2_width blur )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );    /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( blur != 0, D2_VALUETOOSMALL ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   if (blur <= D2_FIX4(1))
    +   {
    +      ctx->invblur   = D2_FIX16(1u);
    +      ctx->features &= (d2_u8) ~(d2_u8)d2_feat_blur;
    +      blur = D2_FIX4(1);
    +   } 
    +   else 
    +   {
    +/*       if ( !(ctx->features & d2_feat_aa))
    + *       {
    + *         // antialiasing must have been set 
    + *         D2_RETERR(handle, D2_INVALIDCONTEXT);
    + *       } */
    +      ctx->invblur   = (65536u * 16u) / ((d2_u32)blur);
    +      ctx->features |= (d2_u8) d2_feat_blur;
    +      ctx->features |= (d2_u8) d2_feat_aa;
    +      ctx->thresholdmask = 0;
    +   }
    +   ctx->blurring = blur;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setlinecap
    + * Specify lineend style.
    + *
    + * Linecaps are applied when rendering lines using <d2_renderline> or <d2_renderline2>
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   mode - linecap mode
    + *
    + * linecap modes:
    + *   d2_lc_butt - lines end directly at endpoints
    + *   d2_lc_round - lines end with halfcircles
    + *   d2_lc_square - line ends are extended by the half linewidth
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setlinecap( d2_device *handle, d2_u32 mode )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );            /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (mode < d2_lc_max), D2_INVALIDENUM );  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->linecap = (d2_u8) mode;
    +
    +   if(mode == d2_lc_round) 
    +   {
    +      ctx->roundends = 3; 
    +   }
    +   else 
    +   {
    +      ctx->roundends = 0;
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setlinejoin
    + * Specify polyline connection style.
    + *
    + * Linejoins are applied when rendering polylines using <d2_renderpolyline>
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   mode - linejoin mode
    + *
    + * linejoin modes:
    + *   d2_lj_none - no connection is applied
    + *   d2_lj_miter - lines meet in a sharp angle (see also <d2_setmiterlimit>)
    + *   d2_lj_round - line are connected by circle segments
    + *   d2_lj_bevel - lines meet in a flat angle
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setlinejoin( d2_device *handle, d2_u32 mode )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );            /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (mode < d2_lj_max), D2_INVALIDENUM );  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->linejoin = (d2_u8) mode;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setmiterlimit
    + * Clipping distance for miter polyline connections.
    + *
    + * When using sharp linejoin's (d2_lj_miter) with <d2_renderpolyline> the sharp
    + * edge has to be clipped at some point. Otherwise it would extend to infinity
    + * when the two segments meet at 180�.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   miter - maximum pixel distance the join can extend beyond bevel edge
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setmiterlimit( d2_device *handle, d2_width miter )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->miterlimit = miter;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setpattern
    + * Specify pattern bitmask.
    + *
    + * When patterns are used to fill a primitive an index into the bitmask is
    + * generated for each pixel (see: <d2_setpatternparam> for mapping details). The
    + * pattern wraps around after N bits (N can be set using <d2_setpatternsize>).
    + *
    + * Depending on the bit color1 or color2 and patternalpha1 or patternalpha2
    + * are used. Fractional indices are interpolated between those two values.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   pattern - N bit pattern mask
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * example:
    + *   The following figure shows a rendered line filled with an 8 bit pattern. Color1 is blue
    + *   and color2 is green, the bitstring is 0101 1001. For the upper line filtering is off, the
    + *   lower line is rendered with filtering enabled (flag: d2_pm_filter).
    + *   (see pattern.png)
    + * */
    +d2_s32 d2_setpattern( d2_device *handle, d2_pattern pattern )
    +{
    +   d2_contextdata *ctx;
    +   d2_s32 i,patLen, maxPatLen;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +   ctx->orgpattern = (d2_s32) pattern;
    +
    +   maxPatLen = ctx->device->maxpatlen;
    +   patLen = ctx->patlen;
    +   /* mask invalid bits in pattern
    +    * pattern &= ((2 << (patlen-1))-1);  (warning: would break 'eye' demo) */
    +
    +   /* extend it to fill entire hardware word */
    +   for (i=0; i<(maxPatLen / patLen); i++) 
    +   {
    +      pattern |= (pattern << patLen);
    +   }
    +   /* store */
    +   ctx->pattern = (d2_s32) pattern;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setpatternalpha
    + * Specify pattern transparency.
    + *
    + * Pattern alpha is mixed with global alpha (gradient or constant). Pattern alpha
    + * index 0 is used where 0bits occur in the pattern bitmask.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - register index (0 or 1 as patterns are always twocolor)
    + *   alpha - alphavalue (0 is totally transparent, 255 is fully opaque)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_setcolor>, <d2_setpattern>
    + * */
    +d2_s32 d2_setpatternalpha( d2_device *handle, d2_s32 index, d2_alpha alpha )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );                /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (((d2_u32)index) < 2U), D2_INVALIDINDEX ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->patternalpha[ index ] = alpha;
    +   ctx->internaldirty |= (d2_dirty_premalpha_p | d2_dirty_premalpha_t) | d2_dirty_material;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setpatternparam
    + * Define mapping of pattern to geometry.
    + *
    + * Pattern mapping is defined by specifying a line segment (startpoint and
    + * vector to endpoint) along which the pattern is mapped. The startpoint
    + * maps to bit0 of the pattern bitmask (see: <set_pattern>).
    + * With the bitmask extending along the direction vector.
    + *
    + * Note that the pattern is repeated infinitely along the defined line.
    + *
    + * Free pattern directions apply to line based geometry only when pattern
    + * mode (see: <d2_setpatternmode>) is not set to auto align.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x, y - pattern startpoint (fixedpoint)
    + *   dx, dy - pattern direction and size (fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_setpatternsize>, <d2_setpattern>, <d2_setpatternmode>
    + * */
    +d2_s32 d2_setpatternparam( d2_device *handle, d2_point x, d2_point y, d2_width dx, d2_width dy )
    +{
    +   d2_contextdata *ctx;
    +   d2_gradientdata *grad;
    +   d2_s32 xa,ya;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_upatlim;
    +
    +   grad = & ctx->patulim[0];
    +   /* calc limiter values */
    +   if(0 != (dx | dy))  /* PRQA S 3344, 4130 */ /* $Misra: #PERF_LOGICOP $*/
    +   {
    +      /* using 64bit division to avoid fixedpoint overflow */
    +      d2_s32 idx = dx;
    +      d2_s32 idy = dy;
    +#ifdef _NO_LL_
    +      d2_int64 tmp, tmp2;
    +#endif
    +      d2_s32 l = ((idx*idx) + (idy*idy));
    +      /* scale to pattern bitlength */
    +#ifndef _NO_LL_
    +      xa = (d2_s32) ((idx * (d2_int64) (ctx->patlen * (1 << 16) * (1 << 4)) ) / l);
    +      ya = (d2_s32) ((idy * (d2_int64) (ctx->patlen * (1 << 16) * (1 << 4)) ) / l);
    +#else
    +      d2_mul3232to64(idx, ctx->patlen * (1 << 16) * (1 << 4), &tmp);
    +      d2_div6432(&tmp, l, &tmp2);
    +      xa  = d2_cast64to32(&tmp2);
    +      
    +      d2_mul3232to64(idy, ctx->patlen * (1 << 16) * (1 << 4), &tmp);
    +      d2_div6432(&tmp, l, &tmp2);
    +      ya  = d2_cast64to32(&tmp2);
    +#endif
    +      
    +   } 
    +   else 
    +   {
    +      xa = 0;
    +      ya = 0;
    +   }
    +
    +   /* store gradient */
    +   grad->mode = d2_grad_linear;
    +   grad->x1 = x;
    +   grad->y1 = y;
    +   grad->xadd = xa;
    +   grad->yadd = ya;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setlinepattern
    + * Specify parameters for aligned patterns.
    + *
    + * When rendering line based geometry it is very often required to align the
    + * pattern perpendicular to the line direction. For single elements it can
    + * be done using <d2_setpatternparam> but this is not efficient and sometimes
    + * (e.g. with polylines) not even possible.
    + *
    + * When enabled by setting the patternmode to contain *d2_pm_autoalign* this
    + * function can be used to describe the pattern relative to any line geometry
    + * by scale and offset.
    + *
    + * The offset can be incremented automatically after rendering an element
    + * if d2_pm_advance is set using <d2_setpatternmode>. Calling <d2_setlinepattern>
    + * resets the internally managed offset to the specified value.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   scale - number of screenpixels one pattern bit is mapped onto
    + *   offset - pattern offset in pixels (fixedpoint format equal to d2_point)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_setpatternmode>, <d2_setpatternparam>
    + * */
    +d2_s32 d2_setlinepattern( d2_device *handle, d2_width scale, d2_s32 offset )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->patoffset = offset;
    +   ctx->patscale = scale;
    +
    +   /* precal reciproc */
    +   ctx->invpatscale = (65536*16) / scale;
    +
    +   D2_RETOK( handle );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setpatternmode
    + * Define pattern addressing details.
    + *
    + * Filtering (interpolation) of pattern data can be disabled by passing 0
    + * as patternmode.
    + *
    + * Patterns can be aligned to run perpendicular to rendered lines automatically
    + * when d2_pm_autoalign mode is enabled (works only when rendering line based
    + * geometry). In this case calling <d2_setpatternparam> is unnecessary but
    + * additional data has to be passed using <d2_linepattern>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *  mode - any combination of pattern mode bits (see below)
    + *
    + * pattern mode bits:
    + * d2_pm_filter - use linear interpolation between colors (default)
    + * d2_pm_autoalign - map pattern to line direction (see: <d2_setlinepattern>)
    + * d2_pm_advance - increase offset automatically (see: <d2_setlinepattern>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setpatternmode( d2_device *handle, d2_u32 mode )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );               /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (((d2_u32)mode) < 256), D2_INVALIDENUM ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* store */
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   ctx->internaldirty |= d2_dirty_material;
    +   ctx->patmode        = (d2_u8) mode;
    +
    +   /* precalc modefield */
    +   if(0 != (mode & d2_pm_filter))
    +   {
    +      ctx->patmodemask = D2C_TEXTUREFILTERX;
    +   }
    +   else
    +   {
    +      ctx->patmodemask = 0;
    +   }
    +
    +   D2_RETOK( handle );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setpatternsize
    + * Define pattern size.
    + *
    + * Patterns are defined as a bitvector. This function can be used to
    + * define the number of valid bits. The size may not exceed the maximum
    + * size supported by the hardware (currently 8).
    + * The default size is set to 4 in every new context for compatibility reasons.
    + *
    + * Size changes affect only the following calls to <d2_setpatternparam>
    + * and <d2_setpattern>
    + *
    + * Note that for correct wraparound the size must divide the hardware
    + * maximum without remainder.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   size - number of valid bits used for pattern mask
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * please note:
    + *   when using small pattern size (<8) all leading unused bits in the pattern mask (see: <d2_setpattern>) must be zero!
    + * */
    +d2_s32 d2_setpatternsize( d2_device *handle, d2_s32 size )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );                                                  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( size > 0, D2_VALUETOOSMALL );                                                /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( size <= (D2_DEV(handle)->ctxselected->device->maxpatlen), D2_INVALIDWIDTH ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* store */
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->patlen = size;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setclipgradient
    + * Define an alpha gradient for clipping.
    + *
    + * Instead or in addition to a constant alpha (transparency) value the hardware
    + * can also apply one or more alpha gradients to the rendered geometry.
    + *
    + * <d2_setalphagradient> offers an interface suitable to specify smooth alpha gradients,
    + * but does not provide enough accuracy for steep gradients, which effectively clip
    + * objects along a straight edge, e.g. let the alpha value drop from 255 to 0 within
    + * the distance of a single pixel.
    + * For this reason d2_setclipgradient offers the necessary accuracy by using 16.16 
    + * fixed point instead of <d2_point> (12.4 fixed point) for the definition of the gradient.
    + * Also the interpretation of nx,ny is different compared to dx,dy of <d2_setalphagradient> 
    + * as follows:
    + * nx,ny specify a normal vector of the clipping edge, pointing towards the non-clipped side.
    + * When this vector is normalized to a length of 1.0 (i.e. 0x00010000), the gradient alpha value
    + * changes from 0 to 255 within the distance of a single pixel. When it is longer, the gradient
    + * is even steeper respectively smoother, when it is shorter. The gradient alpha value is always
    + * clamped to 0 respectively 255 when it leaves this range.
    + *
    + * note:
    + *   Additionally index 2 or 3 can also be used in some cases. These indices are 
    + *   shared with the alpha gradients (and will overwrite these settings) and have to be 
    + *   enabled using <d2_setalphamode> in order to become visible. 
    + *   Please also note that the total number of available gradients (alpha or clip) is 
    + *   restricted by the D/AVE 2D hardware and varies on the primitive types and render modes!
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - alpha gradient index (0 or 1, additionally 2 or 3)
    + *   x,y - startpoint of gradient (point of alpha 0) (fixedpoint)
    + *   nx,ny - normal vector of the clipping edge, pointing towards the non-clipped side (16.16 fixedpoint)
    + *   flags - reserved
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *  <d2_setalphagradient>
    + * */
    +d2_s32 d2_setclipgradient( d2_device *handle, d2_s32 index, d2_point x, d2_point y, d2_s32 nx, d2_s32 ny, d2_u32 flags )
    +{
    +   d2_gradientdata *grad;
    +
    +   if(NULL != handle)
    +   {
    +      /*D2_VALIDATE( handle, D2_INVALIDDEVICE );*/             /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +      D2_CHECKERR( (((d2_u32)index) < 4U), D2_INVALIDINDEX );  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +      /* get access */
    +      grad = & D2_DEV(handle)->ctxselected->gradient[index];
    +      if(0 == (nx | ny))                                       /* PRQA S 3344, 4130 */ /* $Misra: #PERF_LOGICOP $*/
    +      {
    +         /* disable clip plane */
    +         D2_DEV(handle)->ctxselected->gradients &= (d2_u8) ~ BIT(index);
    +      }
    +      else
    +      {
    +         /* store parameters */
    +         grad->mode = d2_grad_linear | flags;
    +         grad->x1 = x;
    +         grad->y1 = y;
    +         grad->xadd = nx;
    +         grad->yadd = ny;
    +         grad->xadd2 = 0;
    +         grad->yadd2 = 0;
    +         /* mark as active */
    +         D2_DEV(handle)->ctxselected->gradients |= (d2_u8) BIT(index);
    +      }
    +
    +      D2_RETOK(handle);
    +   }
    +   else
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setcircleextend
    + * Increase bbox of circles.
    + *
    + * Due to limited precision for circle parameters large circles with enabled 
    + * blurring can become inaccurate.
    + * To avoid clipping at the bbox of the circle the bbox can be extended by offset.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   offset - number by which bbox of circles will be extended (fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * */
    +d2_s32 d2_setcircleextend( d2_device *handle, d2_width offset )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );       /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( offset >= 0, D2_VALUETOOSMALL );  /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* store */
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->circleextendoffset = offset;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_calcpatternalpha_intern( d2_contextdata *ctx )
    +{
    +   d2_u32 patAlpha;
    +
    +   patAlpha = (d2_u32) (ctx->constalpha >> 8);
    +   ctx->premalpha[0] = ((patAlpha * ctx->patternalpha[0]) + 0xffffffu) & 0xff000000u;
    +   ctx->premalpha[1] = ((patAlpha * ctx->patternalpha[1]) + 0xffffffu) & 0xff000000u;
    +
    +   ctx->internaldirty &= (d2_u8) ~(d2_u8)d2_dirty_premalpha_p;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: Context Attribute Queries */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getfillmode
    + * Query fillmode from selected context.
    + *
    + * see: <d2_setfillmode> for a list of fill modes
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   Select fillmode (d2_fm_color,d2_fm_pattern,..). undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setfillmode>
    + * */
    +d2_u8 d2_getfillmode( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->fillmode;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getcolor
    + * Query a color from selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - color register index (0 or 1)
    + *
    + * returns:
    + *   content of specified color register. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_setcolor>
    + * */
    +d2_color d2_getcolor( d2_device *handle, d2_s32 index )
    +{
    +   d2_color ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );                    /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERRP( (((d2_u32)index) < 2U), D2_INVALIDINDEX );     /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->basecolor[ index ];
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getalpha
    + * Query constant alpha from selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   content of constant alpha register. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_setalpha>
    + * */
    +d2_alpha d2_getalpha( d2_device *handle )
    +{
    +   d2_alpha ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->basealpha[0];
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getalphaex
    + * Query constant alpha from selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - alpha register index (0 or 1)
    + *
    + * returns:
    + *   content of constant alpha register. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_setalphaex>
    + * */
    +d2_alpha d2_getalphaex( d2_device *handle, d2_s32 index )
    +{
    +   d2_alpha ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );                    /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERRP( (((d2_u32)index) < 2U), D2_INVALIDINDEX );     /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->basealpha[index];
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getalphamode
    + * Query alpha source from selected context.
    + *
    + * see: <d2_setalphamode> for a list of alpha mode bits
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   alpha source bitmask. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setalphamode>
    + * */
    +d2_u8 d2_getalphamode( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->alphamode;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getblendmodesrc
    + * Query source blend factor from selected context.
    + *
    + * see: <d2_setblendmode> for a list of blendmodes
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   source blend factor. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_getblendmodedst>, <d2_setblendmode>
    + * */
    +d2_u32 d2_getblendmodesrc( d2_device *handle )
    +{
    +   d2_u32 ret;
    +   d2_u32 blendMask;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* retrieve blendunit bits */
    +   blendMask = D2_DEV(handle)->ctxselected->blendmask & (D2C_BSF | D2C_BSI);
    +
    +   switch(blendMask)
    +   {
    +      case 0:
    +         ret = d2_bm_one;
    +         break;
    +
    +      case D2C_BSI:
    +         ret = d2_bm_zero;
    +         break;
    +
    +      case D2C_BSF:
    +         ret = d2_bm_alpha;
    +         break;
    +
    +      case (D2C_BSF | D2C_BSI):
    +         ret = d2_bm_one_minus_alpha;
    +         break;
    +
    +      default:
    +         D2_RETERRU( handle, D2_INVALIDENUM );
    +   }
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getblendmodedst
    + * Query destination blend factor from selected context.
    + *
    + * see: <d2_setblendmode> for a list of blendmodes
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   destination blend factor. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_getblendmodesrc>, <d2_setblendmode>
    + * */
    +d2_u32 d2_getblendmodedst( d2_device *handle )
    +{
    +   d2_u32 ret;
    +   d2_u32 blendMask;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* retrieve blendunit bits */
    +   blendMask = D2_DEV(handle)->ctxselected->blendmask & (D2C_BDF | D2C_BDI);
    +   switch(blendMask)
    +   {
    +      case 0:
    +         ret = d2_bm_one;
    +         break;
    +
    +      case D2C_BDI:
    +         ret = d2_bm_zero;
    +         break;
    +
    +      case D2C_BDF:
    +         ret = d2_bm_alpha;
    +         break;
    +
    +      case (D2C_BDF | D2C_BDI):
    +         ret = d2_bm_one_minus_alpha;
    +         break;
    +
    +      default:
    +         D2_RETERRU( handle, D2_INVALIDENUM );
    +   }
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getalphablendmodesrc
    + * Query source blend factor for alpha channel blending from selected context.
    + *
    + * see: <d2_setalphablendmode> for a list of blendmodes
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   alpha source blend factor. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_getalphablendmodedst>, <d2_setalphablendmode>
    + * */
    +d2_u32 d2_getalphablendmodesrc( d2_device *handle )
    +{
    +   d2_u32 ret;
    +   d2_u32 blendMask;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_ALPHACHANNELBLENDING))
    +   {
    +      /* create write-alpha bits */
    +      blendMask = D2_DEV(handle)->ctxselected->alphablendmask & (D2C_WRITEALPHA2);
    +      if(0 != blendMask)
    +      {
    +         ret = d2_bm_zero;
    +      }
    +      else
    +      {
    +         ret = d2_bm_one;
    +      }
    +   } 
    +   else 
    +   {
    +      /* retrieve blendunit bits */
    +      blendMask = D2_DEV(handle)->ctxselected->alphablendmask & (D2C_BSFA | D2C_BSIA);
    +      switch(blendMask)
    +      {
    +         case 0:
    +            ret = d2_bm_one;
    +            break;
    +
    +         case D2C_BSIA:
    +            ret = d2_bm_zero;
    +            break;
    +
    +         case D2C_BSFA:
    +            ret = d2_bm_alpha;
    +            break;
    +
    +         case (D2C_BSFA | D2C_BSIA):
    +            ret = d2_bm_one_minus_alpha;
    +            break;
    +
    +         default:
    +            D2_RETERRU( handle, D2_INVALIDENUM ); 
    +      }
    +   }
    +
    +   (void)D2_SETOK(handle);
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getalphablendmodedst
    + * Query destination blend factor for alpha channel blending from selected context.
    + *
    + * see: <d2_setalphablendmode> for a list of blendmodes
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   alpha destination blend factor. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_getblendmodesrc>, <d2_setalphablendmode>
    + * */
    +d2_u32 d2_getalphablendmodedst( d2_device *handle )
    +{
    +   d2_u32 ret;
    +   d2_u32 blendMask;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_ALPHACHANNELBLENDING))
    +   {
    +      /* create write-alpha bits */
    +      blendMask = D2_DEV(handle)->ctxselected->alphablendmask & (D2C_WRITEALPHA2);
    +      if(0 == blendMask)
    +      {
    +         ret = d2_bm_zero;
    +      }
    +      else
    +      {
    +         ret = d2_bm_one;
    +      }
    +   } 
    +   else 
    +   {
    +      /* retrieve blendunit bits */
    +      blendMask = D2_DEV(handle)->ctxselected->alphablendmask & (D2C_BDFA | D2C_BDIA);
    +      switch(blendMask)
    +      {
    +         case 0:
    +            ret = d2_bm_one;
    +            break;
    +
    +         case D2C_BDIA:
    +            ret = d2_bm_zero;
    +            break;
    +
    +         case D2C_BDFA:
    +            ret = d2_bm_alpha;
    +            break;
    +
    +         case (D2C_BDFA | D2C_BDIA):
    +            ret = d2_bm_one_minus_alpha;
    +            break;
    +
    +         default:
    +            D2_RETERRU( handle, D2_INVALIDENUM );
    +      }
    +   }
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getalphablendmodeflags
    + * Query alpha blend flags from selected context.
    + *
    + * see: <d2_setalphablendmodeex> for a list of blend flags
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   alpha blend flags. 
    + *   Undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setalphablendmodeex>
    + * */
    +d2_u8 d2_getalphablendmodeflags( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->alphablendflags;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getantialiasing
    + * Query antialiasing setting from selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   Boolean (0 or 1) antialiasing setting. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setantialiasing>
    + * */
    +d2_s32 d2_getantialiasing( d2_device *handle )
    +{
    +   d2_s32 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */  /*$Misra: #DEBUG_MACRO $*/
    +
    +   if(0 != (D2_DEV(handle)->ctxselected->features & d2_feat_aa))
    +   {
    +      ret = 1;
    +   }
    +   else
    +   {
    +      ret = 0;
    +   }
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getblur
    + * Query blurring factor from selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   global blurring factor (fixedpoint). undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_setblur>
    + * */
    +d2_width d2_getblur( d2_device *handle )
    +{
    +   d2_width ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->blurring;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getlinecap
    + * Query lineend style from selected context.
    + *
    + * see: <d2_setlinecap> for a list of all line cap modes
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   Linecap mode. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setlinecap>
    + * */
    +d2_u8 d2_getlinecap( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->linecap;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getlinejoin
    + * Query polyline connection style from selected context.
    + *
    + * see: <d2_setlinejoin> for a list of all line join modes
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   Linejoin mode. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setlinejoin>
    + * */
    +d2_u8 d2_getlinejoin( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->linejoin;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getpattern
    + * Query pattern bitmask from selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   Pattern bitmask. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setpattern>
    + * */
    +d2_pattern d2_getpattern( d2_device *handle )
    +{
    +   d2_pattern ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = (d2_pattern) D2_DEV(handle)->ctxselected->orgpattern;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getpatternmode
    + * Query pattern addressing details.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   Pattern address mode. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setpatternmode>
    + * */
    +d2_u32 d2_getpatternmode( d2_device *handle )
    +{
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   (void)D2_SETOK( handle );
    +   return D2_DEV(handle)->ctxselected->patmode;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getpatternsize
    + * Query pattern bitmask size.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   Pattern bitmask size. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setpatternsize>
    + * */
    +d2_s32 d2_getpatternsize( d2_device *handle )
    +{
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   (void)D2_SETOK( handle );
    +   return D2_DEV(handle)->ctxselected->patlen;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getpatternalpha
    + * Query pattern transparency from selected context.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - register index (0 or 1 as patterns are always twocolor)
    + *
    + * returns:
    + *   Pattern alpha. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *  <d2_setpatternalpha>
    + * */
    +d2_alpha d2_getpatternalpha( d2_device *handle, d2_s32 index )
    +{
    +   d2_alpha ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );                    /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERRP( (((d2_u32)index) < 2U), D2_INVALIDINDEX );     /* PRQA S 3112, 4130 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->patternalpha[ index ];
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    diff --git a/src/drivers/dave2d/src/dave_curve.c b/src/drivers/dave2d/src/dave_curve.c
    new file mode 100644
    index 000000000..562a3bdc6
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_curve.c
    @@ -0,0 +1,324 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_curve.c (%version: 12 %)
    + *          created Wed Oct 10 12:30:33 2012 by hh04044
    + *
    + * Description:
    + *  %date_modified: Wed Oct 10 12:30:33 2012 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2008-10-02 MRe  fix of blurred circles
    + *  2008-11-24 AJ   modify code to support IAR compiler. (no 64bit support)
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_curve.h"
    +
    +
    +#define TWEAK 3
    +
    +
    +void d2_circlesetup_intern(d2_devicedata *handle, const d2_contextdata *ctx, d2_u32 index, d2_point x, d2_point y, d2_width r, d2_s32 band, d2_s32 invert, d2_s32 hiprec )
    +{
    +   d2_s32 a, b, f, ir;
    +   d2_u32 ib;
    +   d2_point xr, yr;
    +   d2_width blur;
    +
    +   /* reduce bitsize (x&y are approx r if unclipped) */
    +   xr = (d2_point)(x - r);
    +   yr = (d2_point)(y - r);
    +   
    +   if(0 != (ctx->features & d2_feat_blur))
    +   {
    +      if( (0 == hiprec) || (0 == (D2_DEV(handle)->hwrevision & D2FB_HILIMITERPRECISION)) )
    +      {
    +         d2_int64 f64, ir64;
    +#ifdef _NO_LL_
    +         d2_int64 tmp, tmp2;
    +#endif
    +        
    +         /* get parameters for blurred circle rendering */
    +         blur = ctx->blurring; 
    +         ib = ctx->invblur;    
    +
    +         /* calc circle parameters (16:16 from 10:4) */
    +         ir =
    +            (
    +               (
    +                  (-1 * D2_FIX16(16))
    +                  * D2_FIX4(1)
    +                ) 
    +               *
    +               (D2_FIX4(1) / 2)
    +             ) 
    +            / (r * blur);               /* 1 / 2rb */     
    +#ifndef _NO_LL_
    +         ir64 = 
    +            (
    +               (
    +                  (
    +                     (
    +                        (-1 * (d2_int64)D2_FIX16(16<<0))
    +                        * D2_FIX4(1)
    +                      )
    +                     *
    +                     (D2_FIX4(1) / 2)
    +                   )
    +                  / (d2_int64)r
    +                )
    +               * (1 << 8)
    +             )
    +            / (d2_int64)blur;               /* 1 / 2rb */  
    +#else
    +         d2_cast32to64(
    +            (
    +               (
    +                  (-1 * D2_FIX16(16<<0))
    +                  * D2_FIX4(1)
    +                ) 
    +               * 
    +               (D2_FIX4(1) / 2)
    +             ) 
    +            / r, &ir64
    +                       );
    +         d2_shiftleft64(&ir64, 8, &tmp);
    +         d2_div6432(&tmp, blur, &ir64);               /* 1 / 2rb */  
    +#endif
    +       
    +         f = 
    +            (
    +               (
    +                  (
    +                     (
    +                        (xr * xr) + (yr * yr)
    +                      )
    +                     / (1 << 8)
    +                   ) 
    +                  * ir
    +                )
    +               / (1 << 4)
    +             ) 
    +            -
    +            (
    +               (
    +                  (
    +                     (r / 2)
    +                     +
    +                     (xr + yr)
    +                   ) 
    +                  * (d2_s32)ib
    +                ) 
    +               / (1 << 4)
    +             );      /* (x²+y²-r²) * ir */ 
    +        
    +#ifndef _NO_LL_
    +         f64 = 
    +            (
    +               (
    +                  (
    +                     ((xr * xr) + (yr * yr))
    +                     / (1 << 8)
    +                   )
    +                  * (d2_int64)ir64
    +                )
    +               / (1 << 4)
    +             )
    +            - 
    +            (
    +               (
    +                  ((r / 2) + (xr + yr))
    +                  * (d2_int64)ib
    +                )
    +               * (1 << 4)
    +             );      /* (x²+y²-r²) * ir */ 
    +         f = (d2_s32)(f64 / (1 << 8));
    +#else
    +         d2_mul3264(
    +            (
    +               (
    +                  (xr * xr)
    +                  +
    +                  (yr * yr)
    +                )
    +               / (1 << 8)
    +             ),
    +            &ir64,
    +            &tmp
    +                    );
    +         d2_shiftright64(&tmp, 4, &f64);
    +         d2_mul3232to64(((r / 2) + (xr + yr)), (d2_s32)ib, &tmp);
    +         d2_shiftleft64(&tmp, 4, &tmp2);
    +         d2_sub64(&f64, &tmp2, &tmp);      /* (x²+y²-r²) * ir */ 
    +         d2_shiftright64(&tmp, 8, &f64);
    +         f = d2_cast64to32(&f64);
    +#endif
    +         ir = (ir / (1 << 4));
    +        
    +#ifndef _NO_LL_
    +         ir = (d2_s32)(ir64 / (1 << (4 + 8)));
    +#else
    +         d2_shiftright64(&ir64, (4 + 8), &tmp);
    +         ir = d2_cast64to32(&tmp);
    +#endif
    +         a = ((16 - (x * 2)) * ir) / (1 << 4);           /* (1 - 2x) * ir */  
    +         b = ((16 - (y * 2)) * ir) / (1 << 4);           /* (1 - 2y) * ir */ 
    +        
    +      }
    +      else
    +      {
    +         d2_int64 f64;
    +#ifdef _NO_LL_
    +         d2_int64 tmp, tmp2;
    +#endif
    +         /* get parameters for blurred circle rendering */
    +         blur = ctx->blurring; 
    +         ib = ctx->invblur;  
    +
    +         /* calc circle parameters (16:16 from 10:4) */
    +         ir = 
    +            (
    +               (
    +                  (
    +                     (
    +                        (-1 * D2_FIX16(16<<0))
    +                        * D2_FIX4(1)
    +                      )
    +                     *
    +                     (D2_FIX4(1) / 2)
    +                   )
    +                  / r
    +                )
    +               * (1 << LIMITER_HIPRECISION)
    +             )
    +            / blur;               /* 1 / 2rb */   
    +#ifndef _NO_LL_
    +         f64 =
    +            (
    +               (
    +                  (
    +                     (
    +                        (xr*xr) + (yr*yr)
    +                      )
    +                     / (1 << 8)
    +                   )
    +                  * (d2_int64)ir
    +                )
    +               / (1 << 4)
    +             ) 
    +            - 
    +            (
    +               (
    +                  (
    +                     (r / 2) + (xr + yr)
    +                   )
    +                  * (d2_int64)ib
    +                )
    +               * (1 << (LIMITER_HIPRECISION - 4))
    +             );      /* (x²+y²-r²) * ir */
    +#else
    +         d2_mul3232to64(((xr * xr) + (yr * yr)) / (1 << 8), ir, &tmp);
    +         d2_shiftright64(&tmp, 4, &f64);
    +         d2_mul3232to64(((r / 2) + (xr + yr)), (d2_s32)ib, &tmp);
    +         d2_shiftleft64(&tmp, (LIMITER_HIPRECISION - 4), &tmp2); 
    +         d2_sub64(&f64, &tmp2, &tmp);      /* (x²+y²-r²) * ir */
    +#endif 
    +         /* ir = ir / (1 << 4); */    /* testcase failure */
    +         ir >>= 4;                    /* works */       /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         a = ((16 - (x * 2)) * (d2_s32)ir) / (1 << (4 + 0));          /* (1 - 2x) * ir */  
    +         b = ((16 - (y * 2)) * (d2_s32)ir) / (1 << (4 + 0));          /* (1 - 2y) * ir */ 
    +#ifndef _NO_LL_
    +         f = (d2_s32)f64;   
    +#else
    +         f = d2_cast64to32(&tmp);
    +#endif
    +      }
    +
    +   }
    +   else
    +   {
    +      /* not blurred case (b == 1 && ib == 1) */
    +      if(0 == (xr | yr)) /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +      {
    +         /* integer aligned, nonclipped case (xr == 0 && yr == 0) */
    +         ir =
    +            (
    +               (
    +                  (-1 * D2_FIX16(1))
    +                  *
    +                  (D2_FIX4(1) / 2)
    +                )
    +             ) 
    +            / r;
    +         f = (-r) * (1 << (16 - 4 - 1));
    +         a = b = ((16 - (r * 2)) * ir) / 16;
    +      }
    +      else
    +      {
    +         d2_int64 ft;
    +         /*d2_int64 ftXXX;*/
    +         d2_s32 xq,yq;
    +#ifdef _NO_LL_
    +         d2_int64 tmp;
    +#endif
    +         /* subpixel positioned or clipped */
    +         ir =
    +            (
    +               (-1 * D2_FIX16(1 << TWEAK)) 
    +               *
    +               (D2_FIX4(1) / 2)
    +             )
    +            / r;
    +         xq = xr * xr;
    +         yq = yr * yr;
    +
    +#ifndef _NO_LL_
    +         /* (note) using the '/' variant of the following line will actually call a 64bit division subroutine
    +          *         the result of it sometimes differs by one bit compared to the '>>' variant, making
    +          *         "test_renderpolyline2" fail.
    +          *         however, this codepath is only taking in the windows softdave emulation environment
    +          */
    +         ft = ((xq + yq) * (d2_int64)ir) >> (8+TWEAK);              /* works */
    +         /*ft = ((xq + yq) * (d2_int64)ir) / (1 << (8 + TWEAK));*/  /* test_renderpolyline2 fails */
    +         /* ftXXX = ((xq + yq) * (d2_int64)ir) / (1 << (8 + TWEAK));*/   /* test_renderpolyline2 fails */
    +
    +         /*if(ft != ftXXX)
    +         {
    +            int i = 42;
    +         }*/
    +
    +         f = (d2_s32)ft - (((r / 2) + (xr + yr)) * (1 << (16 - 4)));
    +#else
    +         d2_mul3232to64((xq + yq), ir, &tmp);
    +         d2_shiftright64(&tmp, (8 + TWEAK), &ft);
    +         f  = d2_cast64to32(&ft) - (((r / 2) + (xr + yr)) * (1 << (16 - 4)));
    +#endif
    +         /* ir /= (1 << TWEAK); */   /* testcase failure */
    +         ir >>= TWEAK;                           /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         a = ((16 - (x * 2)) * ir) / (1 << 4);
    +         b = ((16 - (y * 2)) * ir) / (1 << 4);
    +      }
    +   }
    +
    +
    +   /* set register values (geometric parameters) */
    +   if(0 == invert)
    +   {
    +      D2_DLISTWRITES( D2_L1START + index, f + band );
    +      D2_DLISTWRITES( D2_L2START + index, a ); /* equal l1_xadd */
    +      D2_DLISTWRITES( D2_L1YADD  + index, b );
    +      D2_DLISTWRITES( D2_L2XADD  + index, ir * 2 );
    +      D2_DLISTWRITES( D2_L2YADD  + index, ir * 2 );
    +   }
    +   else
    +   {
    +      D2_DLISTWRITES( D2_L1START + index, -f - band );
    +      D2_DLISTWRITES( D2_L2START + index, -a ); /* equal l1_xadd */
    +      D2_DLISTWRITES( D2_L1YADD  + index, -b );
    +      D2_DLISTWRITES( D2_L2XADD  + index, -ir * 2 );
    +      D2_DLISTWRITES( D2_L2YADD  + index, -ir * 2 );
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_d0_mm_dynamic.c b/src/drivers/dave2d/src/dave_d0_mm_dynamic.c
    new file mode 100644
    index 000000000..e674f5d8c
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_d0_mm_dynamic.c
    @@ -0,0 +1,103 @@
    +//--------------------------------------------------------------------------
    +// Project: D/AVE
    +// File:    dave_d0_mm_dynamic.c (%version: 2 %)
    +//
    +// Description:
    +//  dynamic memory managment functions for dave.
    +//  %date_modified: Mon Feb 05 18:59:57 2007 %  (%derived_by:  hh74036 %)
    +//
    +// Changes:
    +//   2007-01-30 MGe start used old structure of d0_libs as base
    +//
    +#ifdef WITH_MM_DYNAMIC
    +
    +#include "dave_d0_mm_dynamic.h"
    +#include <stdlib.h>
    +
    +#ifdef NO_MSIZE
    +  #define MSIZE(PTR) *(((unsigned int*)(PTR))-1)
    +#else
    +  #include <malloc.h>
    +  #define MSIZE(PTR) _msize(PTR)
    +#endif
    +
    +static unsigned int g_memsum = 0;
    +static unsigned int g_numblocks = 0;
    +
    +//--------------------------------------------------------------------------
    +// function_:d0_dyn_allocmem
    +// Allocate memory from local heap.
    +//
    +// parameters:
    +//  size - size in bytes of requested memory
    +//
    +// returns:
    +//  pointer to memory, NULL if allocation failed
    +//
    +// see also:
    +//  <d0_freemem>
    +//
    +void * d0_dyn_allocmem( unsigned int size )
    +{
    +  unsigned int *ptr;
    +
    +  g_memsum += size;
    +  ++g_numblocks;
    +
    +#ifdef NO_MSIZE  
    +  ptr = malloc( (size_t)size + sizeof(unsigned int) );
    +  if (ptr) {
    +    *ptr = size;
    +    ++ptr;
    +  }
    +#else
    +  ptr = malloc( (size_t)size );
    +#endif
    + 
    +  return (void*) ptr;
    +}
    +
    +
    +//--------------------------------------------------------------------------
    +// function_: d0_dyn_freemem
    +// Free memory from local heap.
    +//
    +// parameters:
    +//  ptr - ptr to previously allocated memory
    +//
    +// see also:
    +//  <d0_allocmem>
    +//
    +void d0_dyn_freemem( void *ptr )
    +{
    +  if (ptr) {
    +    g_memsum -= MSIZE(ptr);
    +    --g_numblocks;
    +#ifdef NO_MSIZE
    +    free( ((unsigned int*)ptr)-1 );
    +#else
    +    free(ptr);
    +#endif
    +  }
    +}
    +
    +//--------------------------------------------------------------------------
    +// function_: d0_dyn_memsize
    +// Return the size of a memory chunk that was allocated using <d0_allocmem>.
    +//
    +// parameters:
    +//  ptr - ptr to allocated memory
    +//
    +// returns:
    +//  size of block, 0 if an error occurred
    +//
    +// see also:
    +//  <d0_allocmem>
    +//
    +unsigned int d0_dyn_memsize( void *ptr )
    +{
    +  if (!ptr) return 0;
    +  return MSIZE(ptr);
    +}
    +
    +#endif
    diff --git a/src/drivers/dave2d/src/dave_d0_mm_fixed_range.c b/src/drivers/dave2d/src/dave_d0_mm_fixed_range.c
    new file mode 100644
    index 000000000..4f3f1c912
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_d0_mm_fixed_range.c
    @@ -0,0 +1,353 @@
    +//--------------------------------------------------------------------------
    +// Project: D/AVE
    +// File:    dave_d0_mm_fixed_range.c (%version: 3 %)
    +//
    +// Description:
    +//  memory managment functions for dave.
    +//  first fit in a fixed range.
    +//  %date_modified: Tue Aug 28 10:39:19 2007 %  (%derived_by:  hh74036 %)
    +//
    +// Changes:
    +//   2006-11-21 CSe start
    +//   2007-01-24 MGe usedd as base for a local heapmanger without block lists
    +//   2007-08-28 MGe fixed comments, fixed a minor bug in setheapmem, maintains
    +//              testcode
    +#include "dave_d0_mm_fixed_range.h"
    +#if (!defined(_NO_ASSERT) && !defined(__CA850__))
    +      #include "assert.h"
    +#else
    +   #define assert(value)
    +#endif
    +
    +
    +/******************************************************************************
    + * memory allocater :
    + *  - strategy: first fit
    + *  - alignment : 4 bytes
    + *  - memory status is stored in the memory blocks
    + *     B  : address of memory block
    + *     B0 : ptr to the last block if the ptr is null it means that this block is free
    + *     B1 : size of the usable memory block
    + *     B2-Bn : usable Memory Block
    + *
    + *  - If a block is freed it will be merged with next and previous free blocks
    + *
    + *  - each functions works on the structure d0_heap that will be passed as first
    + *    parameter
    + *
    + *  - the function d0_setheapmem must be used to initialize a heap
    + *
    + *  - a free blk is marked with lastblk = NULL
    + *
    + *****************************************************************************/
    +
    +
    +typedef struct {
    +  void *base;
    +  void *end;  /* last valid address in heap*/
    +} d0_heap;
    +
    +typedef struct _memblk {
    +  struct _memblk *lastblk;
    +  unsigned int size;
    +} memblk;
    +
    +/* the minimalsize of a datablock in bytes*/
    +#define MINIMUM_BLOCKSIZE 4
    +
    +/******************************************************************************
    + * sets the memory range that shall be used as heap
    + * param:
    + *  base - pointer to the memory block that shall be used as heapmemory
    + *  size - size of the memory block in bytes
    + *****************************************************************************/
    +void d0_fixed_range_setheapmem( void *base, unsigned int size )
    +{
    +  /* create heap struct as header of memory alloc */
    +  d0_heap* heap  = (d0_heap*)base;
    +  /* test alignment and minimal size*/
    +  assert( ! (((unsigned int)base | size) & 3) );
    +  assert( size > ( sizeof(memblk) + sizeof(d0_heap)));
    +  heap->base = heap + 1;
    +  heap->end  = (char*)(heap->base) + size - 1 ;
    +  ((memblk*)(heap->base))->lastblk = NULL;
    +  ((memblk*)(heap->base))->size = size - sizeof(memblk);
    +}
    +
    +/******************************************************************************
    + * purpose: allocates a memory block
    + * param:
    + *  ctrlblk - startaddress of the heap
    + *  size    - size of the memory block that shall be allocated
    + * returns:
    + *  ptr to the allocated memory block
    + *****************************************************************************/
    +void * d0_fixed_range_heapalloc(void *ctrlblk, unsigned int size)
    +{
    +  /* create heap struct as header of memory alloc */
    +  d0_heap* heap  = (d0_heap*)ctrlblk;
    +
    +  memblk *runptr        = heap->base;
    +  memblk *blk_before    = (memblk*)1;
    +  memblk *newfragment   = NULL;
    +
    +  assert( size );
    +  /*align size to 4 bytes*/
    +  size = ( size + 3 ) & ~3;
    +  /* iterate heap range until a fitting block is found or end of heap is reached*/
    +  do {
    +    /* see if block is free and fits */
    +    if ( ( ! runptr->lastblk )  && ( runptr->size >= ( size + sizeof(memblk) ) ) )
    +    {
    +      /* write information for next block, if we produce a new fragment, which has as least MINIMUM_BLOCKSIZE Bytes usable size*/
    +      if ( ( runptr->size - size - sizeof(memblk) ) >  MINIMUM_BLOCKSIZE )
    +      {
    +        /* calc address of the resulting fragment  */
    +        newfragment = (memblk*)((char*)runptr + size + sizeof(memblk));
    +        /* calc size for the resulting fragment  */
    +        newfragment->size = runptr->size - size - sizeof(memblk);
    +        newfragment->lastblk = NULL;
    +
    +        /* correct last block ptr of old next ptr */
    +        if ( (void*)( (char*)newfragment + newfragment->size + sizeof(memblk)  ) <= heap->end )
    +        {
    +          ((memblk*)( (char*)newfragment + newfragment->size + sizeof(memblk) ))->lastblk = newfragment;
    +        }
    +
    +      } else {
    +        /* enlarge block, so that we don't have unusable small blks  */
    +        size = runptr->size;
    +      }
    +      /* write informat for found block*/
    +      runptr->size = size;
    +      runptr->lastblk = blk_before;
    +
    +      return (void*)((unsigned int)runptr + sizeof(memblk));
    +    }
    +    /* proceed to next element*/
    +    blk_before = runptr;
    +
    +    runptr = (memblk*)((unsigned int)runptr + runptr->size + sizeof(memblk));
    +  } while( (void*)runptr  <= (heap->end) );
    +  return NULL;
    +}
    +
    +/******************************************************************************
    + * purpose: frees a allocated memory block
    + * params:
    + *  ctrlblk - address of the heap
    + *  ptr     - address of the memory block that shall be freed
    + * returns: 1 on success
    + *****************************************************************************/
    +unsigned int d0_fixed_range_heapfree(void *ctrlblk, void *ptr )
    +{
    +  /* create heap struct as header of memory alloc */
    +  d0_heap* heap  = (d0_heap*)ctrlblk;
    +
    +  // fetch runptr, last_blk and next_blk
    +  memblk *runptr     = ((memblk*)ptr) - 1;
    +  memblk *last_blk   = runptr->lastblk;
    +  memblk *next_blk   = (memblk*)((unsigned int)runptr + runptr->size + sizeof( memblk ));
    +
    +   // set runptr to free
    +  runptr->lastblk = NULL;
    +  // now merge with last blk if inside of the heap
    +  if ( (void*)last_blk >= heap->base )
    +  {
    +    if ( ! last_blk->lastblk ) // last blk is a free block, so we have to merge
    +    {
    +      last_blk->size += runptr->size + sizeof( memblk );
    +      /* overwrite old infos from blk */
    +      runptr->size = 0;
    +      runptr->lastblk = 0;
    +      /* adjust lastblk from next blk merge now with next blk if possible */
    +      runptr = last_blk;
    +    }
    +  }
    +
    +  // see if we have to merge with the next_blk
    +  if ( ( ! next_blk->lastblk ) && ( (void*)next_blk  <= (heap->end) ) )
    +  {
    +    runptr->size += next_blk->size + sizeof( memblk );
    +    next_blk = (memblk*)((unsigned int)next_blk + next_blk->size + sizeof( memblk ));
    +  }
    +
    +  // check if next block is still inside of the heap,
    +  // so we have to adjust the lastblk pointer from the next_blk
    +  if ( (void*)next_blk  <= (heap->end) )
    +  {
    +    next_blk->lastblk = runptr;
    +  }
    +
    +  return 1;
    +}
    +/******************************************************************************
    + * purpose: returns the size of the current memoryblock
    + * params :
    + *  unused - not used
    + *  ptr   - ptr to the current memoryblock
    + * returns: size of the currentmemory block in bytes
    + *****************************************************************************/
    +unsigned int d0_fixed_range_heapmsize(void *unused, void *ptr)
    +{
    +  (void*)unused;
    +  return ((memblk*)ptr-1)->size;
    +}
    +
    +
    +#ifdef _TEST_HEAPMANAGER
    +#include <stdio.h>
    +#include <stdlib.h>
    +
    +/******************************************************************************
    + * purpose: test a heap with the memoryallocater
    + * params:
    + *  base  - startaddress for the heap
    + *  size  - size of the heap
    + * returns: 0 on failure
    + *          1 on success
    + *****************************************************************************/
    +int checkHeap( void* ctrlblk, unsigned int size ) {
    +  /* create heap struct as header of memory alloc */
    +  d0_heap* heap  = (d0_heap*)ctrlblk;
    +
    +  int counted_size = 0;
    +  memblk* runptr=heap->base;
    +  memblk* last=0;
    +  int blkindex=1;
    +  while ( (void*)runptr <= heap->end ) {
    +    counted_size += runptr->size + sizeof(memblk);
    +    if ( ! ( runptr->size ) ) {
    +      printf("illegal block size 0\n");
    +    }
    +
    +    // check that backward reference is consistent
    +    if ( last && runptr->lastblk) {
    +      if ( !(runptr->lastblk == last) ) {
    +        printf("link is broken\n");
    +      }
    +    }
    +    // next blk
    +    last = runptr;
    +    runptr = (memblk*)( (char*)runptr + sizeof(memblk) + runptr->size );
    +    ++blkindex;
    +    // check size
    +    if ( ( counted_size ) != ((int)runptr - (int)(heap->base) ) )
    +    {
    +      printf("error\n");
    +      //assert(( counted_size ) == ((int)runptr - (int)(heap->base) ));
    +    }
    +  }
    +  // check overall size
    +  if ( size != counted_size )
    +  {
    +    printf(" size should be: 0x%x, is: 0x%x\n",size, counted_size );
    +    assert( size == counted_size );
    +  }
    +}
    +
    +/******************************************************************************
    + * purpose: test a heap with the memoryallocater
    + * params:
    + *  base  - startaddress for the heap
    + *  size  - size of the heap
    + * returns: 0 on failure
    + *          1 on success
    + *****************************************************************************/
    +int testheap ( void* base, unsigned int size )
    +{
    +  int i, j, testcnt_overall = 50000;
    +  void* ptr[100];
    +  int blk;
    +  int sizeofblk;
    +  if ( base ) {
    +    d0_fixed_range_setheapmem( base, size );
    +    // init ptr array
    +    for ( i=0; i < 100; i++ ) ptr[i]=NULL;
    +    // do random mallocs and random frees
    +    for ( i = 0 ;  i < testcnt_overall ; i++ )
    +    {
    +      // random mallocs
    +      for ( j = 0 ; j < 100; j++ )
    +      {
    +        if ( ptr[j] ) continue;
    +        if ( ! ( rand() % 2 ) )
    +        {
    +          do {
    +            //sizeofblk = ((rand() % (size+10))+3)&~3;
    +            sizeofblk = rand();//((rand() % (size+10))+3)&~3;
    +          } while ( sizeofblk == 0);
    +          ptr[j] = d0_fixed_range_heapalloc( base, sizeofblk );
    +          if ( ptr[j] ) 
    +            checkHeap( base, size );
    +        }
    +      }
    +      // random frees
    +      for ( j = 0 ; j < 100; j++ )
    +      {
    +        if ( ! ptr[j] ) continue;
    +        if ( ! ( rand() % 4 ) )
    +        {
    +          if ( d0_fixed_range_heapfree( base, ptr[j] ) )
    +          {
    +            ptr[j] = NULL;
    +            checkHeap( base, size );
    +          }
    +         }
    +      }
    +    }
    +  } else {
    +    return 1;
    +  }
    +  for ( j = 0 ; j < 100; j++ )
    +  {
    +      if ( ! ptr[j] ) continue;
    +        if ( d0_fixed_range_heapfree( base, ptr[j] ) ) ptr[j] = NULL;
    +  }
    +  // check if the size of the heap is still the same
    +  unsigned int mbsize = ((memblk*)(((d0_heap*)base)->base))->size;
    +  if ( mbsize != (size-sizeof(memblk)) ) 
    +  {
    +    printf( "size(0x%x) of memoryblock does not equals the initial size (0x%x)\n",
    +        mbsize, size );
    +    return 0;
    +  }
    +  //return ( ((memblk*)base)->size == (size-sizeof(memblk)) ) ? 1 : 0;
    +  return 1;
    +
    +}
    +/******************************************************************************
    + * purpose: test the memoryallocater
    + * params:
    + *  param1
    + * returns: 0 on failure
    + *          1 on success
    + *****************************************************************************/
    +int testheapmanager( )
    +{
    +  int i = 100;
    +  int base, size;
    +  void* blk;
    +  // test several heaps
    +  for ( i=0 ; i < 100; i++ ) {
    +    size = rand() & ~3;
    +    //size=64;
    +    blk = malloc( size );
    +    if ( blk && (size >= 8)) {
    +      if ( testheap(  blk, size ) ) {
    +        printf("test %d %d success\n", blk, size);
    +      } else {
    +        printf("test %d %d fails\n", blk, size);
    +      };
    +    } else {
    +      //printf("warning: can't get memory block from malloc\n");
    +    }
    +    free(blk);
    +  }
    +}
    +
    +int main() {
    +  testheapmanager();
    +}
    +#endif
    +
    diff --git a/src/drivers/dave2d/src/dave_d0_mm_fixed_range_fixed_blkcnt.c b/src/drivers/dave2d/src/dave_d0_mm_fixed_range_fixed_blkcnt.c
    new file mode 100644
    index 000000000..d80bd5b7f
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_d0_mm_fixed_range_fixed_blkcnt.c
    @@ -0,0 +1,235 @@
    +//--------------------------------------------------------------------------
    +// Project: D/AVE
    +// File:    dave_d0_mm_fixed_range_fixed_blkcnt.c (%version: 2 %)
    +//
    +// Description:
    +//  memory management with controlstructure in a separate addressspace
    +//  %date_modified: Wed Feb 21 17:16:29 2007 %  (%derived_by:  hh74036 %)
    +//
    +// Changes:
    +//   2006-11-21 CSe: start
    +//   2007-01-31 MGe: redesign
    +//   2007-05-24 MGe: bugfix:added initialization of size field in blocklists
    +//   2009-09-23 SSt: bugfix in 3-block merge, added comments
    +
    +#include "dave_d0_mm_fixed_range_fixed_blkcnt.h"
    +#if (!defined(_NO_ASSERT) && !defined(__CA850__))
    +      #include "assert.h"
    +#else
    +   #define assert(value)
    +#endif
    +
    +//------------------------------------------------------------------------------------------------------------
    +//* Initialize the fixed block count heap.                                                                   *
    +//*                                                                                                          *
    +//* A fixed block count heap can manage up to maxblocks individual memory regions (mallloc).                 *
    +//*                                                                                                          *                
    +//* Memory information (allocations etc.) is stored inside a control block.                                  *
    +//* The control block stores the following information:                                                      *
    +//* - pointer to a free_list                                                                                 *
    +//* - pointer to a used_list                                                                                 *
    +//* - maximum number of blocks -1                                                                            *
    +//* - the free list (maxblocks entries of pointer and size)                                                  *
    +//* - the used list (maxblocks entries of pointer and size)                                                  *
    +//*                                                                                                          *
    +//* When calling this function ctrlblk must be big enough to store all this information.                     *                                                                                                         *
    +//*                                                                                                          *
    +//* Parameters:                                                                                              *
    +//*  ctrlblk :   pointer to the heap contol block.                                                           *
    +//*  heapaddr :  base address of the heap.                                                                   *
    +//*  heapsize :  size of the heap.                                                                           *
    +//*  maxblocks : maximum number of blocks.                                                                   *
    +//*                                                                                                          *
    +void d0_fixed_range_fixed_blkcnt_heapinit( void* ctrlblk, void* heapaddr, unsigned int heapsize, unsigned int maxblocks)
    +{
    +  unsigned int i;
    +  unsigned int alignedaddr;
    +  /* create heap structure */
    +  d0_fixed_range_fixed_blkcnt_heap* heap = (d0_fixed_range_fixed_blkcnt_heap*)ctrlblk;
    +  heap->freeblocks  = (d0_fixed_range_fixed_blk_memblock *)((char*)ctrlblk + sizeof( d0_fixed_range_fixed_blkcnt_heap ));
    +  heap->usedblocks  = (d0_fixed_range_fixed_blk_memblock *)((char*)heap->freeblocks + maxblocks*sizeof( d0_fixed_range_fixed_blk_memblock ));
    +  heap->maxidx      = maxblocks; 
    +  
    +  for (i=0;i<maxblocks;++i)
    +  {
    +    heap->freeblocks[i].addr = NULL;
    +    heap->freeblocks[i].size = 0;
    +    heap->usedblocks[i].addr = NULL;
    +    heap->usedblocks[i].size = 0;
    +  }
    +  /*align start of heap to 16 32Bit Words*/      
    +  alignedaddr = ( (unsigned int)heapaddr + 63 ) & ~63;
    +  heapsize -= alignedaddr - (unsigned int)heapaddr;
    +  
    +  heap->freeblocks[0].addr = (void*)alignedaddr;
    +  heap->freeblocks[0].size = heapsize;
    +  heap->maxidx = maxblocks-1;
    +}
    +
    +
    +//------------------------------------------------------------------------------------------------------------
    +//* allocate memory                                                                                          *
    +//*                                                                                                          *
    +//* Tries to allocate size bytes of heap (belonging to ctrlblk)                                              *
    +//*                                                                                                          *
    +//* Parameters:                                                                                              *
    +//*  ctrlblk :  pointer to the heap contol block.                                                            *
    +//*  size:      requested size in bytes                                                                      *
    +//*                                                                                                          *
    +//* Return Value:                                                                                            *
    +//*  NULL in case of an error, a pointer to the reserved memory otherwise.                                   *
    +//*                                                                                                          *
    +void * d0_fixed_range_fixed_blkcnt_heapalloc(void* ctrlblk, unsigned int size)
    +{
    +  char *mem = NULL;    
    +  d0_fixed_range_fixed_blkcnt_heap* heap = (d0_fixed_range_fixed_blkcnt_heap*)ctrlblk;
    +  // find room in used list
    +  d0_fixed_range_fixed_blk_memblock *used_blk  = heap->usedblocks;
    +  d0_fixed_range_fixed_blk_memblock *last_used = used_blk + heap->maxidx;
    +  /* align newly allocated memoryblocks to a size of 16 32Bit Words */  
    +  size = ( size + 63 ) & ~63;
    +  while ((used_blk <= last_used) && (used_blk->addr))
    +    ++used_blk;
    +
    +  if (used_blk <= last_used)
    +  {
    +    // find free block
    +    d0_fixed_range_fixed_blk_memblock *free_blk  = heap->freeblocks;
    +    d0_fixed_range_fixed_blk_memblock *last_free = free_blk + heap->maxidx;
    +
    +    // find suitable block in free list
    +    while ((!mem) && (free_blk <= last_free))
    +    {
    +      if (free_blk->size >= size)
    +      {
    +        mem = free_blk->addr;
    +        free_blk->addr = (char*)(free_blk->addr)+size;
    +        free_blk->size -= size;
    +        used_blk->addr = mem;
    +        used_blk->size = size;
    +      }
    +      else
    +        ++free_blk;
    +    }
    +  }
    +  if (!mem)
    +    assert(mem);
    +
    +  return (void*)mem;
    +}
    +
    +//------------------------------------------------------------------------------------------------------------
    +//* free memory                                                                                              *
    +//*                                                                                                          *
    +//* frees previously reserved memory                                                                         *
    +//*                                                                                                          *
    +//* Parameters:                                                                                              *
    +//*  ctrlblk :  pointer to the heap contol block.                                                            *
    +//*  ptr:       pointer to the memory block                                                                  *
    +//*                                                                                                          *
    +//* Return Value:                                                                                            *
    +//*  0 in case of an error, the size of the freed memory block.                                              *
    +//*                                                                                                          *
    +unsigned int d0_fixed_range_fixed_blkcnt_heapfree(void *ctrlblk, void *ptr )
    +{
    +  d0_fixed_range_fixed_blkcnt_heap* heap = (d0_fixed_range_fixed_blkcnt_heap*)ctrlblk;
    +  // find ptr in used list
    +  d0_fixed_range_fixed_blk_memblock *used_blk  = heap->usedblocks;
    +  d0_fixed_range_fixed_blk_memblock *last_used = used_blk + heap->maxidx;
    +  while ((used_blk <= last_used) && (used_blk->addr != ptr))
    +    ++used_blk;
    +  
    +  assert(used_blk->addr == ptr);
    +
    +  if (used_blk->addr == ptr)
    +  {
    +    // find free blocks, which can be merged with current block
    +    d0_fixed_range_fixed_blk_memblock *free_blk   = heap->freeblocks;
    +    d0_fixed_range_fixed_blk_memblock *last_free  = free_blk + heap->maxidx;
    +    d0_fixed_range_fixed_blk_memblock *pred_free  = NULL;  // direct predecessor
    +    d0_fixed_range_fixed_blk_memblock *succ_free  = NULL;  // direct successor
    +    d0_fixed_range_fixed_blk_memblock *empty_free = NULL;  // unused entry in free list
    +
    +    // find empty block/possibility to merge in free list
    +    while ( (!(pred_free && succ_free)) && (free_blk <= last_free) )
    +    {
    +      if (free_blk->addr)
    +      {
    +        if ( (!pred_free) && (((char*)(free_blk->addr) + free_blk->size) == ptr) )
    +          pred_free = free_blk;
    +
    +        if ( (!succ_free) && ((((char*)ptr) + used_blk->size) == free_blk->addr) )
    +          succ_free = free_blk;
    +      }
    +      else
    +        if (!empty_free)
    +          empty_free = free_blk;  // save first empty block
    +      ++free_blk;
    +    }
    +
    +    // now performe merge (in front of successor if possible, because that is the direction,
    +    // from where we allocate)
    +    if (succ_free)
    +    {
    +      succ_free->addr  = ptr;
    +      succ_free->size += used_blk->size;
    +      if (pred_free)
    +      {
    +        // both blocks (before and after) are free -> merge all three blocks
    +        // this leads to an empty enty in the free list
    +        succ_free->addr  = pred_free->addr;
    +        succ_free->size += pred_free->size;
    +
    +        pred_free->addr  = NULL; //  mark free entry as empty
    +        pred_free->size  = 0;    // any empty entry must have a size of 0
    +      }
    +    }
    +    else
    +    {
    +      if (pred_free)
    +        pred_free->size += used_blk->size;
    +      else
    +      {
    +        // no merge possible -> use an empty free entry
    +	      assert(empty_free);
    +	      if (empty_free)
    +	      {
    +	        empty_free->addr = ptr;
    +	        empty_free->size = used_blk->size;
    +	      }
    +      }
    +    }
    +
    +    // free used list entry
    +    used_blk->addr = NULL;
    +    return used_blk->size;
    +  }
    +  return 0;
    +}
    +
    +//------------------------------------------------------------------------------------------------------------
    +//* query block size memory                                                                                  *
    +//*                                                                                                          *
    +//* retrieve the size of a memory block previously reserved memory                                           *
    +//*                                                                                                          *
    +//* Parameters:                                                                                              *
    +//*  ctrlblk :  pointer to the heap contol block.                                                            *
    +//*  ptr:       pointer to the memory block                                                                  *
    +//*                                                                                                          *
    +//* Return Value:                                                                                            *
    +//*  0 in case of an error, the size of the memory block.                                                    *
    +//*                                                                                                          *
    +unsigned int d0_fixed_range_fixed_blkcnt_heapmsize(void *ctrlblk, void *ptr)
    +{
    +  d0_fixed_range_fixed_blkcnt_heap* heap = (d0_fixed_range_fixed_blkcnt_heap*)ctrlblk;
    +	// find ptr in used list
    +  d0_fixed_range_fixed_blk_memblock *used_blk  = heap->usedblocks;
    +  d0_fixed_range_fixed_blk_memblock *last_used = used_blk + heap->maxidx;
    +  while ((used_blk <= last_used) && (used_blk->addr != ptr))
    +    ++used_blk;
    +  
    +  // return 0 if pointer was not found, blocksize otherwise
    +  if (used_blk->addr != ptr) return 0;
    +
    +	return used_blk->size;
    +}
    diff --git a/src/drivers/dave2d/src/dave_d0lib.c b/src/drivers/dave2d/src/dave_d0lib.c
    new file mode 100644
    index 000000000..7f91d795c
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_d0lib.c
    @@ -0,0 +1,391 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_d0lib.c (%version: 7 %)
    + *
    + * Description:
    + *  memory management
    + *  %date_modified: Tue Feb 06 16:31:07 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + *   2006-11-21 CSe start
    + *   2007-01-31 MGe Redesign
    + *   2007-08-30 ASc fix d0_initheapmanager description, changed C++ to C comments 
    + *   2007-09-10 ASc added error checking to d0_allocvidmem 
    + *   2008-02-12 ASc removed compiler warnings
    + *   2008-11-24 MRe removed compiler warnings 
    + *-------------------------------------------------------------------------- */
    +#if (!defined(_NO_ASSERT) && !defined(__CA850__))
    +      #include "assert.h"
    +#else
    +   #define assert(value)
    +#endif
    +#include "dave_d0lib.h"
    +
    +#if ! defined( WITH_MM_FIXED_RANGE_FIXED_BLKCNT ) && ! defined( WITH_MM_FIXED_RANGE ) && ! defined( WITH_MM_DYNAMIC )
    +  #ifdef WIN32
    +    #error "No memory manager defined! Please define: WITH_MM_FIXED_RANGE_FIXED_BLKCNT, WITH_MM_FIXED_RANGE or WITH_MM_DYNAMIC."
    +  #else
    +    #warning "No memory manager defined! Please define: WITH_MM_FIXED_RANGE_FIXED_BLKCNT, WITH_MM_FIXED_RANGE or WITH_MM_DYNAMIC."
    +    #define WITH_MM_DYNAMIC
    +  #endif
    +#endif
    +
    +#ifdef WITH_MM_FIXED_RANGE_FIXED_BLKCNT
    +#include "dave_d0_mm_fixed_range_fixed_blkcnt.h"
    +#endif
    +
    +#ifdef WITH_MM_FIXED_RANGE
    +#include "dave_d0_mm_fixed_range.h"
    +#endif
    +
    +#ifdef WITH_MM_DYNAMIC
    +#include "dave_d0_mm_dynamic.h"
    +#endif
    +
    +#ifdef WITH_MM_DYNAMIC
    +  /******************************************************************************
    +   * purpose: allocate a piece of memory in the heap
    +   * params:
    +   *  size  - size of the memory block that shall be allocated
    +   * returns: a ptr to new allocated the memory block or NULL if an error occured
    +   *****************************************************************************/
    +  void* d0_dyn_allocmem_wrapper( void* ctrlblk, unsigned int size ) {
    +    (void *) ctrlblk;
    +    return d0_dyn_allocmem( size );
    +  }
    +
    +  /******************************************************************************
    +   * purpose: free a block of allocated memory
    +   * params:
    +   *  ptr - the startadress of the memory block we want to deallocate
    +   * returns:
    +   *****************************************************************************/
    +  void d0_dyn_freemem_wrapper( void* ctrlblk, void *ptr ) {
    +    (void *) ctrlblk;
    +    d0_dyn_freemem( ptr );
    +  }
    +
    +  /******************************************************************************
    +   * purpose: returns the size of the given memory block
    +   * params:
    +   *  ptr - prt to the start of the memoryblock
    +   * returns: the size of the given memoryblock
    +   *****************************************************************************/
    +  unsigned int d0_dyn_memsize_wrapper( void* ctrlblk, void *ptr ) {
    +    (void *) ctrlblk;
    +    return d0_dyn_memsize( ptr );
    +  }
    +#endif
    +
    +#ifdef WITH_MM_FIXED_RANGE
    +  /******************************************************************************
    +   * purpose: allocate a piece of memory in the heap
    +   * params:
    +   *  size  - size of the memory block that shall be allocated
    +   * returns: a ptr to new allocated the memory block or NULL if an error occured
    +   *****************************************************************************/
    +  void* d0_fixed_range_allocmen_wrapper( void* ctrlblk, unsigned int size ) {
    +    return d0_fixed_range_heapalloc( ctrlblk, size );
    +  }
    +
    +  /******************************************************************************
    +   * purpose: free a block of allocated memory
    +   * params:
    +   *  ptr - the startadress of the memory block we want to deallocate
    +   * returns:
    +   *****************************************************************************/
    +  void d0_fixed_range_freemen_wrapper( void* ctrlblk, void *ptr ) {
    +    d0_fixed_range_heapfree( ctrlblk, ptr );
    +  }
    +
    +  /******************************************************************************
    +   * purpose: returns the size of the given memory block
    +   * params:
    +   *  ptr - prt to the start of the memoryblock
    +   * returns: the size of the given memoryblock
    +   *****************************************************************************/
    +  unsigned int d0_fixed_range_memsize_wrapper( void* ctrlblk, void *ptr ) {
    +    return d0_fixed_range_heapmsize( ctrlblk, ptr );
    +  }
    +#endif
    +
    +#ifdef WITH_MM_FIXED_RANGE_FIXED_BLKCNT
    +  /******************************************************************************
    +   * purpose: allocate a piece of memory in the heap
    +   * params:
    +   *  size  - size of the memory block that shall be allocated
    +   * returns: a ptr to new allocated the memory block or NULL if an error occured
    +   *****************************************************************************/
    +  void * d0_fixed_range_fixed_blkcnt_allocmem_wrapper( void* ctrlblk, unsigned int size )
    +  {
    +    void *ptr = NULL;
    +
    +    ptr = d0_fixed_range_fixed_blkcnt_heapalloc( ctrlblk, size);
    +
    +    assert(ptr);
    +    if (!ptr)
    +      return NULL;
    +
    +    return ptr;
    +  }
    +
    +  /******************************************************************************
    +   * purpose: free a block of allocated memory
    +   * params:
    +   *  ptr - the startadress of the memory block we want to deallocate
    +   * returns:
    +   *****************************************************************************/
    +  void d0_fixed_range_fixed_blkcnt_freemem_wrapper( void* ctrlblk, void *ptr )
    +  {
    +    d0_fixed_range_fixed_blkcnt_heapfree( ctrlblk, ptr);
    +  }
    +
    +  /******************************************************************************
    +   * purpose: returns the size of the given memory block
    +   * params:
    +   *  ptr - prt to the start of the memoryblock
    +   * returns: the size of the given memoryblock
    +   *****************************************************************************/
    +  unsigned int d0_fixed_range_fixed_blkcnt_memsize_wrapper( void* ctrlblk, void *ptr )
    +  {
    +   if (!ptr) return 0;
    +   return d0_fixed_range_fixed_blkcnt_heapmsize( ctrlblk, ptr);
    +  }
    +#endif
    +
    +/******************************************************************************
    + * purpose: dummy functions for alloc, free and msize
    + *****************************************************************************/
    +void* d0_dummy_alloc( void* ctrlblk,unsigned int size ) {  (void ) ctrlblk; (void) size; return NULL; }
    +void d0_dummy_free( void* ctrlblk,void * ptr) { (void ) ctrlblk; (void) ptr; }
    +unsigned int d0_dummy_memsize( void* ctrlblk,void *ptr){ (void ) ctrlblk; (void ) ptr; return 0;}
    +
    +/******************************************************************************
    + * purpose: initalize a heapmanager
    + * params:
    + *  memmanagertype  - defines which kind of memorymangment will be used
    + *
    + *  base            - baseaddress of the addressrange( not used for
    + *                    d0_mm_dynamic memorymanager)
    + *
    + *  size            - size of the memory in bytes( not used for
    + *                    d0_mm_dynamic memorymanager)
    + *
    + *  ctrlblk         - startaddress of memory block used for controlstructure
    + *                    this block must have a size of:
    + *                    2*blockcnt*sizeof( d0_fixed_range_fixed_blk_memblock )
    + *                    +sizeof(d0_fixed_range_fixed_blkcnt_heap)
    + *
    + *  blockcnt        - amount of allocatable blocks in memoryrange( only used
    + *                    for d0_mm_fixed_range_fixed_blkcnt memorymanager)
    + *****************************************************************************/
    +void d0_preparememorymanager( d0_memmanager *mgr, d0_memmanager_type memmanagertype, void *base,
    +                          unsigned int size, void *ctrlblk, unsigned int blkcnt )
    +{
    +  (void)blkcnt; (void*)ctrlblk; (void)size; (void*)base;
    +  if ( ! mgr ) {
    +    return;
    +  }
    +  switch ( memmanagertype ) {
    +    case d0_mm_dynamic :
    +      #ifdef WITH_MM_DYNAMIC
    +        mgr->allocmem = d0_dyn_allocmem_wrapper;
    +        mgr->freemem  = d0_dyn_freemem_wrapper;
    +        mgr->memsize  = d0_dyn_memsize_wrapper;
    +      #endif
    +      break;
    +    case d0_mm_fixed_range :
    +      #ifdef WITH_MM_FIXED_RANGE
    +        d0_fixed_range_setheapmem( base, size );
    +        mgr->allocmem = d0_fixed_range_allocmen_wrapper;
    +        mgr->freemem  = d0_fixed_range_freemen_wrapper;
    +        mgr->memsize  = d0_fixed_range_memsize_wrapper;
    +        mgr->ctrlblk = base;
    +      #endif
    +      break;
    +    case d0_mm_fixed_range_fixed_blkcnt :
    +      #ifdef WITH_MM_FIXED_RANGE_FIXED_BLKCNT
    +        d0_fixed_range_fixed_blkcnt_heapinit( mgr->ctrlblk, base, size, blkcnt );
    +        mgr->allocmem = d0_fixed_range_fixed_blkcnt_allocmem_wrapper;
    +        mgr->freemem  = d0_fixed_range_fixed_blkcnt_freemem_wrapper;
    +        mgr->memsize  = d0_fixed_range_fixed_blkcnt_memsize_wrapper;
    +        mgr->ctrlblk = ctrlblk;
    +      #endif
    +      break;
    +    default:
    +      mgr->allocmem = d0_dummy_alloc;
    +      mgr->freemem = d0_dummy_free;
    +      mgr->memsize = d0_dummy_memsize;
    +      break;
    +  }
    +}
    +
    +/******************************************************************************
    + * videomemory and heapmemory manager
    + *****************************************************************************/
    +static d0_memmanager* videomemory = NULL;
    +static d0_memmanager heapmemory={NULL,NULL,NULL,NULL};
    +
    +
    +/******************************************************************************
    + * purpose: returns the size of a ctrlblk structure for a
    + *          fixed_range_fixed_blkcnt memory manager
    + * params:
    + *  blkcnt  - blockcount used in the memorymanager
    + * returns: returns the size of a ctrlblk structure for a
    + *          fixed_range_fixed_blkcnt memory manager
    + *****************************************************************************/
    +unsigned int get_fixed_range_fixed_blkcnt_ctrlblksize( unsigned int blkcnt )
    +{
    +  #ifdef WITH_MM_FIXED_RANGE_FIXED_BLKCNT
    +  return 2*blkcnt*sizeof( d0_fixed_range_fixed_blk_memblock )
    +         + sizeof(d0_fixed_range_fixed_blkcnt_heap);
    +  #else
    +    (void)blkcnt;
    +    assert(0);
    +    return 0;
    +  #endif
    +}
    +
    +/******************************************************************************
    + * purpose: initialize one memory manager for the heap memory and one for the 
    + *          video memory
    + * params:
    + *  heapaddress   - start address of the heap memory
    + *  heapsize      - size of the heap in bytes
    + *  heapmgrtype   - type of the memory manager use for the memory
    + *  vidmemaddress - start address of the video memory manager
    + *  vidmemsize    - size of the video memory
    + *  vidmemblkcnt  - amount of allocatable blocks in video memory range
    + *  vidmemmgrtype - type of the memory manager use for the videomemory
    + *  flags         - possible values (d0_ma_unified, d0_ma_separated)
    + * returns: 1 on success otherwise 0
    + 
    + *****************************************************************************/
    +int d0_initheapmanager(  void* heapaddress, unsigned int heapsize,
    +                         d0_memmanager_type heapmgrtype, void* vidmemaddress,
    +                         unsigned int vidmemsize, unsigned int vidmemblkcnt,
    +                         d0_memmanager_type vidmemmgrtype,
    +                         d0_memarchitectures flags
    +                        )
    +{
    +  /* check arguments */
    +  if ( ! heapsize ) {
    +    return 0;
    +  }
    +  /* initialize system heap memory manager */
    +  if ( heapmgrtype == d0_mm_fixed_range_fixed_blkcnt ) {
    +    return 0;
    +  }
    +  d0_preparememorymanager( &heapmemory, heapmgrtype, heapaddress, heapsize, NULL , 0 );
    +  /* initialize video memory manager if needed */
    +  if ( flags & d0_ma_separated ) {
    +    if ( vidmemsize ) {
    +      /* allocate space for the videomemory controlstructure */
    +      videomemory = d0_allocmem( sizeof(d0_memmanager) ) ;
    +      if ( ! videomemory ) {
    +        return 0;
    +      }
    +      /* allocate extended videomemory control structure if necessary */
    +      if ( vidmemmgrtype == d0_mm_fixed_range_fixed_blkcnt ) {
    +        videomemory->ctrlblk = d0_allocmem( get_fixed_range_fixed_blkcnt_ctrlblksize( vidmemblkcnt ) );
    +        if ( ! videomemory->ctrlblk ) {
    +          return 0;
    +        }
    +      } else {
    +        videomemory->ctrlblk = vidmemaddress;
    +      }
    +      d0_preparememorymanager( videomemory, vidmemmgrtype, vidmemaddress, vidmemsize, videomemory->ctrlblk, vidmemblkcnt );
    +    } else {
    +      return 0;
    +    }
    +  } else {
    +    videomemory = &heapmemory;
    +  }
    +  return 1;
    +}
    +/******************************************************************************
    + * purpose: initialize d0_mm_dynamic as default memorymanager.
    + * params:
    + * returns:  1
    + *****************************************************************************/
    +int d0_initdefaultheapmanager( void )
    +{
    +  d0_preparememorymanager( &heapmemory, d0_mm_dynamic, 0, 0, NULL , 0 );
    +  videomemory = &heapmemory;
    +  return 1;
    +}
    +
    +/******************************************************************************
    + * purpose: allocate videomemory
    + * params:
    + *  size    -   size of the memory block in bytes
    + * returns: a ptr to the new allocated memoryblock or NULL if an error occured
    + *****************************************************************************/
    +void * d0_allocvidmem( unsigned int size )
    +{
    +  if (!videomemory) return NULL;
    +  if (!videomemory->allocmem || !videomemory->ctrlblk) return NULL;
    +  
    +  return videomemory->allocmem( videomemory->ctrlblk, size);
    +}
    +
    +/******************************************************************************
    + * purpose: free a block of videomemory
    + * params:
    + *  ptr     - pointer to the memory block
    + *****************************************************************************/
    +void d0_freevidmem( void *ptr )
    +{
    +  videomemory->freemem(videomemory->ctrlblk, ptr);
    +}
    +/******************************************************************************
    + * purpose: returns the size of a video memory block
    + * params:
    + *  ptr     - points to the memory block
    + * returns: the size of the memory block
    + *****************************************************************************/
    +unsigned int d0_vidmemsize(  void *ptr )
    +{
    +  return videomemory->memsize(videomemory->ctrlblk, ptr);
    +}
    +
    +/******************************************************************************
    + * purpose: allocate heapmemory
    + * params:
    + *  size    -   size of the memory block in bytes
    + * returns: a ptr to the new allocated memoryblock or NULL if an error occured
    + *****************************************************************************/
    +void * d0_allocmem( unsigned int size )
    +{
    +  if ( heapmemory.allocmem ) {
    +    return heapmemory.allocmem( heapmemory.ctrlblk, size);
    +  } else {
    +  #ifdef WITH_MM_DYNAMIC
    +      d0_initdefaultheapmanager();
    +      return heapmemory.allocmem( heapmemory.ctrlblk, size);
    +  #else
    +    return NULL;
    +  #endif
    +  }
    +}
    +/******************************************************************************
    + * purpose: free a block of videomemory
    + * params:
    + *  ptr     - pointer to the memory block
    + *****************************************************************************/
    +void d0_freemem( void *ptr )
    +{
    +  heapmemory.freemem(heapmemory.ctrlblk, ptr);
    +}
    +/******************************************************************************
    + * purpose: returns the size of a memory block
    + * params:
    + *  ptr     - points to the memory block
    + * returns: the size of the memory block
    + *****************************************************************************/
    +unsigned int d0_memsize( void *ptr )
    +{
    +  return heapmemory.memsize(heapmemory.ctrlblk, ptr);
    +}
    +
    diff --git a/src/drivers/dave2d/src/dave_dlist.c b/src/drivers/dave2d/src/dave_dlist.c
    new file mode 100644
    index 000000000..46af6cddd
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_dlist.c
    @@ -0,0 +1,1416 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_dlist.c (%version: 32 %)
    + *          created Thu Feb 17 21:45:11 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Mar 08 15:05:30 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + * 2005-12-22 CSe  - fix nextdlistblock(): jump was inserted after end of block
    + *                 - added d2_copydlist_vidmem_intern()
    + *                 - renamed block->vram to block->vidmem for consistency
    + * 2006-01-05 CSe  - free vidmem when dlist is free'd
    + * 2006-02-28 CSe  - adapted to changes in memory allocation of dlist mem
    + *                 - added d2_cacheflushdlist_intern()
    + * 2006-05-10 CSe  - changes for systems with statically mapped vidmem
    + * 2006-10-30 CSe  - removed counting of dlist used slots
    + * 2006-11-07 CSe  - changes for new 'd2_df_low_localmem' mode
    + * 2006-11-30 CSe  - fixed insertion of dlist special commands
    + * 2007-03-08 CSe  - optimized dlist copying and flushing
    + * 2007-05-23 MGe  - insert null pointer checks to d2_init_dlist_intern, d2_growdlist_inter,
    + *                   d2_nextdlistblock_intern
    + * 2007-10-23 CSe  - added dynamic shrinking of display list
    + * 2008-01-14 ASc  - changed comments from C++ to C, removed tabs
    + * 2008-08-21 MRe  - fixed dynamic shrinking for low_localmem
    + * 2010-07-08 MRe  - fixed support for register caching defined by D2_USEREGCACHE 
    + *                    new device flag d2_df_no_registercaching
    + * 2011-02-07 SSt  - ensure a flush for all dlist ends (needed for multithreading)
    + * 2011-02-28 SSt  - fixed while loop
    + * 2011-03-10 MRe  - invalidate register chaches with every dlist reset
    + * 2011-03-11 MRe  - fixed crash under WIN32 at freemem
    + * 2012-07-18 MRe  - added dlist functions d2_executedlist, d2_adddlist
    + * 2012-09-25 BSp  - MISRA cleanup
    + * 2012-10-16 MRe  - fixed freemem for d2_df_no_dlist
    + * 2017-07-27 HFu  - clearly commented and renamed d2_insertwait...dlist_intern functions
    + * 2020-02-21 MRe  - removed code for big endian
    + *-------------------------------------------------------------------------- */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Dlist Functions
    + *
    + *
    + *-------------------------------------------------------------------------- */
    +
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_dlist.h"
    +#include "dave_memory.h"
    +
    +
    +#define D2_EXECUTE_DLIST_NEEDWAIT defined
    +
    +/*--------------------------------------------------------------------------*/
    +
    +static d2_s32 d2_dlist2dlist_intern( d2_device *handle, d2_dlist *dlist, void *address, d2_s32 size );
    +
    +/*--------------------------------------------------------------------------
    + * create a display list block (displaylist memory can be fetched from a
    + * different heap, see dave_memory.h for detials)
    + * size specifies the number of dlist entries (4 register slots per entry)
    + * */
    +d2_dlist_block * d2_alloc_dlistblock_intern( const d2_device *handle, d2_u32 size )
    +{
    +   d2_dlist_block *dlb;
    +   d1_device      *id = D2_DEV(handle)->hwid;
    +
    +   /* get controlling block structure */
    +   dlb = (d2_dlist_block*) d2_getmem_p( sizeof(d2_dlist_block) );
    +
    +   if(NULL == dlb) 
    +   {
    +      return NULL;
    +   }
    +
    +   /* fill block */
    +   dlb->quantity = size;
    +   dlb->jump   = NULL;
    +
    +   /* get block data */
    +   if(0 == (D2_DEV(handle)->flags & d2_df_no_dlist)) 
    +   {
    +      dlb->block = (d2_dlist_entry*) d2_getmem_d( handle, sizeof(d2_dlist_entry) * size );
    +   } 
    +   else
    +   {
    +      dlb->block = (d2_dlist_entry*) d2_getmem_p( sizeof(d2_dlist_entry) * size );
    +   }
    +
    +   if(NULL == dlb->block)
    +   {
    +      /* failed to get display list memory */
    +      d2_freemem_p( dlb );
    +      return NULL;
    +   }
    +
    +   dlb->vidmem = NULL;
    +   if(0 == (D2_DEV(handle)->flags & d2_df_no_dlist) ) 
    +   {
    +      if(0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_mapped))
    +      {
    +         dlb->vidmem = d1_maptovidmem(id, dlb->block);
    +      }
    +      else if (0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_separated))
    +      {
    +         dlb->vidmem = d1_allocvidmem( id, d1_mem_dlist, sizeof(d2_dlist_entry) * dlb->quantity );
    +      }
    +      else
    +      {
    +         /* empty else block to satisfy MISRA rule 14.10/2004 */
    +      }
    +   }
    +
    +   dlb->next = NULL;
    +
    +   return dlb;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * free display list block.
    + * free the specified display list block and all childs in its chain
    + * */
    +void d2_free_dlistblock_intern( const d2_device *handle, d2_dlist_block *data )
    +{
    +   d2_dlist_block *n;
    +   d1_device      *id = D2_DEV(handle)->hwid;
    +
    +   /* free chain */
    +   while(NULL != data)
    +   {
    +      n = data->next;
    +      if(0 == (D2_DEV(handle)->flags & d2_df_no_dlist)) 
    +      {
    +          d2_freemem_d( handle, data->block );
    +      }
    +      else
    +      {
    +          d2_freemem_p( data->block );
    +      }
    +      if( (NULL != data->vidmem) && (0 != ((D2_DEV(handle)->hwmemarchitecture) & d1_ma_separated)) )
    +      {
    +         d1_freevidmem( id, d1_mem_dlist, data->vidmem );
    +      }
    +      d2_freemem_p( data );
    +      data = n;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * grow display list.
    + * allocate a new display block and chain it into the list. new block becomes
    + * current block automatically.
    + * */
    +void d2_growdlist_intern( d2_dlist *dlist )
    +{
    +   d2_dlist_block *n;
    +
    +   n = dlist->currentblock->next;
    +   if(NULL == n)
    +   {
    +      /* need a new block */
    +      n = d2_alloc_dlistblock_intern( dlist->device, dlist->stepsize );
    +      if(NULL == n)
    +      {
    +         D2_DEV(dlist->device)->delayed_errorcode = D2_NOT_ENOUGH_DLISTBLOCKS;
    +         return;
    +      }
    +      /* chain blocks */
    +      dlist->currentblock->next = n;
    +   }
    +
    +   /* reset patch address */
    +   n->jump = NULL;
    +
    +   /* switch to next block */
    +   dlist->position     = n->block;
    +   dlist->blocksize    = n->quantity;
    +   dlist->currentblock = n;
    +
    +   /* tagindex is reset outside */
    +}
    +
    +/*--------------------------------------------------------------------------
    + * init display list.
    + * prepare a display list structure for usage. creates an initial block.
    + * returns boolean success.
    + * */
    +d2_s32 d2_initdlist_intern( d2_device *handle, d2_dlist *dlist, d2_u32 initialsize )
    +{
    +   void *current_dlist_start;
    +   dlist->device = handle;
    +   dlist->vidmem_blocks = NULL;
    +
    +   if(0 != D2_DEV(handle)->lowlocalmem_mode)
    +   {
    +      d2_lowlocalmem_mode* llm_mode = D2_DEV(handle)->lowlocalmem_mode;
    +      dlist->firstblock = llm_mode->dlist_buffer;
    +
    +      dlist->vidmem_blocks = d2_getmem_p(sizeof(d2_dlist_vidmem_blocks));
    +
    +      if(NULL == dlist->vidmem_blocks) 
    +      {
    +         return 0;
    +      }
    +
    +      {
    +         d2_dlist_vidmem_blocks *vmem_blocks = dlist->vidmem_blocks;
    +         d2_u32 i;
    +         vmem_blocks->blocks = d2_getmem_p(llm_mode->vidmemblocks * sizeof(void*));
    +         if(NULL == vmem_blocks->blocks)
    +         {
    +            return 0;
    +         }
    +         vmem_blocks->num_blocks = llm_mode->vidmemblocks;
    +         vmem_blocks->block_size = llm_mode->vidmemblocksizefactor * D2_DEV(handle)->dlistblocksize;
    +         vmem_blocks->num_slices = llm_mode->vidmemblocksizefactor;
    +
    +         for (i=0; i<vmem_blocks->num_blocks; ++i)
    +         {
    +            vmem_blocks->blocks[i] = NULL;
    +         }
    +         vmem_blocks->currentblock = vmem_blocks->blocks;
    +         /* allocate first block in vidmem */
    +         vmem_blocks->blocks[0] = d1_allocvidmem(D2_DEV(handle)->hwid, d1_mem_dlist, sizeof(d2_dlist_entry) * vmem_blocks->block_size);
    +         if(NULL == vmem_blocks->blocks[0]) 
    +         {
    +            return 0;
    +         }
    +         vmem_blocks->currentaddress = vmem_blocks->blocks[0];
    +         vmem_blocks->blocksleft = vmem_blocks->num_blocks;
    +         vmem_blocks->slicesleft = vmem_blocks->num_slices;
    +      }
    +   }
    +   else
    +   {
    +      dlist->firstblock = d2_alloc_dlistblock_intern( handle, initialsize );
    +   }
    +   dlist->resumeblock = dlist->firstblock;
    +
    +   if(NULL == dlist->firstblock) 
    +   {
    +      return 0;
    +   }
    +
    +   dlist->currentblock = dlist->firstblock;
    +   dlist->position = dlist->firstblock->block;
    +   dlist->blocksize = dlist->firstblock->quantity;
    +   dlist->tagindex = 0;
    +   dlist->shrinkcount = 0;
    +   dlist->count = 0;
    +
    +   dlist->dlist_addresses_max = DLIST_ADRESSES_NUMBER;
    +   dlist->dlist_addresses     = d2_getmem_p(DLIST_ADRESSES_NUMBER*sizeof(d2_s32*));
    +   if(NULL == dlist->dlist_addresses) 
    +   {
    +      return 0;
    +   }
    +
    +   if(NULL != dlist->vidmem_blocks)
    +   {
    +      /* low localmem mode: vidmem is already filled */
    +      current_dlist_start = dlist->vidmem_blocks->blocks[0];
    +   }
    +   else if( (0 != ((D2_DEV(handle)->hwmemarchitecture) & (d1_ma_separated | d1_ma_mapped))) && (NULL != dlist->firstblock->vidmem) )
    +   {
    +      current_dlist_start = dlist->firstblock->vidmem;
    +   }
    +   else
    +   {
    +      current_dlist_start = dlist->firstblock->block;
    +   }
    +   /* reset list of dlist start addresses */
    +   d2_clear_dlistlist_intern(handle, dlist);
    +   (void)d2_add_dlistlist_intern(handle, dlist, current_dlist_start);
    +
    +   return 1;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * de-initialize display list.
    + * free all allocated memory areas
    + * */
    +void d2_deinitdlist_intern(const d2_dlist *dlist)
    +{
    +   if(NULL != dlist->vidmem_blocks)
    +   {
    +      d2_u32 i;
    +      d1_device *id = D2_DEV(dlist->device)->hwid;
    +      for (i=0; i<dlist->vidmem_blocks->num_blocks; ++i)
    +      {
    +         if(NULL != dlist->vidmem_blocks->blocks[i])
    +         {
    +            d1_freevidmem(id, d1_mem_dlist, dlist->vidmem_blocks->blocks[i]);
    +         }
    +      }
    +      d2_freemem_p(dlist->vidmem_blocks->blocks);
    +      d2_freemem_p(dlist->vidmem_blocks);
    +   }
    +   else
    +   {
    +      d2_free_dlistblock_intern( dlist->device, dlist->firstblock );
    +   }
    +   if(NULL != dlist->dlist_addresses)
    +   {
    +      d2_freemem_p(dlist->dlist_addresses);
    +   }
    +   return;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * go to next display list block.
    + * used when the blocksize of the current dlist block is <= 1
    + * the last entry will be spared for a jump which might be necessary
    + * */
    +void d2_nextdlistblock_intern( d2_dlist *dlist )
    +{
    +   d2_dlist_vidmem_blocks *vidmemBlocks = dlist->vidmem_blocks;
    +
    +   if(NULL == vidmemBlocks )
    +   { /* normal mode -> always insert jump and start next block */
    +      d2_s32 *patch = d2_insertdlistjump_intern( dlist, NULL );
    +      d2_insertdlistspecial_intern( dlist, 3 );  /* terminate list correctly */
    +      /* grow to prepare for next write */
    +      d2_growdlist_intern( dlist );
    +      /* check if d2_growdlist succeded */
    +      if ( D2_DEV(dlist->device)->delayed_errorcode != D2_OK )
    +      {
    +         /* no more memory -> terminate current list */
    +         dlist->position = (d2_dlist_entry *) (((d2_s32*)dlist->position) - 3);
    +         d2_insertdlistspecial_intern( dlist, 3 );
    +         return;
    +      }
    +      /* insert next block address (fix jump) */
    +      *patch = (d2_s32) dlist->currentblock->block;
    +   }
    +   else if ((dlist->blocksize < 1) || (vidmemBlocks->slicesleft == 1))
    +   { /* 'low localmem' mode: the spare block for the jump is only needed in last slice */
    +      d1_device *id = D2_DEV(dlist->device)->hwid;
    +
    +      if (vidmemBlocks->slicesleft > 1)
    +      { /* current slice is now completely filled: make sure to pad possible remaining words */
    +         d2_dlist_block *blk = dlist->currentblock;
    +         d2_s32* end = (d2_s32*)(blk->block + blk->quantity);
    +         d2_s32* pos = (d2_s32*)(dlist->position);
    +         d2_s8 *nextaddress = vidmemBlocks->currentaddress + (sizeof(d2_dlist_entry) * blk->quantity);
    +         if(NULL != blk->jump)
    +         {
    +            *(blk->jump) = (d2_s32)nextaddress;
    +            blk->jump = 0;
    +         }
    +         while (pos < end)
    +         {
    +            *pos= (d2_s32)0x80808080u;
    +            pos++;
    +         }
    +         (void)d1_copytovidmem( id, vidmemBlocks->currentaddress, blk->block, sizeof(d2_dlist_entry) * blk->quantity, d1_cf_async );
    +         vidmemBlocks->currentaddress = nextaddress;
    +         vidmemBlocks->slicesleft--;
    +      }
    +      else if (vidmemBlocks->blocksleft > 1)
    +      { /* last slice -> allocate new vidmem block (only if blocks left), insert jump */
    +         d2_dlist_block *blk = dlist->currentblock;
    +         void **nextblock = vidmemBlocks->currentblock + 1;
    +         vidmemBlocks->blocksleft--;
    +
    +         /* allocate next block if necessary */
    +         if (*nextblock == NULL)
    +         {
    +            *nextblock = d1_allocvidmem(id, d1_mem_dlist, sizeof(d2_dlist_entry) * vidmemBlocks->block_size);
    +            if(NULL == *nextblock)
    +            {
    +               D2_DEV(dlist->device)->delayed_errorcode = D2_NOMEMORY ; /* can't get videomemory */
    +            }
    +         }
    +
    +         if(NULL != *nextblock) /* don't insert a jump to null into the list ( happens if allocation of vidmem failed) */
    +         {
    +            if(NULL != blk->jump)
    +            {
    +               *(blk->jump) = (d2_s32)(*nextblock);
    +               blk->jump = 0;
    +            }
    +            else
    +            {
    +               (void)d2_insertdlistjump_intern( dlist, *nextblock );
    +            }
    +         }
    +         d2_insertdlistspecial_intern( dlist, 3 );  /* terminate list correctly */
    +
    +         /* copy the current dlist block to position inside current vidmem block */
    +         (void)d1_copytovidmem( id, vidmemBlocks->currentaddress, dlist->currentblock->block, sizeof(d2_dlist_entry) * dlist->currentblock->quantity, d1_cf_async );
    +
    +         if(NULL != *nextblock)
    +         {
    +            vidmemBlocks->currentblock   = nextblock;
    +            vidmemBlocks->currentaddress = *nextblock;
    +            vidmemBlocks->slicesleft     = vidmemBlocks->num_slices;
    +         }
    +      } 
    +      else if ( (1 == vidmemBlocks->blocksleft) && (1 == vidmemBlocks->slicesleft) ) 
    +      {
    +         D2_DEV(dlist->device)->delayed_errorcode = D2_NOT_ENOUGH_DLISTBLOCKS;      
    +      }
    +      else
    +      {
    +         /* empty else block to satisfy MISRA rule 14.10/2004 */
    +      }
    +    
    +      d2_growdlist_intern( dlist );  /* go to next dlist buffer in ring */
    +
    +      /* check if d2_growdlist succeded */
    +      if ( D2_DEV(dlist->device)->delayed_errorcode != D2_OK )
    +      {
    +         return;
    +      }
    +   }
    +   else
    +   {
    +      /* empty else block to satisfy MISRA rule 14.10/2004 */
    +   }
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * pad display list.
    + * pad remaining entries of current addressword with 0x80 nop codes and fix
    + * address to point onto the next free full entry.
    + * */
    +void d2_paddlist_intern( d2_dlist *dlist )
    +{
    +   d2_u32 tagIndex = dlist->tagindex;
    +   d2_dlist_entry *pos = dlist->position;
    +
    +   switch (tagIndex)
    +   {
    +      case 0:
    +         /* list already closed */
    +         return;
    +
    +      case 1:
    +         pos->address.mask &= 0x000000ffu;
    +         pos->address.mask |= 0x80808000u;
    +         dlist->position = (d2_dlist_entry *) ((d2_s32*)pos + 2);
    +         break;
    +
    +      case 2:
    +         pos->address.mask &= 0x0000ffffu;
    +         pos->address.mask |= 0x80800000u;
    +         dlist->position = (d2_dlist_entry *) ((d2_s32*)pos + 3);
    +         break;
    +
    +      case 3:
    +         pos->address.mask &= 0x00ffffffu;
    +         pos->address.mask |= 0x80000000u;
    +         dlist->position = (d2_dlist_entry *) ((d2_s32*)pos + 4);
    +         break;
    +         
    +      default:
    +         break;
    +   }
    +
    +   /* fix tag */
    +   dlist->tagindex = 0;
    +   dlist->blocksize--;
    +}
    +
    +/*-------------------------------------------------------------------------- */
    +void d2_resetdlist_intern( d2_dlist *dlist )
    +{
    +#ifdef D2_USEREGCACHE
    +   d2_cacheddata *cachedData = & ((d2_devicedata *) dlist->device)->cache;
    +   d2_s32 regIdx;
    +   if(0 == (((d2_devicedata *) dlist->device)->flags & d2_df_no_registercaching))
    +   {
    +      for (regIdx = 0; regIdx < D2_QUANTITY; regIdx++)
    +      {
    +         cachedData->valid[regIdx] = 0;
    +      }
    +   }
    +#endif
    +
    +   dlist->currentblock = dlist->firstblock;
    +   dlist->resumeblock  = dlist->firstblock;
    +
    +   if(NULL != dlist->vidmem_blocks)
    +   {
    +      dlist->vidmem_blocks->currentblock   = dlist->vidmem_blocks->blocks;
    +      dlist->vidmem_blocks->currentaddress = dlist->vidmem_blocks->blocks[0];
    +      dlist->vidmem_blocks->blocksleft     = dlist->vidmem_blocks->num_blocks;
    +      dlist->vidmem_blocks->slicesleft     = dlist->vidmem_blocks->num_slices;
    +   }
    +
    +   dlist->position  = dlist->firstblock->block;
    +   dlist->blocksize = dlist->firstblock->quantity;
    +   dlist->tagindex  = 0;
    +   dlist->count     = 0;
    +
    +}
    +
    +/*--------------------------------------------------------------------------
    + * prepare display list for reading.
    + * terminates the list with an FF command, applies padding and shrinks dlist
    + * if possible
    + * */
    +void* d2_preparedlist_read_intern( const d2_device *handle, d2_dlist *dlist, d2_s32 reset )
    +{
    +   void *next_dlist_start = 0;
    +
    +   /* copy scratch buffer to dlist (dlist cache flush) */
    +   d2_scratch2dlist_intern( dlist->device );
    +
    +   /* mark end of scene in dlist */
    +   d2_insertdlistspecial_intern( dlist, 3 );
    +
    +   if (D2_DEV(handle)->lowlocalmem_mode == NULL)
    +   {
    +      /* update shrinkcount */
    +      if(NULL != dlist->currentblock->next)
    +      {
    +         ++dlist->shrinkcount;  /* list is too long */
    +      }
    +      else
    +      {
    +         dlist->shrinkcount = 0; /* at end of list */
    +      }
    +
    +      if (dlist->shrinkcount == D2_DLISTSHRINKDELAY)
    +      {
    +         /* go to penultimate element in list */
    +         d2_dlist_block *blk = dlist->currentblock;
    +         while(NULL != blk->next->next)
    +         {
    +            blk = blk->next;
    +         }
    +
    +         /* free the last element */
    +         d2_free_dlistblock_intern(dlist->device, blk->next);
    +         blk->next = NULL;
    +         dlist->shrinkcount = 0;
    +      }
    +   }
    +
    +   /* copy resp. flush dlist to vidmem */
    +   if(NULL != dlist->vidmem_blocks)
    +   {
    +      /* low_local_memory_mode */
    +      if(0 != reset)
    +      {
    +         (void)d1_copytovidmem( d2_level1interface(dlist->device), 
    +                                dlist->vidmem_blocks->currentaddress,
    +                                dlist->currentblock->block, 
    +                                (d2_u32)(sizeof(d2_dlist_entry) * (dlist->currentblock->quantity - dlist->blocksize)), 
    +                                0
    +                                );
    +      } 
    +      /* if !reset then d1_copytovidmem is done below by d2_nextdlistblock_intern */
    +   }
    +   else if(0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_separated))
    +   {
    +      d2_copydlist_vidmem_intern( dlist );
    +   }
    +   else if (0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_mapped))
    +   {
    +      d2_mapdlist_vidmem_intern( dlist );
    +   }
    +   else
    +   {
    +      d2_cacheflushdlist_intern( dlist );
    +   }
    +
    +   if(0 != reset)
    +   {
    +      /* reset list */
    +      d2_resetdlist_intern( dlist );
    +      dlist->busy = 0;
    +   }
    +   else
    +   { /* goto next dlist block and get the current_dlist_start */
    +
    +      /* mark dlist block to be full, so d2_nextdlistblock_intern will move to next block in any case */
    +      dlist->blocksize = 0;
    +
    +      /* resume adding commands in a new block */
    +      d2_nextdlistblock_intern( dlist );
    +      dlist->resumeblock = dlist->currentblock;
    +
    +      if(NULL != dlist->vidmem_blocks)
    +      {
    +         /* low_local_memory_mode */
    +         next_dlist_start =  dlist->vidmem_blocks->currentaddress;
    +      }
    +      else if( (0 != ((D2_DEV(handle)->hwmemarchitecture) & (d1_ma_separated | d1_ma_mapped))) && (NULL != dlist->currentblock->vidmem) )
    +      {
    +         next_dlist_start = dlist->currentblock->vidmem;
    +      }
    +      else
    +      {
    +         next_dlist_start = dlist->position;
    +      }
    +   }
    +
    +   return next_dlist_start;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * simulated execution of a single display list page. optimized for speed
    + * returns end of list argument.
    + * note list MUST be terminated correctly
    + * */
    +d2_u32 d2_executedlist_intern( const d2_device *handle, d2_dlist_entry *block )
    +{
    +   d2_u32 adrmask;
    +   d2_u32 argument = 0;
    +   d1_device *id = D2_DEV(handle)->hwid;
    +   d2_u32 a1,a2,a3,a4;
    +
    +   for (;;)
    +   {
    +      d2_s32 bEOL = 0;
    +
    +      adrmask = block->address.mask;
    +      if(0 != (adrmask & 0x80808080u))
    +      {
    +         /* contains special indices */
    +         if(0x80808080u == adrmask)
    +         {
    +            /* completely empty -> skip */
    +            block = (d2_dlist_entry*) ((d2_s32*)block + 1);
    +         }
    +         else if(0 != (adrmask & 0x00008000u))
    +         {
    +            /* index1 only */
    +            if ((adrmask & 0xffu) == D2_DLISTSTART)
    +            {
    +               /* catch special case of display list jump */
    +               return argument;
    +            } 
    +            else 
    +            {
    +               /* normal rewrite */
    +               a1 = adrmask & 0xffu;
    +               d2hw_set(id, a1, block->value[0]);
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +               if(a1 == D2_ORIGIN)
    +               {
    +                  d2hw_wait(id);
    +               }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +            }
    +            block = (d2_dlist_entry*) ((d2_s32*)block + 2);
    +         }
    +         else if (0 != (adrmask & 0x00800000u))
    +         {
    +            /* index1&2 only */
    +            if( 0xffu == (adrmask & 0xffu) )
    +            {
    +               /* end of list word */
    +               argument = (adrmask >> 8) & 0xffu;
    +               if(2 == argument)
    +               {
    +                  /* just a flush. keep on reading */
    +                  block = (d2_dlist_entry*) ((d2_s32*)block + 1);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +                  d2hw_wait(id);
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +                  bEOL = 1;
    +               } 
    +               else 
    +               {
    +                  /* terminate */
    +                  return argument;
    +               }
    +            }
    +
    +            if(0 == bEOL)
    +            {
    +               a1 = adrmask & 0xffu;
    +               a2 = (adrmask >> 8) & 0xffu;
    +
    +               d2hw_set(id, a1, block->value[0]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +               if(D2_ORIGIN == a1)
    +               {
    +                  d2hw_wait(id);
    +               }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +               d2hw_set(id, a2, block->value[1]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +               if(D2_ORIGIN == a2)
    +               {
    +                  d2hw_wait(id);
    +               }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +               block = (d2_dlist_entry*) ((d2_s32*)block + 3);
    +            }
    +         }
    +         else if (0 != (adrmask & 0x80000000u))
    +         {
    +            /* index1,2,3 only */
    +            a1 = adrmask & 0xffu;
    +            a2 = (adrmask >> 8) & 0xffu;
    +            a3 = (adrmask >> 16) & 0xffu;
    +
    +            d2hw_set(id, a1, block->value[0]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +            if(D2_ORIGIN == a1)
    +            {
    +               d2hw_wait(id);
    +            }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +            d2hw_set(id, a2, block->value[1]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +            if(D2_ORIGIN == a2)
    +            {
    +               d2hw_wait(id);
    +            }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +            d2hw_set(id, a3, block->value[2]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +            if(D2_ORIGIN == a3)
    +            {
    +               d2hw_wait(id);
    +            }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +            block = (d2_dlist_entry*) ((d2_s32*)block + 4);
    +         }
    +         else
    +         {
    +            /* end of list word */
    +            if((adrmask & 0xffu) == 0xffu)
    +            {
    +               /* get eol argument */
    +               argument = (adrmask >> 8) & 0xffu;
    +               if ((2 == argument) || (4 == argument))
    +               {
    +                  /* just a flush. keep on reading */
    +                  block = (d2_dlist_entry*) ((d2_s32*)block + 1);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +                  d2hw_wait(id);
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +               } 
    +               else 
    +               {
    +                  /* terminate */
    +                  return argument;
    +               }
    +            } 
    +            else 
    +            {
    +               /* invalid case, no index used */
    +               block = (d2_dlist_entry*) ((d2_s32*)block + 1);
    +            }
    +         }
    +      } 
    +      else 
    +      {
    +         /* contains simple indices only */
    +         a1 = adrmask & 0xffu;
    +         a2 = (adrmask >> 8) & 0xffu;
    +         a3 = (adrmask >> 16) & 0xffu;
    +         a4 = adrmask >> 24;
    +
    +         d2hw_set(id, a1, block->value[0]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +         if(D2_ORIGIN == a1)
    +         {
    +            d2hw_wait(id);
    +         }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +         d2hw_set(id, a2, block->value[1]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +         if(D2_ORIGIN == a2)
    +         {
    +            d2hw_wait(id);
    +         }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +         d2hw_set(id, a3, block->value[2]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +         if(D2_ORIGIN == a3)
    +         {
    +            d2hw_wait(id);
    +         }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +         d2hw_set(id, a4, block->value[3]);
    +
    +#ifdef D2_EXECUTE_DLIST_NEEDWAIT
    +         if(D2_ORIGIN == a4)
    +         {
    +            d2hw_wait(id);
    +         }
    +#endif /* D2_EXECUTE_DLIST_NEEDWAIT */
    +
    +         /* next entry */
    +         block++;
    +      }
    +   }
    +
    +   /* never reached */
    +}
    +
    +/*-------------------------------------------------------------------------
    + * Add a dave flush command into current dlist and wait */
    +d2_s32 d2_insertwaitpipedlist_intern( d2_device *handle )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* copy scratch buffer to dlist (dlist cache flush) */
    +   d2_scratch2dlist_intern( handle );
    +   /* insert 0x04 wait into dlist to wait for pipeline flush */
    +   d2_insertdlistspecial_intern( &D2_DEV(handle)->selectedbuffer->baselist, 4 );
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*-------------------------------------------------------------------------
    + * Add a dave flush command into current dlist wait */
    +d2_s32 d2_insertwaitfulldlist_intern( d2_device *handle )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* copy scratch buffer to dlist (dlist cache flush) */
    +   d2_scratch2dlist_intern( handle );
    +   /* insert 0x02 wait into dlist to wait for pipeline flush and cache write complete */
    +   d2_insertdlistspecial_intern( &D2_DEV(handle)->selectedbuffer->baselist, 2 );
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Copy scratch buffer into display list (dlist cache flush) */
    +void d2_scratch2dlist_intern( d2_device *handle )
    +{
    +   d2_devicedata *dev = D2_DEV(handle);
    +   d2_dlist *dlist    = &D2_DEV(handle)->selectedbuffer->baselist;
    +   d2_dlist_scratch_entry *scratchEntry = dev->dlscratch_base;
    +   d2_dlist_entry *pos;
    +   d2_u32 i, cnt = (d2_u32) (dev->dlscratch_pos - dev->dlscratch_base);
    +   d2_u32 tagIndex;
    +
    +
    +#ifdef D2_USEREGCACHE
    +   d2_cacheddata *cachedData = & ((d2_devicedata *) dlist->device)->cache;
    +   d2_s32  *cache_data  = cachedData->data;
    +   d2_s8   *cache_valid = cachedData->valid;
    +
    +   if(0 == (D2_DEV(handle)->flags & d2_df_no_registercaching))
    +   {
    +      /* walk scratchbuffer
    +       */
    +      tagIndex = dlist->tagindex;
    +      pos = dlist->position;
    +
    +      for(i=0; (i < cnt) && (0 ==  D2_DEV(dlist->device)->delayed_errorcode) ; i++)
    +      {
    +         d2_s32 bSkip = 0;
    +         d2_u32 regIdx = scratchEntry->reg;
    +         d2_s32 val = scratchEntry->value;
    +
    +         /* next */
    +         scratchEntry++;
    +
    +#ifdef _DEBUG
    +         if (regIdx > D2_QUANTITY)
    +         {
    +            bSkip = 1;
    +         }
    +#endif
    +
    +#ifdef _DEBUG
    +         if(0 == bSkip)
    +#endif /* _DEBUG */
    +         {
    +            if(0 != d2_cacheableregs[regIdx])
    +            {
    +               if( (0 != cache_valid[regIdx]) && ( cache_data[regIdx] == val ) ) 
    +               {
    +                  bSkip = 1;
    +               }
    +               else
    +               {
    +                  cache_valid[regIdx] = 1;
    +                  cache_data[regIdx]  = val;
    +               }
    +            }
    +
    +            if(0 == bSkip)
    +            {
    +               /* store in displaylist */
    +               pos->address.array[tagIndex] = (d2_u8) regIdx;
    +               pos->value[tagIndex] = val;
    +
    +               /* next tagindex */
    +               tagIndex = (tagIndex + 1) & 3;
    +
    +               dlist->count++;
    +
    +               /* finish entry */
    +               if(0 == tagIndex)
    +               {
    +                  dlist->position++;
    +                  dlist->blocksize--;
    +                  if(dlist->blocksize <= 1)
    +                  {
    +                     dlist->tagindex = tagIndex;
    +                     d2_nextdlistblock_intern( dlist );
    +                  }
    +                  pos = dlist->position;
    +               }
    +
    +            } /* 0 == bSkip */
    +
    +         } /* 0 == bSkip */
    +
    +      } /* for i=0..cnt */
    +
    +      dlist->tagindex = tagIndex;
    +      cnt = 0;
    +   } 
    +   else 
    +#endif
    +   {
    +      dlist->count += cnt;
    +
    +      /* copy entries until start of a new dlist entry block */
    +      tagIndex = dlist->tagindex;
    +      if(0 == D2_DEV( dlist->device)->delayed_errorcode)
    +      {
    +         if(0 != tagIndex)
    +         {
    +            pos = dlist->position;
    +
    +            while( (cnt > 0) && (0 != tagIndex) )
    +            {
    +               /* read entry */
    +               d2_u32 regIdx = scratchEntry->reg;
    +               d2_s32 scrValue = scratchEntry->value;
    +
    +               /* next entry */
    +               scratchEntry++;
    +               cnt--;
    +
    +               /* store in displaylist */
    +               pos->address.array[tagIndex]   = (d2_u8) regIdx;
    +               pos->value[tagIndex] = scrValue;
    +
    +               /* next tagindex */
    +               tagIndex = (tagIndex + 1u) & 3u;
    +            }
    +
    +            /* finish entry */
    +            if(0 == tagIndex)
    +            {
    +               dlist->tagindex = tagIndex;
    +               dlist->position++;
    +               dlist->blocksize--;
    +               if(dlist->blocksize <= 1) 
    +               {
    +                  d2_nextdlistblock_intern( dlist );
    +               }
    +            }
    +         }
    +
    +         if(0 == tagIndex)
    +         {
    +            /* walk rest of scratchbuffer in multiples of 4
    +             * tagindex must be 0 at this point (only exception is that cnt is already 0) */
    +            for(i=0; (i < (cnt / 4)) && (0 == D2_DEV(dlist->device)->delayed_errorcode); i++)
    +            {
    +               pos = dlist->position;
    +
    +               pos->address.array[0] = (d2_u8) scratchEntry[0].reg;
    +               pos->address.array[1] = (d2_u8) scratchEntry[1].reg;
    +               pos->address.array[2] = (d2_u8) scratchEntry[2].reg;
    +               pos->address.array[3] = (d2_u8) scratchEntry[3].reg;
    +
    +               pos->value[0] = scratchEntry[0].value;
    +               pos->value[1] = scratchEntry[1].value;
    +               pos->value[2] = scratchEntry[2].value;
    +               pos->value[3] = scratchEntry[3].value;
    +
    +               /* finish entry */
    +               dlist->position++;
    +               dlist->blocksize--;
    +               if ( dlist->blocksize <= 1 ) 
    +               {
    +                  d2_nextdlistblock_intern( dlist );
    +               }
    +               /* next scratch entry */
    +               scratchEntry += 4;
    +            }
    +
    +
    +            /* copy remaining entries */
    +            cnt &= 3;
    +            for(i=0; (i < cnt) && (0 == D2_DEV( dlist->device)->delayed_errorcode); i++)
    +            {
    +               d2_u32 regIdx = scratchEntry->reg;
    +               d2_s32 scrValue = scratchEntry->value;
    +
    +               /* next */
    +               scratchEntry++;
    +
    +               tagIndex = dlist->tagindex;
    +               pos = dlist->position;
    +
    +               /* store in displaylist */
    +               pos->address.array[tagIndex] = (d2_u8) regIdx;
    +               pos->value[tagIndex] = scrValue;
    +
    +               /* next tagindex */
    +               tagIndex = (tagIndex + 1u) & 3u;
    +               dlist->tagindex = tagIndex;
    +            }
    +         }
    +      }
    +   }
    +   /* free scratch memory */
    +   dev->dlscratch_pos = dev->dlscratch_base;
    +   dev->dlscratch_cnt = D2_DLISTSCRATCH;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Append a prepared display list to the display list. */
    +static d2_s32 d2_dlist2dlist_intern( d2_device *handle, d2_dlist *dlist, void *address, d2_s32 size )
    +{
    +   d2_dlist_entry * pos         = dlist->position;
    +   d2_u32           tagIndex    = dlist->tagindex;
    +   d2_s32           cnt         = (size / (d2_s32)sizeof(d2_s32));
    +   d2_s32           cnt_rem     = (cnt % 5);
    +   d2_u32 *         dlist_word  = (d2_u32*)address;
    +   d2_s32           i;
    +
    +   if(0 != tagIndex)
    +   {
    +      /* fill dlist entry with 0x80 indices */
    +      while(0 != tagIndex)
    +      {
    +         /* store in displaylist */
    +         pos->address.array[tagIndex]   = (d2_u8) 0x80u;
    +         pos->value[tagIndex] = (d2_s32)0x80808080u; /* pad with NULL command */
    +         /* next tagindex */
    +         tagIndex = (tagIndex + 1u) & 3u;
    +      }
    +      dlist->tagindex = 0;
    +      /* finish entry */
    +      dlist->position++;
    +      dlist->blocksize--;
    +      if(dlist->blocksize <= 1) 
    +      {
    +         d2_nextdlistblock_intern( dlist );
    +      }
    +   }
    +
    +   /* copy dlist with size of dlist entries */
    +   while(cnt >= 5)
    +   {
    +      d2_u32 *dl = &dlist->position->address.mask;
    +      dl[0] = dlist_word[0];
    +      dl[1] = dlist_word[1];
    +      dl[2] = dlist_word[2];
    +      dl[3] = dlist_word[3];
    +      dl[4] = dlist_word[4];
    +      dl += 5;
    +      dlist_word += 5;
    +
    +      /* finish entry */
    +      dlist->position++;
    +      dlist->blocksize--;
    +      if(dlist->blocksize <= 1)
    +      {
    +         d2_nextdlistblock_intern( dlist );
    +      }
    +      cnt -= 5;
    +   }
    +
    +   /* pad dlist entry */
    +   if(0 != cnt_rem)
    +   {
    +      d2_u32 *dl = &dlist->position->address.mask;
    +
    +      /* copy remaining words */
    +      cnt--;
    +      if(0 != cnt)
    +      {
    +         do
    +         {
    +            *dl = *dlist_word;
    +            dl++;
    +            dlist_word++;
    +            cnt--;
    +         }
    +         while(0 != cnt);
    +      }
    +
    +      /* pad with 0x80808080 */
    +      for(cnt_rem = (5 - cnt_rem); cnt_rem > 0; cnt_rem--)
    +      {
    +         *dl = 0x80808080u;
    +         dl++;
    +      }
    +   }
    +
    +   /* clear register cache */
    +#ifdef D2_USEREGCACHE
    +   for(i=0; i<D2_QUANTITY; i++)
    +   {
    +      D2_DEV(handle)->cache.data[i]  = 0;
    +      D2_DEV(handle)->cache.valid[i] = 0;
    +   }
    +#endif
    +
    +   return 0;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Copy a display list to video memory. */
    +void d2_copydlist_vidmem_intern( const d2_dlist *dlist )
    +{
    +   d1_device *id = D2_DEV(dlist->device)->hwid;
    +   d2_dlist_block *blk  = dlist->resumeblock;
    +   d2_dlist_block *last = dlist->currentblock;
    +
    +   if(0 != (D2_DEV(dlist->device)->flags & d2_df_no_dlist))
    +   {
    +      return;
    +   }
    +
    +   /* copy all but the last block */
    +   while(blk != last)
    +   {
    +      /* replace jump address with new address inside vidmem */
    +      if((NULL != blk->next) && (NULL != blk->jump))
    +      {
    +         /* replace jump address */
    +         *(blk->jump) = (d2_s32)(blk->next->vidmem);
    +      }
    +
    +      /* write block to video memory */
    +      (void)d1_copytovidmem( id, blk->vidmem, blk->block, sizeof(d2_dlist_entry) * blk->quantity, 0 );
    +
    +      /* next block */
    +      blk = blk->next;
    +   }
    +
    +   /* copy last block (not whole block needs to be copied) */
    +   (void)d1_copytovidmem( id, blk->vidmem, blk->block, sizeof(d2_dlist_entry) * (blk->quantity - dlist->blocksize), 0 );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * Flush a display list out of data cache. */
    +void d2_cacheflushdlist_intern( const d2_dlist *dlist )
    +{
    +   d1_device *id = D2_DEV(dlist->device)->hwid;
    +   d2_dlist_block *blk  = dlist->resumeblock;
    +   d2_dlist_block *last = dlist->currentblock;
    +
    +   if(0 != (D2_DEV(dlist->device)->flags & d2_df_no_dlist))
    +   {
    +      return;
    +   }
    +
    +   /* flush all but the first block */
    +   while(blk != last)
    +   {
    +      /* replace jump address with new address inside vidmem */
    +      (void)d1_cacheblockflush(id, d1_mem_dlist, blk->block, sizeof(d2_dlist_entry) * blk->quantity );
    +      blk = blk->next;
    +   }
    +
    +   /* flush last block (not whole block needs to be flushed) */
    +   (void)d1_cacheblockflush(id, d1_mem_dlist, blk->block, sizeof(d2_dlist_entry) * (blk->quantity - dlist->blocksize) );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * Map a displaylist to vidmem. */
    +void d2_mapdlist_vidmem_intern( const d2_dlist *dlist )
    +{
    +   d1_device *id = D2_DEV(dlist->device)->hwid;
    +   d2_dlist_block *blk  = dlist->resumeblock;
    +   d2_dlist_block *last = dlist->currentblock;
    +
    +   if(0 != (D2_DEV(dlist->device)->flags & d2_df_no_dlist))
    +   {
    +      return;
    +   }
    +
    +   /* flush all but the first block */
    +   while(blk != last)
    +   {
    +      if( (NULL != blk->next) && (NULL != blk->jump) )
    +      {
    +         /* replace jump address (vidmem has been assigned by d2_alloc_dlistblock_intern) */
    +         *(blk->jump) = (d2_s32)(blk->next->vidmem);
    +      }
    +
    +      /* replace jump address with new address inside vidmem */
    +      (void)d1_cacheblockflush(id, d1_mem_dlist, blk->vidmem, sizeof(d2_dlist_entry) * blk->quantity );
    +      blk = blk->next;
    +   }
    +
    +   /* flush last block (not whole block needs to be flushed) */
    +   (void)d1_cacheblockflush(id, d1_mem_dlist, blk->vidmem, sizeof(d2_dlist_entry) * (blk->quantity - dlist->blocksize) );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Clear the list of dlist start addresses. */
    +void d2_clear_dlistlist_intern( const d2_device *handle, d2_dlist *dlist )
    +{
    +   d2_s32 i;
    +   d2_s32 *dlist_list = (d2_s32 *)dlist->dlist_addresses;
    +   (void)handle; /* PRQA S 3112 */ /*$Misra: #COMPILER_WARNING $*/
    +
    +   for (i=0; i<dlist->dlist_addresses_max; i++)
    +   {
    +      dlist_list[i] = 0;
    +   }
    +   dlist->dlist_addresses_cur = 0;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Add an address to the list of dlist start addresses. */
    +d2_s32* d2_add_dlistlist_intern( const d2_device *handle, d2_dlist *dlist, const void *dlistaddress )
    +{
    +   d2_s32 i, pos;
    +   d2_s32 *dlist_list = (d2_s32 *)dlist->dlist_addresses;
    +   (void)handle; /* PRQA S 3112 */ /*$Misra: #COMPILER_WARNING $*/
    +
    +   pos = dlist->dlist_addresses_cur;
    +   if(pos >= (dlist->dlist_addresses_max - 1)) /* leave last entry 0 */
    +   {
    +      /* grow dlist list */
    +      dlist->dlist_addresses_max = (d2_s16)(dlist->dlist_addresses_max+DLIST_ADRESSES_NUMBER);
    +      dlist->dlist_addresses      = d2_reallocmem_p( (d2_u32)dlist->dlist_addresses_max * sizeof(d2_s32*), dlist->dlist_addresses, 1 );
    +      dlist_list = (d2_s32 *)dlist->dlist_addresses;
    +
    +      /* clear new part */
    +      for(i=pos; i<dlist->dlist_addresses_max; i++)
    +      {
    +         dlist_list[i] = 0;
    +      }
    +   }
    +
    +   dlist_list[pos] = (d2_s32)dlistaddress;
    +   dlist->dlist_addresses_cur = (d2_s16) (pos + 1);
    +
    +   return &dlist_list[pos];
    +}
    +
    +/*------------------------------------------------------------------------
    + * function: d2_executedlist
    + *
    + * Execute an already prepared display list. 
    + * A display list (Dlist) can be created e.g. by <d2_dumprenderbuffer>.  
    + *
    + * Basically the address will be sent to D/AVE and will be executed immediately.
    + * So the dlist address must be accessible by the GPU and 
    + * it is in the application's responsibility to prepare the Dlist
    + * correctly.
    + * 
    + * d2_executedlist must not be called while D/AVE is busy rendering
    + * (see: <Render Buffers>). 
    + *
    + * Note: 
    + * This has no influence on the render buffer mechanism. The
    + * driver will manage cooperation of render buffers and Dlists.
    + *
    + * Note: 
    + * In case d2_opendevice was called with d2_df_no_dlist address must 
    + * be accessible by the CPU.
    + *
    + * parameters:
    + *   handle  - device pointer (see: <d2_opendevice>)
    + *   address - Address of the Dlist (must be accessible by the GPU)
    + *   flags   - reserved (set to 0)
    + *
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see <Errorcodes> for details
    + * */
    +d2_s32 d2_executedlist( d2_device *handle, const void *address, d2_u32 flags )
    +{
    +   d2_devicedata *dev = D2_DEV(handle);
    +   d2_dlist  dlist;
    +   d2_s32 *dlist_list;
    +   (void) flags; /* PRQA S 3112 */ /*$Misra: #COMPILER_WARNING $*/
    +
    +   D2_VALIDATE( handle,  D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( address, D2_INVALIDBUFFER ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* put dlist_start to special address list */
    +   dlist.dlist_addresses     = dev->dlist_list_single;
    +   dlist.dlist_addresses_max = 2;
    +   dlist.dlist_addresses_cur = 1;
    +
    +   dlist_list = (d2_s32 *)dlist.dlist_addresses;
    +   dlist_list[0] = (d2_s32)address;
    +   dlist_list[1] = 0;
    +
    +   /* start dlist execution */
    +   d2hw_start(handle, &dlist, 1);
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*------------------------------------------------------------------------
    + * function: d2_adddlist
    + *
    + * Add an already prepared display list to the current render buffer.
    + * A display list (Dlist) can be created e.g. by <d2_dumprenderbuffer>.  
    + *
    + * Depending on the flags, the Dlist will be added to the current
    + * render buffer by copying its content or by adding 'call' operations
    + * to the current render buffer.
    + *
    + * If a 'postprocess' rendermode is active the layers are merged before
    + * the Dlist is added (see: <d2_selectrendermode>).
    + *
    + * Note: 
    + * If d2_al_no_copy is selected, the GPU must be able to select the
    + * specified address, in case if d2_al_copy the CPU must be able to 
    + * access the Dlist.
    + *
    + * Note: 
    + * For the mode d2_al_no_copy the low level driver must support the handling
    + * of lists of Dlist start addresses (see: <d2_level1interface> and 
    + * low level device <D1 Display list handling at ../../../driver_l1/files/doc/d1_dlistindirect-txt.html>).
    + * 
    + * If this handling is not supported then no Dlists can be added in this mode.
    + *
    + * parameters:
    + *   handle  - device pointer (see: <d2_opendevice>)
    + *   address - Address of the Dlist 
    + *            (in case of d2_al_no_copy must be accessible by the GPU 
    + *             in case of d2_al_no_copy must be accessible by CPU)
    + *   size    - size of Dlist
    + *   flags   - d2_al_copy, d2_al_no_copy
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see <Errorcodes> for details
    + *
    + * flags:
    + *   d2_al_default - default behavior d2_al_copy.
    + *   d2_al_copy    - content will be copied.
    + *   d2_al_no_copy - call to the Dlist will be added.
    + *
    + * see also:
    + *   <d2_dumprenderbuffer>, <d2_getrenderbuffersize>, <d2_relocateframe>
    + * */
    +d2_s32 d2_adddlist( d2_device *handle, void *address, d2_s32 size, d2_u32 flags )
    +{  
    +   d2_devicedata *dev   = D2_DEV(handle);
    +   d2_dlist      *dlist;
    +   void          *current_dlist_start;
    +
    +   D2_VALIDATE( handle,  D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( address, D2_INVALIDBUFFER ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( size,    D2_VALUETOOSMALL ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   dlist = &dev->selectedbuffer->baselist;
    +
    +   /* reset postprocessing mode if still active */
    +   if(d2_rm_postprocess == dev->rendermode)
    +   {
    +      (void)d2_selectrendermode( handle, d2_rm_solid );
    +   }
    +
    +   /* merge in layers if they contain data */
    +   d2_layer2dlist_intern( handle );
    +
    +   if(d2_al_copy == flags)
    +   {
    +      d2_scratch2dlist_intern(handle);
    +
    +      /* append our dlist to the dlist*/
    +      (void)d2_dlist2dlist_intern(handle, dlist, address, size);
    +   }
    +   else
    +   {
    +      if( (0 != dev->dlist_indirect_supported) && (0 == (dev->flags & d2_df_no_dlist)) ) 
    +      {
    +         current_dlist_start = d2_preparedlist_read_intern( handle, dlist, 0 );
    +
    +         /* append dlist_start to address list*/
    +         (void)d2_add_dlistlist_intern(handle, dlist, address);
    +
    +         /* append current dlist position to address list */
    +         (void)d2_add_dlistlist_intern(handle, dlist, current_dlist_start);
    +      }
    +   }
    +
    +   D2_RETOK(handle);
    +}
    diff --git a/src/drivers/dave2d/src/dave_driver.c b/src/drivers/dave2d/src/dave_driver.c
    new file mode 100644
    index 000000000..7891c15c4
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_driver.c
    @@ -0,0 +1,1337 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_driver.c (%version: 51 %)
    + *          created Mon Jan 10 13:38:34 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Mar 12 15:29:14 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + *  2005-12-22 CSe  removed transfermode field, added flags field in d2_opendevice()
    + *  2006-02-16 CSe  added performance counter support + cache burstmodes
    + *  2006-02-28 CSe  removed d2_df_dlist_big_endian which is now handled by hw
    + *  2006-04-12 CSe  completed documentation for d2_opendevice
    + *  2006-04-13 CSe  extended hwrevision for performance counter feature bit
    + *  2006-05-10 CSe  moved initialization of dlists from d2_opendevice to d2_inithw
    + *  2006-10-30 CSe  removed waitdlist flag
    + *  2006-11-07 CSe  added dlist_buffer to device struct for 'd2_df_low_localmem' mode
    + *  2007-03-01 MGe  added check of null values after creation of renderbuffers
    + *  2007-03-12 CSe  fixed error in d2_lowlocalmemmode
    + *  2007-05-23 MGe  added null checks in d2_inithw; initalize delayed_errorcode in context
    + *  2007-08-30 ASc  replaced clib functions, removed tabs, added description for
    + *                  d2_getrendermode, changed C++ to C comments, changed g_versionid
    + *  2007-09-10 ASc  smaller updates of d2_lowlocalmemmode and d2_inithw
    + *  2008-01-15 ASc  add error checking for d2_geterror and d2_geterrorstr
    + *  2010-07-08 MRe  fixed support for register caching defined by D2_USEREGCACHE
    + *  2010-07-08 MRe  new device flag d2_df_no_registercaching
    + *  2011-03-10 MRe  fixed delayed error handling in d2_geterror
    + *  2011-03-11 MRe  improved/removed context backup for blit
    + *  2012-09-25 BSp  MISRA cleanup
    + *  2013-06-25 MRe  changed check of dlistblocks in d2_lowlocalmemmode to >= 1
    + *  2020-02-05 MRe  added d2_inithwburstlengthlimit
    + *-------------------------------------------------------------------------- */
    + 
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Basic Functions
    + * Driver device management and hardware initialization / shutdown.
    + *
    + *-------------------------------------------------------------------------- */
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_memory.h"
    +#include "dave_render.h"
    +#include "dave_dlist.h"
    +
    +/*-------------------------------------------------------------------------- */
    +static d2_devicedata *g_devicechain = NULL;
    +
    +#ifdef _DEBUG
    +#define _DEBUG_STR " _DEBUG "
    +#else
    +#define _DEBUG_STR ""
    +#endif 
    +
    +/*---------------------------------------------------------------------------
    + * List of hardware registers that can be cached for redundancy elimination
    + * */
    +#ifdef D2_USEREGCACHE
    +const d2_u8 d2_cacheableregs[D2_QUANTITY] ={
    +   0,    /*D2_CONTROL      0 */
    +   1,    /*D2_CONTROL2     1 */
    +   0,    /*D2_CONTROL3     2 */
    +   0,    /*                3 */
    +   0,    /*D2_L1START      4 */
    +   0,    /*D2_L2START      5 */
    +   0,    /*D2_L3START      6 */
    +   0,    /*D2_L4START      7 */
    +   0,    /*D2_L5START      8 */
    +   0,    /*D2_L6START      9 */
    +   1,    /*D2_L1XADD       10 */
    +   1,    /*D2_L2XADD       11 */
    +   1,    /*D2_L3XADD       12 */
    +   1,    /*D2_L4XADD       13 */
    +   1,    /*D2_L5XADD       14 */
    +   1,    /*D2_L6XADD       15 */
    +   0,    /*D2_L1YADD       16 */
    +   1,    /*D2_L2YADD       17 */
    +   0,    /*D2_L3YADD       18 */
    +   1,    /*D2_L4YADD       19 */
    +   0,    /*D2_L5YADD       20 */
    +   1,    /*D2_L6YADD       21 */
    +   1,    /*D2_L1BAND       22 */
    +   1,    /*D2_L2BAND       23 */
    +   0,    /*                24 */
    +   1,    /*D2_COLOR1       25 */
    +   1,    /*D2_COLOR2       26 */
    +   0,    /*                27 */
    +   0,    /*                28 */
    +   1,    /*D2_PATTERN      29 */
    +   1,    /*D2_SIZE         30 */
    +   1,    /*D2_PITCH        31 */
    +   0,    /*D2_ORIGIN       32 */
    +   0,    /*                33 */
    +   0,    /*                34 */
    +   0,    /*                35 */
    +   0,    /*D2_LUSTART      36 */
    +   1,    /*D2_LUXADD       37 */
    +   1,    /*D2_LUYADD       38 */
    +   0,    /*D2_LVSTARTI     39 */
    +   0,    /*D2_LVSTARTF     40 */
    +   1,    /*D2_LVXADDI      41 */
    +   1,    /*D2_LVYADDI      42 */
    +   1,    /*D2_LVYXADDF     43 */
    +   0,    /*                44 */
    +   1,    /*D2_TEXPITCH     45 */
    +   1,    /*D2_TEXMASK      46 */
    +   1,    /*D2_TEXORIGIN    47 */
    +   0,    /*D2_IRQCTL       48 */
    +   0,    /*D2_CACHECTL     49 */
    +   0,    /*D2_DLISTSTART   50 */
    +   0,    /*D2_PERFCOUNT1   51 */
    +   0,    /*D2_PERFCOUNT2   52 */
    +   0,    /*D2_PERFTRIGGER  53 */
    +   0,    /*D2_TEXCLUT      54 */
    +   0,    /*D2_TEXCLUT_ADDR 55 */
    +   0,    /*D2_TEXCLUT_DATA 56 */
    +   1,    /*D2_TEXCLUT_OFFSET 57 */
    +   1     /*D2_COLKEY       58 */
    +};
    +#endif
    +
    +
    +/*--------------------------------------------------------------------------
    + * Group: Static functions
    + * */
    +
    +static d2_contextdata_backup * d2_newbackupcontext_intern( d2_device *handle, d2_u32 flags );
    +static void d2_strcpy(d2_char *dst, const d2_char *src, d2_u32 dst_size);
    +static void d2_strcat(d2_char *dst, const d2_char *src, d2_u32 dst_size);
    +#ifdef NEED_D2_INTTOSTR
    +static void d2_inttostr(d2_char *a_dst, d2_u32 a_number, d2_u32 a_size);
    +#endif /* NEED_D2_INTTOSTR */
    +static void d2_hextostr(d2_char *a_dst, d2_u32 a_number, d2_u32 a_size);
    +
    +/*--------------------------------------------------------------------------
    + * Group: Device management
    + * */
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getversionstring
    + * Query versionID string (device independent)
    + *
    + * returns:
    + *  human readable driver version as a string.
    + *
    + * see also:
    + *  <d2_getversion>
    + * */
    +const d2_char * d2_getversionstring( void )
    +{
    +   static const d2_char g_versionid[] ="@(#)DAVE driver " D2_VERSION_STRING D2_VERSION_STATE " - " _DEBUG_STR " - " __DATE__ " " __TIME__ ;
    +
    +   return g_versionid;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getversion
    + * Query versionID (device independent)
    + *
    + * returns:
    + *  driver revision as a single 32bit integer 
    + * 
    + * bits 31..24 - branch number
    + * bits 23..16 - major version number
    + * bits 15..0  - minor version number
    + *
    + * see also:
    + *  <d2_getversionstring>
    + * */
    +d2_s32 d2_getversion( void )
    +{
    +   return D2_VERSION;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * d2_newbackupcontext_intern
    + * Create a backup area for context data that is used by blit.
    + * */
    +static d2_contextdata_backup * d2_newbackupcontext_intern( d2_device *handle, d2_u32 flags )
    +{
    +   d2_contextdata_backup *ctx;
    +
    +   if(0 != (flags & d2_df_no_blitctxbackup))
    +   {
    +      ctx = 0;
    +   }
    +   else
    +   {
    +      ctx = (d2_contextdata_backup *) d2_getmem_p( sizeof(d2_contextdata_backup) );
    +   }
    +
    +   (void)D2_SETOK(handle);
    +   return ctx;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_opendevice
    + * Create a new device handle.
    + *
    + * A device is the basic software object. It contains references to objects
    + * that the drawing engine requires, (e.g.: displaylists). 
    + * All 2D drawing functions require such a device pointer as first parameter. 
    + *
    + * A device on its own is useless, unless bound to a physical hardware (i.e.: Drawing Engine).
    + * The binding is done by the function <d2_inithw>. A hardware instance can only be mapped to
    + * one device object.
    + * It is not possible to share a single device pointer between different processes.
    + *
    + * Creating a device will never fail (sufficient memory assumed) but binding
    + * it to a hardware (see: <d2_inithw>) can fail.
    + *
    + * parameters:
    + *  flags - a bitfield containing flags
    + *
    + * flags:
    + *  d2_df_no_dlist           - don't use a display list (slower single command mode)
    + *  d2_df_no_irq             - don't use an interrupt (slower polling used instead)
    + *  d2_df_no_fbcache         - disable framebuffer cache (attention: see note below)
    + *  d2_df_no_texcache        - disable texture cache (attention: see note below)
    + *  d2_df_no_dwclear         - disable double word clearing in d2_clear
    + *  d2_df_no_registercaching - don't use register caching
    + *  d2_df_no_blitctxbackup   - don't backup context data at blit for better performance; previous texture modes get lost and must be set again
    + *
    + * note:
    + *  Flags 'd2_df_no_fbcache' and 'd2_df_no_texcache' should only be used for debugging purposes.
    + *  Especially when multithreading is used, these flags must not be set different for devices which are bound to the same hardware instance through
    + *  <d2_inithw>.
    + *
    + * returns:
    + *  device pointer or NULL if not enough memory was available
    + * */
    +d2_device * d2_opendevice( d2_u32 flags )
    +{
    +#ifdef D2_USEREGCACHE
    +   d2_s32 i;
    +#endif
    +
    +   d2_devicedata *handle = (d2_devicedata *) d2_getmem_p( sizeof(d2_devicedata) );
    +
    +   if(NULL != handle)
    +   {
    +      /* initialize device context */
    +      handle->flags             = flags;
    +      handle->errorcode         = D2_OK;
    +      handle->delayed_errorcode = D2_OK;
    +      handle->hwid              = NULL;
    +      handle->ctxchain          = NULL;
    +      handle->fbformat          = 2;
    +      handle->fbwidth           = 0;
    +      handle->fbheight          = 0;
    +      handle->fbstylemask       = D2C_WRITEFORMAT2;
    +      handle->ctxdef            = d2_newcontext( handle );   /* create default context */
    +      handle->ctxselected       = handle->ctxdef;
    +      handle->ctxsolid          = handle->ctxdef;
    +      handle->ctxoutline        = handle->ctxdef;
    +#ifdef D2_USEBLITBACKUPCONTEXT
    +      handle->blitcontext       = d2_newcontext( handle ); /* create blit context */
    +#else
    +      handle->blitcontext_b     = d2_newbackupcontext_intern( handle, flags ); /* create backup for blit context */
    +#endif
    +      handle->srccontext        = NULL;
    +      handle->srcclut           = NULL;
    +      handle->lasttextwasrle    = 0;
    +      /* default rendering parameters */
    +      handle->framebuffer       = NULL;
    +      handle->pitch             = 0;
    +      handle->bpp               = 0;
    +      handle->rendermode        = d2_rm_solid;
    +      handle->outlinewidth      = 0;
    +      handle->soffx             = 0;
    +      handle->soffy             = 0;
    +      handle->clipxmin          = 0;
    +      handle->clipymin          = 0;
    +      handle->clipxmax          = 0;
    +      handle->clipymax          = 0;
    +      /* initialize default display lists */
    +      handle->renderbuffer[0]   = NULL;
    +      handle->renderbuffer[1]   = NULL;
    +      /* preselect list */
    +      handle->selectedbuffer   = NULL;
    +      handle->writelist        = NULL;
    +      handle->readlist         = NULL;
    +      handle->dlistblocksize   = D2_DLISTBLOCKSIZE;
    +
    +      /* 0x30 is for enabling burstmode of caches -> can be removed for later versions */
    +      handle->cachectlmask     = D2C_CACHECTL_ENABLE_FB | D2C_CACHECTL_ENABLE_TX;
    +
    +      if(0 != (flags & d2_df_no_fbcache))
    +      {
    +         handle->cachectlmask &= ~D2C_CACHECTL_ENABLE_FB;
    +      }
    +
    +      if(0 != (flags & d2_df_no_texcache))
    +      {
    +         handle->cachectlmask &= ~D2C_CACHECTL_ENABLE_TX;
    +      }
    +
    +      handle->perftriggermask  = 0;
    +      handle->lowlocalmem_mode = NULL;
    +
    +      /* clear register cache */
    +#ifdef D2_USEREGCACHE
    +      for(i=0; i<D2_QUANTITY; i++)
    +      {
    +         handle->cache.data[i]  = 0;
    +         handle->cache.valid[i] = 0;
    +      }
    +#endif
    +
    +      /* hw revision */
    +      handle->hwrevision                   = 0;
    +      handle->hilimiterprecision_supported = 0;
    +      handle->maxpatlen                    = 8;
    +
    +      /* attach to chain */
    +      handle->next = g_devicechain;
    +      g_devicechain = handle;
    +   }
    +
    +   return handle;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_closedevice
    + * Destroy a device handle.
    + *
    + * All contexts associated with the device are destroyed as well.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_closedevice( d2_device *handle )
    +{
    +   d2_s32 result;
    +   d2_devicedata **prev;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* release hardware if assigned */
    +   if(NULL != D2_DEV(handle)->hwid)
    +   {
    +      result = d2_deinithw( handle );
    +   }
    +   else
    +   {
    +      result = D2_OK;
    +   }
    +
    +   /* find in chain */
    +   prev = &g_devicechain;
    +   while( (NULL != prev) && (*prev != handle))
    +   {
    +      prev = (d2_devicedata **) *prev;
    +   }
    +
    +   if(NULL == prev)
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +
    +   /* remove from chain */
    +   *prev = D2_DEV(handle)->next;
    +
    +   /* free render contexts */
    +   D2_DEV(handle)->ctxdef = NULL; /* necessary in order to free default context */
    +
    +   while(NULL != D2_DEV(handle)->ctxchain)
    +   {
    +      (void)d2_freecontext(D2_DEV(handle), D2_DEV(handle)->ctxchain);
    +   }
    +
    +   if(0 != D2_DEV(handle)->lowlocalmem_mode)
    +   {
    +      d2_freemem_p(D2_DEV(handle)->lowlocalmem_mode);
    +   }
    +
    +#ifdef D2_USEBLITBACKUPCONTEXT
    +   D2_DEV(handle)->blitcontext = NULL; /* was freed by chain */
    +#else
    +   if(NULL != D2_DEV(handle)->blitcontext_b)
    +   {
    +      d2_freemem_p(D2_DEV(handle)->blitcontext_b);
    +   }
    +   D2_DEV(handle)->blitcontext_b = NULL;
    +#endif
    +
    +   /* free context memory */
    +   d2_freemem_p( handle );
    +
    +   return result;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_geterror
    + * Query device error information.
    + *
    + * See list of all <Errorcodes> for more details.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   integer error code (0 is no error)
    + * */
    +d2_s32 d2_geterror( const d2_device *handle )
    +{
    +   d2_s32 errorCode;
    +
    +   if(NULL != handle)
    +   {
    +      /*D2_VALIDATE( handle, D2_INVALIDDEVICE);*/ /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +      errorCode = D2_DEV(handle)->errorcode;
    +
    +      if(errorCode == D2_OK)
    +      {
    +         errorCode = D2_DEV(handle)->delayed_errorcode;
    +      }
    +   }
    +   else
    +   {
    +      errorCode = D2_INVALIDDEVICE;
    +   }
    +
    +   return errorCode;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_geterrorstring
    + * Query detailed device error information.
    + *
    + * See list of all <Errorcodes> for more details.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   string with human readable error description, or 0 if an error occurs
    + * */
    +const d2_char * d2_geterrorstring( const d2_device *handle )
    +{
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   return d2_translateerror( d2_geterror( handle ) );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Function: d2_inithw
    + *
    + * Initialize hardware for working with specified device.
    + * After creation a device is 'bound' to a hardware instance by calling
    + * inithw for this device. A single device cannot work with multiple
    + * hardware units.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   flags - hardware instance id (use 0 for default)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_inithw( d2_device *handle, d2_u32 flags )
    +{
    +#ifdef D2_USEREGCACHE
    +   d2_s32 i;
    +#endif
    +   d2_devicedata *d2_dev = D2_DEV(handle);
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE);             /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( d2_dev->hwid == NULL, D2_DEVASSIGNED); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   d2_dev->hwid = d2hw_acquire( handle, flags );
    +   if(NULL == d2_dev->hwid)
    +   {
    +      D2_RETERR(handle, D2_HWINUSE);
    +   }
    +
    +   /* invalidate register cache */
    +#ifdef D2_USEREGCACHE
    +   for(i=0; i<D2_QUANTITY; i++)
    +   {
    +      d2_dev->cache.valid[i] = 0;
    +   }
    +#endif
    +
    +   /* setup a ring of two display list blocks as local buffer for low_localmem mode */
    +   if(0 != d2_dev->lowlocalmem_mode)
    +   {
    +      d2_lowlocalmem_mode* llm_mode = d2_dev->lowlocalmem_mode;
    +
    +      llm_mode->dlist_buffer = d2_alloc_dlistblock_intern(handle, d2_dev->dlistblocksize);
    +      D2_CHECKERR( llm_mode->dlist_buffer, D2_NOMEMORY ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +      llm_mode->dlist_buffer->next = d2_alloc_dlistblock_intern(handle, d2_dev->dlistblocksize);
    +      D2_CHECKERR( llm_mode->dlist_buffer->next, D2_NOMEMORY ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +      llm_mode->dlist_buffer->next->next = llm_mode->dlist_buffer;
    +   }
    +
    +   /* initialize default display lists (allocates memory -> can't be done before
    +    * lowlevel initialization!!) */
    +   d2_dev->renderbuffer[0] = (d2_rbuffer*) d2_newrenderbuffer( handle, d2_dev->dlistblocksize, d2_dev->dlistblocksize );
    +   d2_dev->renderbuffer[1] = (d2_rbuffer*) d2_newrenderbuffer( handle, d2_dev->dlistblocksize, d2_dev->dlistblocksize );
    +
    +   if( (NULL == d2_dev->renderbuffer[0]) || (NULL == d2_dev->renderbuffer[1]) )
    +   {
    +      (void)D2_SETERR( handle, D2_NOMEMORY);
    +      return D2_NOMEMORY;
    +   }
    +
    +   /* preselect list */
    +   d2_dev->selectedbuffer = d2_dev->renderbuffer[0];
    +   d2_dev->writelist      = &d2_dev->renderbuffer[0]->baselist;
    +   d2_dev->readlist       = &d2_dev->renderbuffer[1]->baselist;
    +   d2_dev->srccontext     = NULL;
    +
    +   /* allocate and init list assembly scratch buffer */
    +   d2_dev->dlscratch_base = (d2_dlist_scratch_entry*) d2_getmem_p( D2_DLISTSCRATCH * sizeof(d2_dlist_scratch_entry) );
    +   D2_CHECKERR( d2_dev->dlscratch_base, D2_NOMEMORY ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   d2_dev->dlscratch_pos  = d2_dev->dlscratch_base;
    +   d2_dev->dlscratch_cnt  = D2_DLISTSCRATCH;
    +   d2_dev->dlscratch_hook = &d2_scratch2dlist_intern;
    +
    +
    +   d2_dev->dlist_indirect_supported = 0;
    +   if(0 != d1_devicesupported(d2_dev->hwid, D1_DLISTINDIRECT))
    +   {
    +      /* query d1 driver to use lists of dlist start addresses */
    +      d1_setregister(d2_dev->hwid, D1_DLISTINDIRECT, 0, 0x000000ff);
    +      if(0x000000ff == d1_getregister(d2_dev->hwid, D1_DLISTINDIRECT, 0))
    +      {
    +         d2_dev->dlist_indirect_supported = 1;
    +      }
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_deinithw
    + * Unlink hardware currently bound by specified device.
    + * Hardware must be deinitialized before it can be reinitalized for another
    + * device.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_deinithw( d2_device *handle )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   /* error if no hw assigned ? */
    +
    +   if(NULL != D2_DEV(handle)->hwid)
    +   {
    +      d2_s32 err;
    +      d2_rbuffer *rb1,*rb2;
    +
    +      if(0 != D2_DEV(handle)->lowlocalmem_mode)
    +      {
    +         /* free the ring of displaylist blocks */
    +         D2_DEV(handle)->lowlocalmem_mode->dlist_buffer->next->next = NULL;
    +         d2_free_dlistblock_intern(handle, D2_DEV(handle)->lowlocalmem_mode->dlist_buffer);
    +      }
    +
    +      /* free display lists */
    +      rb1 = D2_DEV(handle)->renderbuffer[0];
    +      rb2 = D2_DEV(handle)->renderbuffer[1];
    +      D2_DEV(handle)->renderbuffer[0] = NULL; /* necessary in oder to free default buffer */
    +      D2_DEV(handle)->renderbuffer[1] = NULL;
    +      if(NULL != rb1)
    +      {
    +         (void)d2_freerenderbuffer( handle, rb1 );
    +      }
    +      if(NULL != rb2)
    +      {
    +         (void)d2_freerenderbuffer( handle, rb2 );
    +      }
    +      D2_DEV(handle)->selectedbuffer = NULL;
    +      D2_DEV(handle)->writelist      = NULL;
    +      D2_DEV(handle)->readlist       = NULL;
    +      D2_DEV(handle)->srccontext     = NULL;
    +
    +      /* free scratch buffer */
    +      d2_freemem_p(D2_DEV(handle)->dlscratch_base);
    +      D2_DEV(handle)->dlscratch_base = NULL;
    +      D2_DEV(handle)->dlscratch_pos  = NULL;
    +
    +      err = d2hw_release( D2_DEV(handle)->hwid );
    +      D2_DEV(handle)->hwid = NULL;
    +      D2_RETERR(handle, err);
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    +* function: d2_inithwburstlengthlimit
    +* Set the maximum burst lenght of the master bus interfaces.
    +* Changing the burst length limit should be done only when Dave completely is in idle mode
    +* and all bus transfers are finished.
    +*
    +* parameters:
    +*   handle - device pointer (see: <d2_opendevice>)
    +*   burstlengthFBread - max burst length of framebuffer read interface
    +*   burstlengthFBwrite - max burst length of framebuffer write interface
    +*   burstlengthTX - max burst length of texture cache read interface
    +*   burstlengthDL - max burst length of displaylist read interface
    +*
    +* d2_busburstlength:
    +*   d2_bbl_1  -  single cycle bus access
    +*   d2_bbl_2  -  max bus burst length = 2
    +*   d2_bbl_4  -  max bus burst length = 4
    +*   d2_bbl_8  -  max bus burst length = 8
    +*   d2_bbl_16 -  max bus burst length = 16
    +*   d2_bbl_32 -  max bus burst length = 32
    +*
    +* returns:
    +*   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    +* */
    +d2_s32  d2_inithwburstlengthlimit(d2_device *handle, d2_busburstlength burstlengthFBread, d2_busburstlength burstlengthFBwrite, d2_busburstlength burstlengthTX, d2_busburstlength burstlengthDL)
    +{
    +    d2hw_set(D2_DEV(handle)->hwid, D2_CONTROL3, burstlengthFBread | (burstlengthFBwrite << 8) | (burstlengthTX << 16) | (burstlengthDL << 24));
    +    D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_level1interface
    + * Get the lowlevel device handle currently used by the d2_device. This is necessary
    + * e.g. for allocating framebuffers using the lowlevel (d1_) interface.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   handle for lowlevel device, or NULL if an error occurs
    + * */
    +d1_device * d2_level1interface( const d2_device *handle )
    +{
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   return D2_DEV(handle)->hwid;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getrevisionhw
    + * Query hw revisionID.
    + * This information is available after calling <d2_inithw>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + * HW Revision ID
    + *
    + * HW Revision ID structure:
    + * Bit[7..0]   - revision number
    + * Bit[11..8]  - branch number
    + * Bit[15..12] - D/AVE Type
    + * Bit[20..16] - Features
    + *
    + * D/AVE Type:
    + * 0 - D/AVE2DT-S
    + * 1 - D/AVE2DT-L
    + *
    + * Feature bits:
    + * Bit[16] - D2FB_SWDAVE (Software D/AVE)
    + * Bit[17] - D2FB_DLR (DisplayListReader available)
    + * Bit[18] - D2FB_FBCACHE (Framebuffer Cache available)
    + * Bit[19] - D2FB_TXCACHE (Texture Cache available)
    + * Bit[20] - D2FB_PERFCOUNT (Two performance counters available)
    + * Bit[21] - D2FB_TEXCLUT (Color Lookup Table for ai44 format)
    + * Bit[22] - D2FB_FBPREFETCH (frame buffer cache prefetch available)
    + * Bit[23] - D2FB_RLEUNIT (RLE unit available)
    + * Bit[24] - D2FB_TEXCLUT256 (256 entry CLUT available)
    + * Bit[25] - D2FB_COLORKEY (color keying available)
    + * Bit[26] - D2FB_HILIMITERPRECISION (limiter high precision mode available)
    + * Bit[27] - D2FB_ALPHACHANNELBLENDING (alpha channel blending available)
    + *
    + * see also:
    + *  <d2_getrevisionstringhw>
    + * */
    +d2_u32 d2_getrevisionhw( const d2_device *handle )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   return D2_DEV(handle)->hwrevision;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Copy a string.
    + * 
    + * dst      - Destination string 
    + * src      - Null-terminated source string
    + * dst_size - Size of destination string in chars
    + * */
    +static void d2_strcpy(d2_char *dst, const d2_char *src, d2_u32 dst_size)
    +{
    +   if( (NULL == dst) || (0 == dst_size) )
    +   {
    +      return;
    +   }
    +
    +   --dst_size;
    +   while( (0 != *src) && (0 != dst_size) )
    +   {
    +      *dst = *src;
    +      dst++;
    +      src++;
    +      --dst_size;
    +   }
    +   *dst = 0;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * Append a string.
    + * 
    + * dst      - Destination string 
    + * src      - Null-terminated source string
    + * dst_size - Size of destination string in chars
    + * */
    +static void d2_strcat(d2_char *dst, const d2_char *src, d2_u32 dst_size)
    +{
    +   if(NULL == dst)
    +   {
    +      return;
    +   }
    +
    +   --dst_size;
    +   while( (0 != *dst) && (0 != dst_size) )
    +   {
    +      dst++;
    +   }
    +
    +   d2_strcpy(dst, src, dst_size);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * Convert an unsigned integer to a string.
    + * 
    + * a_dst    - Destination string 
    + * a_number - unsigned integer number
    + * a_size   - Size of destination string in chars
    + * */
    +#ifdef NEED_D2_INTTOSTR
    +static void d2_inttostr(d2_char *a_dst, d2_u32 a_number, d2_u32 a_size)
    +{
    +   d2_u32 digits = 0;
    +   d2_u32 divisor = 1;
    +   d2_u32 num = a_number;
    +   a_size--;
    +
    +   /* find number of digits */
    +   do
    +   {
    +      num /= 10;
    +      divisor *= 10;
    +      digits++;
    +   } while (num > 0);
    +
    +   /* convert to string */
    +   while( (a_size > 0) && (digits > 0) )
    +   {    
    +      d2_u32 digit;
    +
    +      divisor /= 10;
    +      digit = a_number / divisor;
    +      *a_dst = (d2_char) (digit + '0');
    +      a_dst++;
    +      a_number -= digit * divisor;
    +      a_size--;
    +      digits--;    
    +   }
    +
    +   /* add termination */
    +   *a_dst = 0;
    +}
    +#endif /* NEED_D2_INTTOSTR */
    +
    +/*--------------------------------------------------------------------------
    + * Convert an unsigned integer to a hex string.
    + * 
    + * a_dst    - Destination string 
    + * a_number - unsigned integer number
    + * a_size   - Size of destination string in chars
    + * */
    +static void d2_hextostr(d2_char *a_dst, d2_u32 a_number, d2_u32 a_size)
    +{
    +   d2_u32 digits = 0;
    +   d2_u32 divisor = 1;
    +   d2_u32 num = a_number;
    +   a_size--;
    +
    +   /* find number of digits */
    +   do
    +   {
    +      num /= 16;
    +      divisor *= 16;
    +      digits++;
    +   } while (num > 0);
    +
    +   /* convert to string */
    +   while( (a_size > 0) && (digits > 0) )
    +   {    
    +      d2_u32 digit;
    +
    +      divisor /= 16;
    +      digit = a_number / divisor;
    +
    +      if (digit < 10)
    +      {
    +         *a_dst = (d2_char) (digit + '0');
    +         a_dst++;
    +      }
    +      else if (digit < 16)
    +      {
    +         *a_dst = (d2_char) ((digit - 10) + 'a');
    +         a_dst++;
    +      }
    +      else
    +      {
    +         /* empty else block to satisfy MISRA rule 14.10/2004 */
    +      }
    +      /* else if (digit < 16)
    +         {
    +           *a_dst = '-';
    +           a_dst++;
    +         }
    +      */ /* (note) block never reached */
    +      a_number -= digit * divisor;
    +      a_size--;
    +      digits--;    
    +   }
    +
    +   /* add termination */
    +   *a_dst = 0;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getrevisionstringhw
    + * Query hw revisionID string.
    + * This information is available after calling <d2_inithw>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *  human readable hw revision string, or 0 if an error occurs
    + *  (e.g. "D/AVE 2DT-S, Revision 1.05, Features: DLR FBCACHE").
    + *
    + * see also:
    + *  <d2_getrevisionhw>
    + * */
    +const d2_char * d2_getrevisionstringhw( const d2_device *handle)
    +{
    +   static d2_char g_revisionstring[256];
    +   static const d2_char g_hwrevision[3][16] = { {"D/AVE 2DT-S"},
    +                                                {"D/AVE 2DT-L"},
    +                                                {"D/AVE UNKNOWN"}
    +   };
    +   static const d2_char g_hwfeatures[12][64] = { {"SWDAVE"},
    +                                                 {"DLR"},
    +                                                 {"FBCACHE"},
    +                                                 {"TXCACHE"},
    +                                                 {"PERFCOUNT"},
    +                                                 {"TEXCLUT"},
    +                                                 {"TEXCLUT256"},
    +                                                 {"TEXRLE"},
    +                                                 {"TEXCOLORKEY"},
    +                                                 {"HILIMITERPRECISION"},
    +                                                 {"ALPHACHANNELBLENDING"},
    +                                                 {"???"}
    +   };
    +   d2_u32 hwrev;
    +   d2_u32 nb;
    +   d2_u32 type;
    +   d2_char strnb[11];
    +   const d2_u32 bits[] = { D2FB_SWDAVE, D2FB_DLR, D2FB_FBCACHE, D2FB_TXCACHE, D2FB_PERFCOUNT, D2FB_TEXCLUT, D2FB_TEXCLUT256, D2FB_RLEUNIT, D2FB_COLORKEY, D2FB_HILIMITERPRECISION, D2FB_ALPHACHANNELBLENDING };
    +   d2_u32 i = 0;
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   hwrev    = D2_DEV(handle)->hwrevision;
    +   nb       = hwrev & 4095u;
    +   type     = (hwrev >> 12) & 15u;
    +
    +   if(type > 1)
    +   {
    +      type = 2;
    +   }
    +
    +   d2_strcpy(g_revisionstring, g_hwrevision[type], sizeof(g_revisionstring) );
    +   d2_strcat(g_revisionstring, ", Revision ", sizeof(g_revisionstring) );
    +   d2_hextostr(strnb, (nb & 0xf00u) >> 8, sizeof(strnb) );
    +   d2_strcat(g_revisionstring, strnb, sizeof(g_revisionstring) );
    +   d2_strcat(g_revisionstring, ".", sizeof(g_revisionstring) );
    +   d2_hextostr(strnb, (nb & 0x0ffu) >> 0, sizeof(strnb) );
    +   d2_strcat(g_revisionstring, strnb, sizeof(g_revisionstring) );
    +   d2_strcat(g_revisionstring, ", Features: ", sizeof(g_revisionstring) );
    +
    +   for(i=0; i < (sizeof(bits) / sizeof(d2_s32)); ++i)
    +   {
    +      if( (hwrev & bits[i]) != 0 )
    +      {
    +         d2_strcat(g_revisionstring, g_hwfeatures[i], sizeof(g_revisionstring) );
    +         d2_strcat(g_revisionstring, " ", sizeof(g_revisionstring) );
    +      }
    +   }
    +
    +   return g_revisionstring;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_lowlocalmemmode
    + * Enable and configure the 'low localmem' mode.
    + *
    + * On systems with low local CPU memory, the display lists can not be completely
    + * assembled in the local memory. A special mode is used in this case, which
    + * assembles small display list blocks in the local memory and copies them to
    + * the video memory, where they are concatenated to larger blocks.
    + * In order to use this mode it is necessary to call d2_lowlocalmemmode directly
    + * after <d2_opendevice> and before <d2_inithw>.
    + *
    + * Querying the number of effectively used display list blocks can be done using
    + * <d2_getdlistblockcount>, which gives the number of display list blocks used so far
    + * (in units of the local display list block size).
    + * The application developer must take care that the maximum display list size configured
    + * using <d2_lowlocalmemmode> is sufficient.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   dlistblockfactor - size of a dlist block in vidmem is this factor * local size (configurable using <d2_setdlistblocksize>)
    + *   dlistblocks - maximum number of dlist blocks in vidmem
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_setdlistblocksize>
    + * */
    +d2_s32 d2_lowlocalmemmode(d2_device *handle, d2_u32 dlistblockfactor, d2_u32 dlistblocks)
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_CHECKERR(dlistblockfactor >= 2, D2_VALUETOOSMALL); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR(dlistblocks >= 1, D2_VALUETOOSMALL);      /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 != (D2_DEV(handle)->flags & d2_df_no_dlist))
    +   {
    +      D2_RETERR( handle, D2_NO_DISPLAYLIST);
    +   }
    +
    +   if(NULL == D2_DEV(handle)->lowlocalmem_mode)
    +   {
    +      D2_DEV(handle)->lowlocalmem_mode = d2_getmem_p(sizeof(d2_lowlocalmem_mode));
    +      D2_CHECKERR(D2_DEV(handle)->lowlocalmem_mode, D2_NOMEMORY); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   }
    +
    +   D2_DEV(handle)->lowlocalmem_mode->vidmemblocksizefactor = dlistblockfactor;
    +   D2_DEV(handle)->lowlocalmem_mode->vidmemblocks = dlistblocks;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: Rendering Mode
    + * */
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_selectrendermode
    + * Select a rendering mode.
    + * Dave can automatically generate and render geometry outlines and shadows.
    + * A different rendering context is used for interior (solid context) and addons
    + * (outline context) so that both parts can have entirely different materials.
    + *
    + * Note that primitives which are issued while rendermode 'postprocess' is active
    + * are buffered and put into the commandlist after all normal commands.
    + * Combined rendermodes like 'solid_outlined' and 'solid_shadow' internally use
    + * postprocessing to sort solid and outline parts.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   mode - rendering mode
    + *
    + * available rendering modes:
    + *   d2_rm_solid - Direct rendering of primitives (default mode)
    + *   d2_rm_outline - Only outlines are rendered
    + *   d2_rm_solid_outlined - Interior and outlines are rendered
    + *   d2_rm_shadow - Only shadows are rendered
    + *   d2_rm_solid_shadow - Interior and shadows are rendered
    + *  d2_rm_postprocess - Direct rendering of primitives as a postprocess
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_outlinewidth>, <d2_shadowoffset>
    + * */
    +d2_s32 d2_selectrendermode( d2_device *handle, d2_u32 mode )
    +{
    +   d2_u32 oldmode;
    +
    +   if(NULL == handle)
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +   /*D2_VALIDATE( handle, D2_INVALIDDEVICE );*/ /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ((mode & ( d2_rm_solid | d2_rm_outline | d2_rm_shadow | d2_rm_postprocess)) == mode) && (mode != 0), D2_ILLEGALMODE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   oldmode = D2_DEV(handle)->rendermode;
    +   if(oldmode == mode)
    +   {
    +      D2_RETOK(handle);
    +   }
    +
    +   if( (oldmode != mode) && (oldmode != d2_rm_postprocess) && (mode != d2_rm_postprocess) )
    +   {
    +      /* merge in layers if they contain data */
    +      (void)d2_layermerge( handle );
    +   }
    +
    +   D2_DEV(handle)->rendermode = mode;
    +   D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +
    +   /* change target buffer if postprocess mode */
    +   if(d2_rm_postprocess == oldmode)
    +   {
    +      d2_rendertobase_intern( handle );
    +   }
    +
    +   if(d2_rm_postprocess == mode)
    +   {
    +      d2_rendertolayer_intern( handle );
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getrendermode
    + * Get the rendering mode.
    + * This function can be used to get the rendering mode used for a 
    + * specified d2_device.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * available rendering modes:
    + *   d2_rm_solid - Direct rendering of primitives (default mode)
    + *   d2_rm_outline - Only outlines are rendered
    + *   d2_rm_solid_outlined - Interior and outlines are rendered
    + *   d2_rm_shadow - Only shadows are rendered
    + *   d2_rm_solid_shadow - Interior and shadows are rendered
    + *   d2_rm_postprocess - Direct rendering of primitives as a postprocess
    + *
    + * returns:
    + *   integer specifying the rendering mode, or 0 if an error occurs
    + *
    + * */
    +d2_u32 d2_getrendermode( const d2_device *handle )
    +{
    +   if(NULL == handle)
    +   {
    +      return 0;
    +   }
    +   else
    +   {
    +      return D2_DEV(handle)->rendermode;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_layermerge
    + * Join outline and solid parts of currently selected renderbuffer. When
    + * using rendermode *d2_rm_postprocess* (see: <d2_selectrendermode>) the
    + * postprocess buffer can be flushed using a call to d2_layermerge.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_selectrendermode>
    + * */
    +d2_s32 d2_layermerge( d2_device *handle )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   d2_layer2dlist_intern( handle );
    +   D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +
    +   D2_RETOK(handle);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_outlinewidth
    + * Define the width of geometry outlines. Used only when using outline or
    + * solid_outlined rendering modes.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   width - outline width in pixels (fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_selectrendermode>, <d2_shadowoffset>
    + * */
    +d2_s32 d2_outlinewidth( d2_device *handle, d2_width width )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );    /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( width >= 0, D2_INVALIDWIDTH ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_DEV(handle)->outlinewidth = width;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_shadowoffset
    + * Define the offset of geometry shadows. Used only when using shadow or
    + * solid_shadow rendering modes.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x - x axis offset in pixels (fixedpoint)
    + *   y - y axis offset in pixels (fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_selectrendermode>, <d2_outlinewidth>
    + * */
    +d2_s32 d2_shadowoffset( d2_device *handle, d2_point x, d2_point y )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_DEV(handle)->soffx = x;
    +   D2_DEV(handle)->soffy = y;
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: Utility Functions
    + * */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_flushframe
    + * Wait for current rendering to end.
    + *
    + * Function will not return until the hardware has finished executing all
    + * currently active rendering operations. Note that no rendering operations
    + * are started until a renderbuffer is executed. (See <Render Buffers>)
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_flushframe( d2_device *handle )
    +{
    +   if(NULL != handle)
    +   {
    +      /*D2_VALIDATE( handle, D2_INVALIDDEVICE );*/ /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +      /* wait for current frame rendering to end */
    +      d2hw_finish( handle );
    +
    +      D2_RETOK(handle);
    +   }
    +   else
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setdlistblocksize
    + * Set blocksize for default displaylists.
    + *
    + * Sets the number of displaylist entries per block (aka page).
    + * The value given is effectively used for internal calls to <d2_newrenderbuffer>
    + * as both 'initialsize' and 'stepsize'.
    + * For hints on how to optimize this size see documentation of <d2_newrenderbuffer>.
    + *
    + * The default blocksize is: 204
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   size   - number of displaylist entries per block (minimum is 3)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * note:
    + *   The minimum number of displaylist entries per block is 3. This 
    + *   limitation is required to terminate a list correctly, there must be
    + *   enough space to insert a dlist jump and a special termination entry.
    + *
    + * see also:
    + *   <d2_getdlistblocksize>, <d2_newrenderbuffer>
    + * */
    +d2_s32 d2_setdlistblocksize(d2_device *handle, d2_u32 size)
    +{
    +   if(NULL != handle)
    +   {
    +      /*D2_VALIDATE( handle, D2_INVALIDDEVICE );*/ /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +      D2_CHECKERR(size > 2, D2_VALUETOOSMALL); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +      D2_DEV(handle)->dlistblocksize = size;
    +
    +      D2_RETOK(handle);
    +   }
    +   else
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getdlistblocksize
    + * Get blocksize of default displaylist.
    + *
    + * Function will return the number of displaylist entries per block
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   number of displaylist entries per block, or 0 if an error occurs
    + *
    + * see also:
    + *   <d2_setdlistblocksize>, <d2_newrenderbuffer>
    + * */
    +d2_u32 d2_getdlistblocksize(const d2_device *handle)
    +{
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   return D2_DEV(handle)->dlistblocksize;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getdlistblockcount
    + * Get number of blocks of default displaylist (writelist).
    + *
    + * Function will return the number of used blocks for current displaylist
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   number of used blocks
    + *
    + * see also:
    + *   <d2_setdlistblocksize>, <d2_newrenderbuffer>
    + * */
    +d2_u32 d2_getdlistblockcount(d2_device *handle)
    +{
    +   d2_dlist          *dlist;
    +   d2_dlist_block    *cblock;
    +   d2_u32             num = 1;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   dlist = &D2_DEV(handle)->selectedbuffer->baselist;
    +   cblock = dlist->firstblock;
    +
    +   /* clear scratch before counting */
    +   d2_scratch2dlist_intern(handle);
    +
    +   if(NULL != dlist->vidmem_blocks)
    +   {
    +      num += ((d2_u32)(dlist->vidmem_blocks->currentblock - dlist->vidmem_blocks->blocks)) * dlist->vidmem_blocks->num_slices;
    +      num += dlist->vidmem_blocks->num_slices - dlist->vidmem_blocks->slicesleft;
    +   }
    +   else
    +   {
    +      while(cblock != dlist->currentblock)
    +      {
    +         cblock = cblock->next;
    +         ++num;
    +      }
    +   }
    +
    +   return num;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_commandspending
    + * Check if there are pending commands in the current displaylist.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   boolean value: true when there are commands pending, also 0 if an error occurs
    + *
    + * see also:
    + *   <d2_getdlistblockcount>
    + * */
    +d2_s32 d2_commandspending(d2_device *handle)
    +{
    +   d2_dlist *dlist;
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   dlist = &D2_DEV(handle)->selectedbuffer->baselist;
    +
    +   /* clear scratch before check */
    +   d2_scratch2dlist_intern(handle);
    +
    +   if(dlist->position != dlist->firstblock->block)
    +   {
    +      return 1; /* this means commands pending in any case */
    +   }
    +
    +   /* in lowlocalmem mode, we might be at the beginning of the first block, but in
    +    * another vidmem block */
    +   if( (NULL != dlist->vidmem_blocks) && (dlist->vidmem_blocks->currentaddress == dlist->vidmem_blocks->blocks[0]) )
    +   {
    +      return 1;
    +   }
    +   else
    +   {
    +      return 0;
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_edge.c b/src/drivers/dave2d/src/dave_edge.c
    new file mode 100644
    index 000000000..8357740b6
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_edge.c
    @@ -0,0 +1,660 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_edge.c (%version: 14 %)
    + *          created Mon Jan 31 18:40:01 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jan 04 13:51:46 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2010-09-28 MRe  use 64bit arithmetic for blurring calculation
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_edge.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + * line length may not be zero.
    + * */
    +void d2_lineedge_setup3blur_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 flags, const d2_contextdata *ctx, d2_s32 *length )
    +{
    +   d2_s32 xa, ya, l;
    +   d2_s32 s1, s2, s3;
    +   d2_s32 oa, ob;
    +
    +   /* get extension offsets */
    +   if(0 != (flags & d2_le_exclude_start))
    +   {
    +      oa = 0;
    +   }
    +   else
    +   {
    +      oa = (d2_s32) (ctx->invblur << 0);
    +   }
    +
    +   if(0 != (flags & d2_le_exclude_end))
    +   {
    +      ob = 0;
    +   }
    +   else
    +   {
    +      ob = (d2_s32) (ctx->invblur << 0);
    +   }
    +
    +   l = ((d2_s32)(ctx->invblur * 16u)) / d2_sqrt( (d2_u32) ((dx * dx) + (dy * dy)) );
    +
    +   if(NULL != length)
    +   {
    +      *length = l;
    +   }
    +
    +   xa = (-dy * l) >> 4;                              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   ya = ( dx * l) >> 4;                              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s1 = (((-px * xa) - (py * ya) ) >> 4);            /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s2 = (((-px * ya) + (py * xa) ) >> 4);            /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s3 = (((px + dx) * ya) - ((py + dy) * xa)) >> 4;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /* store limiter parameters */
    +   lim[0].start = s1 + (d2_s32)(ctx->invblur / 2u);
    +   lim[0].xadd  = xa;
    +   lim[0].yadd  = ya;
    +   lim[1].start = s2 + oa;
    +   lim[1].xadd  = ya;
    +   lim[1].yadd  = -xa;
    +   lim[2].start = s3 + ob;
    +   lim[2].xadd  = -ya;
    +   lim[2].yadd  = xa;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * line length may not be zero.
    + * */
    +void d2_lineedge_setup3sqrt_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 flags, d2_s32 *length )
    +{
    +   d2_s32 xa, ya, l;
    +   d2_s32 s1, s2, s3;
    +   d2_s32 oa, ob;
    +
    +   /* get extension offsets */
    +   if(0 != (flags & d2_le_exclude_start))
    +   {
    +      oa = 0;
    +   }
    +   else
    +   {
    +      oa = D2_FIX16(1);
    +   }
    +
    +   if(0 != (flags & d2_le_exclude_end))
    +   {
    +      ob = 0;
    +   }
    +   else
    +   {
    +      ob = D2_FIX16(1);
    +   }
    +
    +   l = (65536 * 16) / d2_sqrt( (d2_u32)( (dx * dx) + (dy * dy) ) );
    +
    +   if(NULL != length)
    +   {
    +      *length = l;
    +   }
    +
    +   xa = (-dy * l) >> 4;                              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   ya = ( dx * l) >> 4;                              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s1 = ((-px * xa) - (py * ya) ) >> 4;              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s2 = ((-px * ya) + (py * xa) ) >> 4;              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s3 = (((px + dx) * ya) - ((py + dy) * xa)) >> 4;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /* store limiter parameters */
    +   lim[0].start = s1 + (D2_FIX16(1) / 2);
    +   lim[0].xadd  = xa;
    +   lim[0].yadd  = ya;
    +   lim[1].start = s2 + oa;
    +   lim[1].xadd  = ya;
    +   lim[1].yadd  = -xa;
    +   lim[2].start = s3 + ob;
    +   lim[2].xadd  = -ya;
    +   lim[2].yadd  = xa;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * note use for thin lines (w<2) only (due to l1 norm approximation)
    + * line length may not be zero.
    + * */
    +void d2_lineedge_setup3_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 flags, d2_s32 *length )
    +{
    +   d2_s32 n, xa, ya;
    +   d2_s32 s1, s2, s3;
    +   d2_s32 oa, ob;
    +
    +   /* get extension offsets */
    +   if(0 != (flags & d2_le_exclude_start))
    +   {
    +      oa = 0;
    +   }
    +   else
    +   {
    +      oa = D2_FIX16(1);
    +   }
    +
    +   if(0 != (flags & d2_le_exclude_end))
    +   {
    +      ob = 0;
    +   }
    +   else
    +   {
    +      ob = D2_FIX16(1);
    +   }
    +
    +   /* find line octant */
    +   if(dx < 0)
    +   {
    +      if(dy < 0)
    +      {
    +         /* dx -
    +          * dy - */
    +         if(dx < dy)
    +         {
    +            /* 3. octant
    +             * l = -dx, nx = -dy / -dx, ny = -1 */
    +
    +            n = (dy << 16) / dx;                                       /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = (py << (16 - 4)) - ((px * n) >> 4);                   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s2 = (px << (16 - 4)) + ((py * n) >> 4);                   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/  
    +            s3 = -((px + dx) << (16 - 4)) - (((py + dy) * n) >> 4);    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            xa = n;
    +            ya = D2_FIX16( -1 );                                       /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +            if(NULL != length)
    +            {
    +               *length = -dx;
    +            }
    +
    +         }
    +         else
    +         {
    +            /* 4. octant
    +             * l = -dy, nx = 1, ny = dx / -dy */
    +
    +            n = (dx << 16) / -dy;                                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = (-px << (16 - 4)) - ((py * n) >> 4);                  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s2 = ( py << (16 - 4)) - ((px * n) >> 4);                  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s3 = (((px + dx) * n) >> 4) - ((py + dy) << (16 - 4));     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            xa = D2_FIX16( 1 );                                        /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = n;
    +
    +            if(NULL != length)
    +            {
    +               *length = -dy;
    +            }
    +         }
    +      }
    +      else
    +      {
    +         /* dx -
    +          * dy + */
    +         if(-dx > dy)
    +         {
    +            /* 5. octant
    +             * l = dx, nx = -dy / -dx, ny = -1 */
    +
    +            n = (dy << 16) / dx;                                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = (py << (16 - 4)) - ((px * n) >> 4);                 /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s2 = (px << (16 - 4)) + ((py * n) >> 4);                 /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s3 = -((px + dx) << (16 - 4)) - (((py + dy) * n) >> 4);  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            xa = n;
    +            ya = D2_FIX16( -1 );                                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +            if(NULL != length)
    +            {
    +               *length = dx;
    +            }
    +
    +         }
    +         else
    +         {
    +            /* 6. octant
    +             * l = dy, nx = -1, ny = dx / dy */
    +
    +            n = (dx << 16) / dy;                                    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = ( px << (16 - 4)) - ((py * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s2 = (-py << (16 - 4)) - ((px * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s3 = (((px + dx) * n) >> 4) + ((py + dy) << (16 - 4));  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            xa = D2_FIX16( -1 );                                    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = n;
    +
    +            if(NULL != length)
    +            {
    +               *length = dy;
    +            }
    +         }
    +      }
    +   }
    +   else
    +   {
    +      if(dy < 0)
    +      {
    +         /* dx +
    +          * dy - */
    +         if(dx > -dy)
    +         {
    +            /* 1. octant
    +             * l = dx, nx = -dy / dx, ny = 1 */
    +
    +            n = (dy << 16) / -dx;                                   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = (-py << (16 - 4)) - ((px * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s2 = (-px << (16 - 4)) + ((py * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s3 = ((px + dx) << (16 - 4)) - (((py + dy) * n) >> 4);  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            xa = n;
    +            ya = D2_FIX16( 1 );                                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +            if(NULL != length)
    +            {
    +               *length = dx;
    +            }
    +
    +         }
    +         else
    +         {
    +            /* 2. octant
    +             * l = -dy, nx = 1, ny =  dx / -dy */
    +
    +            n = (dx << 16) / -dy;                                   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = (-px << (16 - 4)) - ((py * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            s2 = ( py << (16 - 4)) - ((px * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            s3 = (((px + dx) * n) >> 4) - ((py + dy) << (16 - 4));  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +            xa = D2_FIX16( 1 );                                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = n;
    +            
    +            if(NULL != length)
    +            {
    +               *length = -dy;
    +            }
    +         }
    +      }
    +      else
    +      {
    +         /* dx +
    +          * dy + */
    +         if(dx > dy)
    +         {
    +            /* 8. octant
    +             * l = dx, nx = -dy / dx, ny = 1 */
    +
    +            n = (dy << 16) / -dx;                                   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = (-py << (16 - 4)) - ((px * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            s2 = (-px << (16 - 4)) + ((py * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            s3 = ((px + dx) << (16 - 4)) - (((py + dy) * n) >> 4);  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = n;
    +            ya = D2_FIX16( 1 );                                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +            if(NULL != length)
    +            {
    +               *length = dx;
    +            }
    +
    +         }
    +         else
    +         {
    +            /* 7. octant
    +             * l = dy, nx = -1, ny =  dx / dy */
    +
    +            n = (dx << 16) / dy;                                    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s1 = ( px << (16 - 4)) - ((py * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            s2 = (-py << (16 - 4)) - ((px * n) >> 4);               /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            s3 = (((px + dx) * n) >> 4) + ((py + dy) << (16 - 4));  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = D2_FIX16( -1 );                                    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = n;
    +
    +            if(NULL != length)
    +            {
    +               *length = dy;
    +            }
    +         }
    +      }
    +   }
    +
    +   /* store limiter parameters */
    +   lim[0].start = s1 + (D2_FIX16(1) / 2);                           /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   lim[0].xadd  = xa;
    +   lim[0].yadd  = ya;
    +   lim[1].start = s2 + oa;
    +   lim[1].xadd  = ya;
    +   lim[1].yadd  = -xa;
    +   lim[2].start = s3 + ob;
    +   lim[2].xadd  = -ya;
    +   lim[2].yadd  = xa;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * edge deltas may not both be zero. centering of start value (+0.5) is
    + * omitted here. this was necessary to allow highler level to change center
    + * for non shared edges.
    + * */
    +void d2_triedge_setup_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_u32 rightedge )
    +{
    +   d2_s32 n;
    +   d2_s32 s,xa,ya;
    +
    +   /* find edge octant */
    +   if(dx < 0)
    +   {
    +      if(dy < 0)
    +      {
    +         /* dx -
    +          * dy - */
    +         px = (d2_point)(px + (d2_point) dx);
    +         py = (d2_point)(py + (d2_point) dy);
    +
    +         if(dx > dy)
    +         {
    +            /* 3. octant */
    +            n = (dx << 16) / dy;                       /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((py * n) >> 4) - (px << (16 - 4));    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = D2_FIX16( 1 );                        /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = -n;
    +         }
    +         else
    +         {
    +            /* 4. octant */
    +            n = (dy << 16) / dx;                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (py << (16 - 4)) - ((px * n) >> 4);   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = n;
    +            ya = D2_FIX16( -1 );                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         }
    +      }
    +      else
    +      {
    +         /* dx -
    +          * dy + */
    +         if(-dx > dy)
    +         {
    +            /* 5. octant */
    +            n = (dy << 16) / dx;                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (py << (16 - 4)) - ((px * n) >> 4);   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = n;
    +            ya = D2_FIX16( -1 );                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         }
    +         else
    +         {
    +            /* 6. octant */
    +            n = (dx << 16) / dy;                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (px << (16 - 4)) - ((py * n) >> 4);   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = D2_FIX16( -1 );                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = n;
    +         }
    +      }
    +   }
    +   else
    +   {
    +      if(dy < 0)
    +      {
    +         /* dx +
    +          * dy - */
    +         px = (d2_point)(px + (d2_point) dx);
    +         py = (d2_point)(py + (d2_point) dy);
    +
    +         if(dx > -dy)
    +         {
    +            /* 1. octant */
    +            n = (dy << 16) / dx;                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((px * n) >> 4) - (py << (16 - 4));  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = -n;
    +            ya = D2_FIX16( 1 );                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         }
    +         else
    +         {
    +            /* 2. octant */
    +            n = (dx << 16) / dy;                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((py * n) >> 4) - (px << (16 - 4));  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = D2_FIX16( 1 );                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = -n;
    +         }
    +      }
    +      else
    +      {
    +         /* dx +
    +          * dy + */
    +         if(dx > dy)
    +         {
    +            /* 8. octant */
    +            n = (dy << 16) / dx;                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((px * n) >> 4) - (py << (16 - 4));  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = -n;
    +            ya = D2_FIX16( 1 );                      /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         }
    +         else
    +         {
    +            /* 7. octant */ 
    +            n = (dx << 16) / dy;                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (px << (16 - 4)) - ((py * n) >> 4);  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = D2_FIX16( -1 );                     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            ya = n;
    +         }
    +      }
    +   }
    +
    +   if(0 != rightedge)
    +   {
    +      s += D2_EPSILON;
    +   }
    +
    +   lim->start = s;
    +   lim->xadd  = xa;
    +   lim->yadd  = ya;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * note should use sqrtsetup when bluring long distance
    + * edge deltas may not both be zero.
    + * */
    +void d2_triedge_setupblur_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, const d2_contextdata *ctx )
    +{
    +   d2_int64 n;
    +   d2_int64 tmp;
    +   d2_s32 s,xa,ya;
    +   d2_s32 invBlur;
    +
    +   /* reduce bitsize */
    +   invBlur = (d2_s32)ctx->invblur;
    +
    +   /* find edge octant */
    +   if ( dx < 0 )
    +   {
    +      if ( dy < 0 )
    +      {
    +         /* dx -
    +          * dy - */
    +         px = (d2_point)(px + (d2_point) dx);
    +         py = (d2_point)(py + (d2_point) dy);
    +
    +         if(dx > dy)
    +         {
    +            /* 3. octant */
    +            D2_CAST32TO64((dx << 16) / dy, &n); /* n = (dx << 16) / dy; */     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((py * D2_CAST64TO32(&n)) >> 4) - (px << (16 - 4));            /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = invBlur;
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            ya = -D2_CAST64TO32(&n);
    +         }
    +         else
    +         {
    +            /* 4. octant */
    +            D2_CAST32TO64((dy << 16) / dx, &n); /* n = (dy << 16) / dx; */     /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (py << (16 - 4)) - ((px * D2_CAST64TO32(&n)) >> 4);            /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            xa = D2_CAST64TO32(&n);
    +            ya = -invBlur;
    +         }
    +      }
    +      else
    +      {
    +         /* dx -
    +          * dy + */
    +         if(-dx > dy)
    +         {
    +            /* 5. octant */
    +            D2_CAST32TO64((dy << 16) / dx, &n); /* n = (dy << 16) / dx; */    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (py << (16 - 4)) - ((px * D2_CAST64TO32(&n)) >> 4);           /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            xa = D2_CAST64TO32(&n); /* (n * redinv) >> 8; */
    +            ya = -invBlur;
    +         }
    +         else
    +         {
    +            /* 6. octant */
    +            D2_CAST32TO64((dx << 16) / dy, &n); /* n = (dx << 16) / dy; */   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (px << (16 - 4)) - ((py * D2_CAST64TO32(&n)) >> 4);          /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = -invBlur;
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            ya = D2_CAST64TO32(&n); /* (n * redinv) >> 8; */
    +         }
    +      }
    +   }
    +   else
    +   {
    +      if(dy < 0)
    +      {
    +         /* dx +
    +          * dy - */
    +         px = (d2_point)(px + (d2_point) dx);
    +         py = (d2_point)(py + (d2_point) dy);
    +
    +         if(dx > -dy)
    +         {
    +            /* 1. octant */
    +            D2_CAST32TO64((dy << 16) / dx, &n); /* n = (dy << 16) / dx; */  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((px * D2_CAST64TO32(&n)) >> 4) - (py << (16 - 4));         /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            xa = -D2_CAST64TO32(&n); /* (-n * redinv) >> 8; */
    +            ya = invBlur;
    +         }
    +         else
    +         {
    +            /* 2. octant */
    +            D2_CAST32TO64((dx << 16) / dy, &n); /* n = (dx << 16) / dy; */  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((py * D2_CAST64TO32(&n)) >> 4) - (px << (16 - 4));         /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = invBlur;
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            ya = -D2_CAST64TO32(&n);
    +         }
    +      }
    +      else
    +      {
    +         /* dx +
    +          * dy + */
    +         if(dx > dy)
    +         {
    +            /* 8. octant */
    +            D2_CAST32TO64((dy << 16) / dx, &n); /* n = (dy << 16) / dx; */  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = ((px * D2_CAST64TO32(&n)) >> 4) - (py << (16 - 4));         /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            xa = -D2_CAST64TO32(&n);
    +            ya = invBlur;
    +         }
    +         else
    +         {
    +            /* 7. octant */
    +            D2_CAST32TO64((dx << 16) / dy, &n); /* n = (dx << 16) / dy; */  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +            s = (px << (16 - 4)) - ((py * D2_CAST64TO32(&n)) >> 4);         /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/ /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +            xa = -invBlur;
    +            D2_MUL3264(invBlur, &n, &tmp);
    +            D2_SHIFTRIGHT64(&tmp, 16, &n);
    +            ya = D2_CAST64TO32(&n); /* (n * redinv) >> 8; */
    +         }
    +      }
    +   }
    +
    +   s = (s << 4) / ctx->blurring;                                            /* PRQA S 4131       */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +   lim->start = s + (invBlur / 2);
    +   lim->xadd  = xa;
    +   lim->yadd  = ya;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * warning: will overflow earlier than aa version. might blow 11bit border
    + * edge deltas may not both be zero.
    + * */
    +void d2_triedge_setupnoaa_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_s32 rightedge )
    +{
    +   d2_s32 s,xa,ya;
    +
    +   /* flip if negative (necessary for gapless rendering of adjacent edges) */
    +   if ( dy < 0 )
    +   {
    +      px = (d2_point)(px + (d2_point) dx);
    +      py = (d2_point)(py + (d2_point) dy);
    +   }
    +
    +   /* non normalized limiter base: not suited for aa rendering but fast */
    +   s = ((px * dy) - (py * dx)) << (16 - 8);    /* PRQA S 4131       */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   xa = (-dy) << (16 - 4);                     /* PRQA S 4131       */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   ya =   dx  << (16 - 4);                     /* PRQA S 4131       */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +   /* use > instead of >= threshold on right/top edges */
    +   if(0 != rightedge)
    +   {
    +      s += D2_EPSILON;
    +   }
    +
    +   lim->start = s + (D2_FIX16(1)/2);
    +   lim->xadd  = xa;
    +   lim->yadd  = ya;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_triedge_setupsqrt_intern( d2_limdata *lim, d2_point px, d2_point py, d2_s32 dx, d2_s32 dy, d2_s32 rightedge )
    +{
    +   d2_s32 s, xa, ya, l;
    +
    +   /* flip if negative (necessary for gapless rendering of adjacent edges) */
    +   if(dy < 0)
    +   {
    +      px = (d2_point)(px + (d2_point) dx);
    +      py = (d2_point)(py + (d2_point) dy);
    +   }
    +
    +   l = (d2_s32)( (65536u * 16u) / (d2_u32)d2_sqrt( (d2_u32)( (dx * dx) + (dy * dy) ) ) );
    +
    +   xa = (-dy * l) >> 4;                 /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +   ya = ( dx * l) >> 4;                 /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +   s = ((-px * xa) - (py * ya) ) >> 4;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +
    +   /* use > instead of >= threshold on right/top edges */
    +   if(0 != rightedge)
    +   {
    +      s += D2_EPSILON;
    +   }
    +
    +   lim->start = s + (D2_FIX16(1)/2);
    +   lim->xadd  = xa;
    +   lim->yadd  = ya;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * used to setup bottom-up rendering
    + * */
    +void d2_invertlimiter_intern(d2_limdata *lim, d2_s32 ystep)
    +{
    +   /* prestep and flip */
    +   lim->start =  lim->start + (lim->yadd * ystep);
    +   lim->yadd  = -lim->yadd;
    +}
    diff --git a/src/drivers/dave2d/src/dave_errorcodes.c b/src/drivers/dave2d/src/dave_errorcodes.c
    new file mode 100644
    index 000000000..9028f0d53
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_errorcodes.c
    @@ -0,0 +1,38 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_errorcodes.c (%version: 2 %)
    + *          created Tue Jan 11 13:45:53 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Wed Feb 09 13:40:19 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2007-08-31 ASc  removed tabs, changed C++ to C comments,
    + *                   changed g_errorcodes to const pointer to const data
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +
    +
    +/*-------------------------------------------------------------------------- */
    +#define ERR(x,y) y " (" #x ")" ,
    +
    +/*-------------------------------------------------------------------------- */
    +const d2_char *d2_translateerror( d2_s32 errorcode )
    +{
    +
    +static const d2_char* const g_errorcodes[ D2_ERROR_QUANTITY+1 ] = {
    +#include "dave_errorcodes.h"                                         /* PRQA S 5087 */ /* $Misra: #INCLUDE_ERRCODES $*/
    +   "undefined error" };
    +
    +   /* map undefined indices to last index (undef error) */
    +   if((d2_u32)errorcode > (d2_u32)D2_ERROR_QUANTITY)
    +   {
    +      errorcode = D2_ERROR_QUANTITY;
    +   }
    +
    +   /* return errordescription */
    +   return g_errorcodes[ errorcode ];
    +}
    diff --git a/src/drivers/dave2d/src/dave_gradient.c b/src/drivers/dave2d/src/dave_gradient.c
    new file mode 100644
    index 000000000..23e096e4b
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_gradient.c
    @@ -0,0 +1,234 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_gradient.c (%version: 8 %)
    + *          created Fri Jan 21 16:45:30 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Jun 13 11:46:15 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_render.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE d2_u32 d2_initgradient_lin( d2_devicedata *handle, const d2_gradientdata *grad, const d2_bbox *bbox, d2_u32 index, d2_u32 usehiprecision ); /* to satisfy MISRA rule 3450 */
    +
    +static D2_INLINE d2_u32 d2_initgradient_quad( const d2_devicedata *handle, const d2_gradientdata *grad, const d2_bbox *bbox, d2_u32 index );
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_initgradient_intern( d2_gradientdata *grad )
    +{
    +   grad->mode  = d2_grad_none;
    +   grad->x1    = 0;
    +   grad->y1    = 0;
    +   grad->xadd  = 0;
    +   grad->yadd  = 0;
    +   grad->xadd2 = 0;
    +   grad->yadd2 = 0;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE d2_u32 d2_initgradient_lin( d2_devicedata *handle, const d2_gradientdata *grad, const d2_bbox *bbox, d2_u32 index, d2_u32 usehiprecision )
    +{
    +   d2_s32 x, y, s;
    +   d2_u32 ctrl;
    +
    +   x = grad->x1 - bbox->xmin;
    +   y = grad->y1 - bbox->ymin;
    +   s = ((x * grad->xadd) + (y * grad->yadd)) >> 4;        /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   if(0 != (grad->mode & d2_grad_rightedge))
    +   {
    +      s += D2_EPSILON;
    +   }
    +
    +   if(0 != (grad->mode & d2_grad_offset))
    +   {
    +      s -= D2_FIX16(1);
    +   }
    +
    +   ctrl = D2C_LIM1ENABLE << index;
    +
    +   if(0 != (grad->mode & d2_grad_threshold))
    +   {
    +      ctrl |= D2C_LIM1THRESHOLD << index;
    +
    +      // compensate that threshold moves actual edge to pixel center
    +      s -= (D2_FIX16(1)>>1) + D2_EPSILON;
    +   }
    +
    +   if(0 != (grad->mode & d2_grad_concave))
    +   {
    +      ctrl |= D2C_UNION12 << (index >> 1);
    +   }
    +
    +   if(0 == usehiprecision)
    +   {
    +      D2_DLISTWRITES( D2_L1START + index, -s );
    +      D2_DLISTWRITES( D2_L1XADD  + index, grad->xadd );
    +      D2_DLISTWRITES( D2_L1YADD  + index, grad->yadd );
    +   }
    +   else
    +   {
    +      D2_DLISTWRITES( D2_L1START + index, -s << LIMITER_HIPRECISION );         /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      D2_DLISTWRITES( D2_L1XADD  + index, grad->xadd << LIMITER_HIPRECISION ); /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      D2_DLISTWRITES( D2_L1YADD  + index, grad->yadd << LIMITER_HIPRECISION ); /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   }
    +
    +   return ctrl;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE d2_u32 d2_initgradient_quad( const d2_devicedata *handle, const d2_gradientdata *grad, const d2_bbox *bbox, d2_u32 index )
    +{
    +   /* dummy */
    +   (void)handle;  /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +   (void)grad;    /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +   (void)bbox;    /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +   (void)index;   /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +
    +   return 0;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_u32 d2_initgradients_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox, d2_u32 limindex, d2_u32 control )
    +{
    +   if(0 != (ctx->gradients & 1))
    +   {
    +      if(0 != (ctx->gradient[0].mode & d2_grad_linear))
    +      {
    +         if(limindex > 5)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_lin( handle, &ctx->gradient[0], bbox, limindex, control & D2C_LIMITERPRECISION );
    +         control &= ~D2C_SPANSTORE;
    +         if(0 != (ctx->gradient[0].mode & d2_grad_concave))
    +         {
    +            control &= ~D2C_SPANABORT;
    +         }
    +
    +         limindex += 1;
    +      }
    +      else
    +      {
    +         if(limindex > 4)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_quad( handle, &ctx->gradient[0], bbox, limindex );
    +         control &= ~D2C_SPANSTORE;
    +
    +         limindex += 2;
    +      }
    +   }
    +
    +   if(0 != (ctx->gradients & 2))
    +   {
    +      if(0 != (ctx->gradient[1].mode & d2_grad_linear))
    +      {
    +         if(limindex > 5)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_lin( handle, &ctx->gradient[1], bbox, limindex, control & D2C_LIMITERPRECISION );
    +         control &= ~D2C_SPANSTORE;
    +         if(0 != (ctx->gradient[1].mode & d2_grad_concave))
    +         {
    +            control &= ~D2C_SPANABORT;
    +         }
    +
    +         limindex += 1;
    +      }
    +      else
    +      {
    +         if(limindex > 4)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_quad( handle, &ctx->gradient[1], bbox, limindex );
    +         control &= ~D2C_SPANSTORE;
    +
    +         limindex += 2;
    +      }
    +   }
    +
    +   if( (0 != (ctx->alphamode & d2_am_gradient1)) && (0 != (ctx->gradients & 4)) )
    +   {
    +      if(0 != (ctx->gradient[2].mode & d2_grad_linear))
    +      {
    +         if(limindex > 5)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_lin( handle, &ctx->gradient[2], bbox, limindex, control & D2C_LIMITERPRECISION );
    +         control &= ~D2C_SPANSTORE;
    +
    +         limindex += 1;
    +      }
    +      else
    +      {
    +         if(limindex > 4)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_quad( handle, &ctx->gradient[2], bbox, limindex );
    +         control &= ~D2C_SPANSTORE;
    +
    +         limindex += 2;
    +      }
    +   }
    +
    +   if( (0 != (ctx->alphamode & d2_am_gradient2)) && (0 != (ctx->gradients & 8)) )
    +   {
    +      if(0 != (ctx->gradient[3].mode & d2_grad_linear))
    +      {
    +         if(limindex > 5)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_lin( handle, &ctx->gradient[3], bbox, limindex, control & D2C_LIMITERPRECISION );
    +         control &= ~D2C_SPANSTORE;
    +
    +         limindex += 1;
    +      }
    +      else
    +      {
    +         if(limindex > 4)
    +         {
    +            return control; /* assume 6limiter architecture */
    +         }
    +
    +         control |= d2_initgradient_quad( handle, &ctx->gradient[3], bbox, limindex );
    +         control &= ~D2C_SPANSTORE;
    +
    +         limindex += 2;
    +      }
    +   }
    +
    +   return control;
    +}
    diff --git a/src/drivers/dave2d/src/dave_hardware.c b/src/drivers/dave2d/src/dave_hardware.c
    new file mode 100644
    index 000000000..a4eec252b
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_hardware.c
    @@ -0,0 +1,180 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_hardware.c (%version: 18 %)
    + *          created Wed Aug 24 12:57:58 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Mar 08 15:05:38 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + *  2005-12-22 CSe  - d2hw_start():  added copy of dlist to vidmem
    + *                  - d2hw_finish(): added wait for dlist irq
    + *  2006-02-28 CSe  - d2hw_start():  added flush of dlist blocks
    + *  2006-04-12 CSe  - d2hw_start():  removed flush of complete data cache
    + *  2006-05-10 CSe  - d2hw_start():  added map of dlist for systems with
    + *                                   statically mapped vidmem
    + *  2006-10-30 CSe  - d2hw_finish(): changed waiting for dlist irq
    + *  2006-11-07 CSe  - d2hw_start():  changes for new 'd2_df_low_localmem' mode
    + *  2007-03-08 CSe  - d2hw_start():  moved copying and flushing of dlist to
    + *                                   d2_preparedlist_read_intern()
    + *  2007-08-29 ASc  - changed g_d1refcount and g_d1handle to static variables
    + *                    removed tabs, changed C++ to C comments
    + *  2010-11-25 MRe  - fixed d2hw_acquire for multiple calls in case of 
    + *                    multithreading
    + *  2011-02-07 SSt  - moved instance management for multithreading to d1 driver
    + *  2012-09-25 BSp  - MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_render.h"
    +
    +/*--------------------------------------------------------------------------
    + * */
    +d1_device * d2hw_acquire( d2_device *handle, d2_u32 flags )
    +{
    +   d1_device *d1handle;
    +
    +   d1handle = d1_opendevice( (d2_slong) flags );
    +
    +   if(NULL != d1handle)
    +   {
    +      D2_DEV(handle)->hwrevision = (d2_u32) d1_getregister( d1handle, D1_DAVE2D, D2_HWREVISION );
    +
    +      if(0 != (D2_DEV(handle)->hwrevision & D2FB_HILIMITERPRECISION))
    +      {
    +         D2_DEV(handle)->hilimiterprecision_supported = 1;
    +      }
    +
    +      if(0 == (D2_DEV(handle)->hwrevision & D2FB_DLR))
    +      {
    +         D2_DEV(handle)->flags |= d2_df_no_dlist;
    +      }
    +
    +      /* attention: don't change cache settings while HW is running -> added caution note in doc of d2_opendevice() */
    +      d1_setregister( d1handle, D1_DAVE2D, D2_CACHECTL, (d2_slong) D2_DEV(handle)->cachectlmask );
    +
    +      D2_DEV(handle)->hwmemarchitecture = (d2_u32) d1_queryarchitecture(d1handle);
    +   }
    +
    +   return d1handle;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +d2_s32 d2hw_release( d1_device * hwid )
    +{
    +   if(1 == d1_closedevice( hwid ))
    +   {
    +      return D2_OK;
    +   }
    +   else
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +void d2hw_set(d1_device * hwid, d2_u32 index, d2_s32 value)
    +{
    +   d1_setregister( hwid, D1_DAVE2D, (d2_s32)index, value );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +d2_s32 d2hw_get(d1_device * hwid, d2_u32 index)
    +{
    +   return d1_getregister( hwid, D1_DAVE2D, (d2_s32)index );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +void d2hw_wait(d1_device * hwid)
    +{
    +   /* wait for enum ready state */
    +   while(0 != ((d2_u32)d1_getregister( hwid, D1_DAVE2D, D2_STATUS ) & D2C_BUSY_ENUM) )
    +   {}
    +}
    +
    +
    +/*---------------------------------------------------------------------------
    + * return only after all rendering has finished
    + * */
    +void d2hw_finish(const d2_device *handle)
    +{
    +   d1_device * hwId = (d1_device *) D2_DEV(handle)->hwid;
    +
    +   if(0 != (D2_DEV(handle)->flags & d2_df_no_dlist))
    +   {
    +      /* wait for ready state */
    +      while(0 != ((d2_u32)d1_getregister( hwId, D1_DAVE2D, D2_STATUS ) & ( D2C_BUSY_ENUM | D2C_BUSY_WRITE )))
    +      {}
    +   }
    +   else
    +   {
    +      /* wait for dlist finish signal */
    +      while(0 != ((d2_u32)d1_getregister( hwId, D1_DAVE2D, D2_STATUS ) & D2C_DLISTACTIVE))
    +      {
    +         if(0 == (D2_DEV(handle)->flags & d2_df_no_irq))
    +         {
    +            /* don't wait forever in case another driver instance is scheduled between
    +             * the register check and the wait for the irq and takes the event */
    +            (void)d1_queryirq(hwId, d1_irq_dlist, 200);
    +         }
    +      }
    +   }
    +}
    +
    +/*---------------------------------------------------------------------------
    + * start rendering primitives
    + * */
    +void d2hw_start( d2_device *handle, const d2_dlist *dlist, d2_s32 startnoblk )
    +{
    +   d2_devicedata  *dev        = D2_DEV(handle);
    +   d1_device      *id         = D2_DEV(handle)->hwid;
    +   d2_dlist_block *blk        = dlist->firstblock;
    +   d2_s32         *dlist_list = (d2_s32 *) dlist->dlist_addresses;
    +
    +   if(0 != (dev->flags & d2_df_no_dlist))
    +   {
    +      /* emulated display list processing */
    +
    +      /* note that no video memory has been allocated to store dlists */
    +
    +      if(0 != startnoblk)
    +      {
    +         /* we come from d2_executedlist */
    +         (void)d2_executedlist_intern(handle, (d2_dlist_entry *)*dlist_list);
    +      }
    +      else
    +      {
    +         while(NULL != blk)
    +         {
    +            d2_dlist_entry *pos = blk->block;
    +
    +            if(3 == d2_executedlist_intern(handle, pos))
    +            {
    +               break;
    +            }
    +
    +            blk = blk->next;
    +         }
    +      }
    +
    +      return;
    +   }
    +
    +   if(0 != dlist_list[0])
    +   {
    +      if(0 != dev->dlist_indirect_supported)
    +      {
    +         d2hw_set( id, D2_DLISTSTART , (d2_s32)&dlist_list[0] );
    +      }
    +      else
    +      {
    +         d2hw_set( id, D2_DLISTSTART , dlist_list[0] );
    +      }
    +   }
    +
    +}
    diff --git a/src/drivers/dave2d/src/dave_line.c b/src/drivers/dave2d/src/dave_line.c
    new file mode 100644
    index 000000000..ae66dee13
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_line.c
    @@ -0,0 +1,1455 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_line.c (%version: 40 %)
    + *          created Mon Jan 31 16:49:01 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Mar 08 14:52:36 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2007-03-08 NSc  fixed incorrect blurring of lines
    + *  2008-01-02 ASc  fixed drawing lines with width=0
    + *  2008-01-14 ASc  fixed bug in d2_renderline_intern_split
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2011-01-20 SSt  made lines and polylines thread safe (eliminated globals)
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_viewport.h"
    +#include "dave_render.h"
    +#include "dave_pattern.h"
    +#include "dave_line.h"
    +#include "dave_circle.h"
    +#include "dave_edge.h"
    +#include "dave_curve.h"
    +#include "dave_texture.h"
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags, d2_limdata *edge_buffer, d2_bbox *edge_bbox, const d2_s32 *connectors)
    +{
    +   d2_bbox bbox, bbox2;
    +   d2_limdata edge[4];
    +   d2_width wh, er;
    +   d2_s32 w16;
    +   d2_u32 control;
    +   d2_u32 tmask;
    +   d2_s32 flip, h, swt, miter, len;
    +   d2_u32 cap;
    +
    +   /* find deltas */
    +   d2_s32 dx = x2 - x1;
    +   d2_s32 dy = y2 - y1;
    +
    +   if(0 == (dx | dy))           /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $ */
    +   {
    +      return 0;
    +   }
    +
    +   cap = ctx->linecap;
    +
    +   /* find bounding box */
    +   wh = (d2_width)((w + 15) >> 1);          /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   if(d2_lc_square == cap)
    +   {
    +      /* increase bbox for square ends */
    +      if( (flags & d2_le_exclude_both) != d2_le_exclude_both )
    +      {
    +         /* scale halfwidth by sqrt(2) */
    +         wh = (d2_width)((wh * 23) >> 4);   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      }
    +   }
    +
    +   if(0 != (flags & d2_lei_miter_edge))
    +   {
    +      if(d2_lj_bevel == ctx->linejoin)
    +      {
    +         /* scale halfwidth by 1.25 */
    +         wh = (d2_width)((wh * 20) >> 4);   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         miter = (w >> 1) << (16 - 4); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +      else
    +      {
    +         miter = (ctx->miterlimit + (w >> 1)) << (16 - 4); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         wh = (d2_width)( ((ctx->miterlimit + (w >> 1)) * 20) >> 4 ); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      }
    +   }
    +   else
    +   {
    +      miter = 0;
    +   }
    +
    +   if(dx > 0)
    +   {
    +      bbox.xmin = (d2_point) D2_FLOOR4( x1 - wh );
    +      bbox.xmax = (d2_point) D2_CEIL4( x2 + wh );
    +   }
    +   else
    +   {
    +      bbox.xmin = (d2_point) D2_FLOOR4( x2 - wh );
    +      bbox.xmax = (d2_point) D2_CEIL4( x1 + wh );
    +   }
    +
    +   if(dy > 0)
    +   {
    +      bbox.ymin = (d2_point) D2_FLOOR4( y1 - wh );
    +      bbox.ymax = (d2_point) D2_CEIL4( y2 + wh );
    +   }
    +   else
    +   {
    +      bbox.ymin = (d2_point) D2_FLOOR4( y2 - wh );
    +      bbox.ymax = (d2_point) D2_CEIL4( y1 + wh );
    +   }
    +
    +   /* clipping */
    +   if(0 == d2_clipbbox_intern( handle, &bbox ))
    +   {
    +      return 0;
    +   }
    +
    +   /* make relative (dont need relative endpoint) */
    +   x1 = (d2_point)(x1 - bbox.xmin);
    +   y1 = (d2_point)(y1 - bbox.ymin);
    +
    +   /* don't use round endpoints on very small lines */
    +   if(w < D2_FIX4(3))
    +   {
    +      if(d2_lc_round == cap)
    +      {
    +         cap = d2_lc_square;
    +      }
    +   }
    +
    +   /* don't consider endpoint style if both are omitted */
    +   if( (flags & d2_le_exclude_both) == d2_le_exclude_both )
    +   {
    +      cap = d2_lc_butt;
    +   }
    +
    +   /* calc edge interpolation parameters */
    +   if( (ctx->features & (d2_feat_blur | d2_feat_aa)) == (d2_feat_blur | d2_feat_aa) )
    +   {
    +      /* using special setup for blurred lines */
    +      d2_lineedge_setup3blur_intern( edge, x1, y1, dx, dy, flags, ctx, &len );
    +      w16 = (w * (d2_s32)ctx->invblur) >> 4;         /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      edge[0].start += w16 >> 1;             /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +      /* apply linecap */
    +      if(d2_lc_square == cap)
    +      {
    +         if(0 == (flags & d2_le_exclude_start))
    +         {
    +            edge[1].start += w16 >> 1;       /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         }
    +
    +         if(0 == (flags & d2_le_exclude_end))
    +         {
    +            edge[2].start += w16 >> 1;       /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         }
    +      }
    +
    +      w16 += (d2_s32)(ctx->invblur >> 1) - 65536;
    +   }
    +   else
    +   {
    +      /* using sqrt setup for wide lines (note: reduce threshold to 1?) */
    +      if(w < D2_FIX4(2))
    +      {
    +         d2_lineedge_setup3_intern( edge, x1, y1, dx, dy, flags, &len );
    +      }
    +      else
    +      {
    +         d2_lineedge_setup3sqrt_intern( edge, x1, y1, dx, dy, flags, &len );
    +      }
    +
    +      w16 = w << (16 - 4);                  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      edge[0].start += (w16 >> 1);          /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +      /* apply linecap */
    +      if(d2_lc_square == cap)
    +      {
    +         if(0 == (flags & d2_le_exclude_start))
    +         {
    +            edge[1].start += (w16 - D2_FIX16(1)) >> 1;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         }
    +
    +         if(0 == (flags & d2_le_exclude_end))
    +         {
    +            edge[2].start += (w16 - D2_FIX16(1)) >> 1;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         }
    +      }
    +   }
    +
    +   /* set register values (material parameters) */
    +   d2_setupmaterial_intern( handle, ctx );
    +   tmask = ctx->thresholdmask;
    +
    +   /* determine rendering direction */
    +   if( ((dy > 0) && (dx < 0)) || ((dy < 0) && (dx > 0)) )
    +   {
    +      flip = 1;
    +   }
    +   else
    +   {
    +      flip = 0;
    +   }
    +
    +   control = 
    +      D2C_LIM1ENABLE  | 
    +      D2C_LIM2ENABLE  | 
    +      D2C_LIM5ENABLE  |
    +      D2C_BAND1ENABLE | 
    +      (tmask & (D2C_LIM1THRESHOLD | D2C_LIM2THRESHOLD | D2C_LIM5THRESHOLD)) |
    +      D2C_SPANABORT   | 
    +      D2C_SPANSTORE   ;
    +
    +   /* check for alpha gradients */
    +   if(0 != (ctx->alphamode & (d2_am_gradient1 | d2_am_gradient2)))
    +   {
    +      d2_u32 gidx;
    +
    +      if(d2_lc_round != cap)
    +      {
    +         gidx = 2;   /* put gradients on limiters 3&4 for nonround lines */
    +      }
    +      else
    +      {
    +         gidx = 5;   /* put gradients on limiter 6 for rounded lines */
    +      }
    +
    +      if(0 != (flags & d2_lei_miter_edge))
    +      {
    +         gidx = 5;   /* keep limiters 3&4 free for miter limiters */
    +      }
    +
    +      control = d2_initgradients_intern( handle, ctx, &bbox, gidx, control );
    +
    +      if(0 == (control & D2C_SPANSTORE))
    +      {
    +         flip = 0;
    +      }
    +   }
    +
    +   /* pattern autoalign */
    +   if(0 != (ctx->patmode & d2_pm_autoalign))
    +   {
    +      d2_gradientdata *grad;
    +
    +      grad = & ctx->patulim[0];
    +      ctx->internaldirty |= d2_dirty_upatlim;
    +
    +      grad->mode = d2_grad_linear | d2_grad_aapattern;
    +      grad->x1 = x1;
    +      grad->y1 = y1;
    +
    +      if(0 != (ctx->patmode & d2_pm_orthogonal))
    +      {
    +         grad->xadd = (edge[1].yadd << 4) / ctx->patscale;   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         grad->yadd = (-edge[1].xadd << 4) / ctx->patscale;  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +      else
    +      {
    +         grad->xadd = (edge[1].xadd << 4) / ctx->patscale;   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         grad->yadd = (edge[1].yadd << 4) / ctx->patscale;   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +      grad->xadd2 = ctx->patoffset << (16 - 4);              /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +      /* pattern auto advance */
    +      if(0 != (ctx->patmode & d2_pm_advance))
    +      {
    +         ctx->patoffset += (len << 4) / ctx->patscale;       /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +   }
    +
    +   /* output texture and pattern setup */
    +   d2_setuppattern( handle, ctx, &bbox, flip );
    +   d2_setuptexture( handle, ctx, &bbox, flip );
    +
    +   /* include first round end */
    +   if(d2_lc_round == cap)
    +   {
    +      d2_point x,y;
    +
    +      /* endpoint radius */
    +      er = (d2_width)((w + D2_FIX4(1)) >> 1);           /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +      if(0 != (flags & d2_le_exclude_start))
    +      {
    +         /* endpoint (no second part) */
    +         if(0 != flip)
    +         {
    +            x = (d2_point)(x2 - bbox.xmin);
    +            y = (d2_point)(bbox.ymax - y2);
    +         }
    +         else
    +         {
    +            x = (d2_point)(x2 - bbox.xmin);
    +            y = (d2_point)(y2 - bbox.ymin);
    +         }
    +
    +         /* no need to consider round ends anymore */
    +         cap = d2_lc_butt;
    +         swt = 1;
    +      }
    +      else
    +      {
    +         /* startpoint */
    +         if(0 != flip)
    +         {
    +            x = x1;
    +            y = (d2_point)((bbox.ymax - bbox.ymin) - y1);
    +         }
    +         else
    +         {
    +            x = x1;
    +            y = y1;
    +         }
    +
    +         if(0 != (flags & d2_le_exclude_end))
    +         {
    +            /* no second part */
    +            cap = d2_lc_butt;
    +         }
    +         else
    +         {
    +            /* shared edge at endpoint (endpoint rendered as second part) */
    +            control |= D2C_LIM5THRESHOLD;
    +         }
    +         swt = 0;
    +      }
    +
    +      /* check endpoint clipping to avoid 'far off' endpoints */
    +      if( ((x + (er*2)) > 0) &&
    +          ((y + (er*2)) > 0) &&
    +          ((x - (er*2)) < (bbox.xmax - bbox.xmin)) &&
    +          ((y - (er*2)) < (bbox.ymax - bbox.ymin))
    +          )
    +      {
    +         /* round endpoint limiter setup */
    +         d2_circlesetup_intern( handle, ctx, 2, x, y, er, 0, 0, 0);
    +
    +         /* include l3/l4 */
    +         control |= D2C_LIM3ENABLE | D2C_QUAD2ENABLE | D2C_UNIONAB | (tmask & D2C_LIM3THRESHOLD);
    +         /* update cache for circular rendering */
    +      }
    +   }
    +   else
    +   {
    +      swt = 0;
    +      /* just to shutup compiler */
    +      er = 0;
    +   }
    +
    +   /* disable antialiasing for excluded endpoints */
    +   if(0 != (flags & d2_le_exclude_start))
    +   {
    +      if(0 == swt)
    +      {
    +         control |= D2C_LIM2THRESHOLD;
    +      }
    +      else
    +      {
    +         control |= D2C_LIM5THRESHOLD;
    +      }
    +
    +      if(0 != (flags & d2_lei_ext_first_edge))
    +      {
    +         /* use external edge */
    +         d2_triedge_setupnoaa_intern(&edge[1], x1, y1, connectors[0], connectors[1], 0 );
    +         wh = (d2_width)(wh*2); /* expand span delay (experimental) */   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +      else
    +      {
    +         /* keep original edge */
    +         edge[1].start += D2_FIX16(1) >> 1;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         /* rightedge flags */
    +         if(dy > 0)
    +         {
    +            edge[1].start += D2_EPSILON;
    +         }
    +      }
    +   }
    +
    +   if(0 != (flags & d2_le_exclude_end))
    +   {
    +      if(0 != swt)
    +      {
    +         control |= D2C_LIM2THRESHOLD;
    +      }
    +      else
    +      {
    +         control |= D2C_LIM5THRESHOLD;
    +      }
    +
    +      if(0 != (flags & d2_lei_ext_last_edge))
    +      {
    +         /* use external edge */
    +         d2_triedge_setupnoaa_intern(&edge[2], (d2_point)(x2 - bbox.xmin), (d2_point)(y2 - bbox.ymin), -connectors[2], -connectors[3], 1 );
    +         wh = (d2_width)(wh*2); /* expand span delay (experimental) */   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +      else
    +      {
    +         /* keep original edge */
    +         edge[2].start += D2_FIX16(1) >> 1;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         /* rightedge flags */
    +         if(dy <= 0)
    +         {
    +            edge[2].start += D2_EPSILON;
    +         }
    +      }
    +   }
    +
    +   /* store edges if requested */
    +   if(0 != (flags & (d2_lei_buffer_first_edge | d2_lei_buffer_last_edge)))
    +   {
    +      if(0 != (flags & d2_lei_buffer_first_edge))
    +      {
    +         edge_buffer[0] = edge[1];
    +      }
    +
    +      if(0 != (flags & d2_lei_buffer_last_edge))
    +      {
    +         edge_buffer[1] = edge[2];
    +      }
    +
    +      *edge_bbox = bbox;
    +   }
    +
    +   /* optimize for span abort / span store */
    +   if(0 != flip)
    +   {
    +      h = D2_INT4( bbox.ymax - bbox.ymin );   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      d2_invertlimiter_intern(&edge[0], h);
    +      d2_invertlimiter_intern(&edge[1], h);
    +      d2_invertlimiter_intern(&edge[2], h);
    +   }
    +   else
    +   {
    +      /* just to shutup compiler */
    +      h = 0;
    +   }
    +
    +   /* add miter edges if requested */
    +   if(0 != (flags & d2_lei_miter_edge))
    +   {
    +      /* miter outward shift to avoid line cutting into itself at 180� */
    +      miter += D2_FIX16(1);
    +
    +      if( (0 != (flags & d2_lei_ext_first_edge)) && (0 != (connectors[0] | connectors[1])) ) /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $ */
    +      {
    +         /* add first edge miter limit (L3) */
    +         control |= D2C_LIM3ENABLE | (tmask & D2C_LIM3THRESHOLD);
    +
    +         /* could be extracted from edge[1], but edge1 is not normalized */
    +         d2_triedge_setupsqrt_intern(&edge[3], x1, y1, -connectors[1], connectors[0], 0 );
    +
    +         if(0 != flip)
    +         {
    +            d2_invertlimiter_intern(&edge[3], h);
    +         }
    +
    +         if(0 == (flags & d2_lei_miter1_flip))
    +         {
    +            D2_DLISTWRITES( D2_L3START, edge[3].start + miter );
    +            D2_DLISTWRITES( D2_L3XADD , edge[3].xadd );
    +            D2_DLISTWRITES( D2_L3YADD , edge[3].yadd );
    +         }
    +         else
    +         {
    +            D2_DLISTWRITES( D2_L3START, -edge[3].start + miter );
    +            D2_DLISTWRITES( D2_L3XADD , -edge[3].xadd );
    +            D2_DLISTWRITES( D2_L3YADD , -edge[3].yadd );
    +         }
    +      }
    +
    +      if( (0 != (flags & d2_lei_ext_last_edge)) && (0 != (connectors[2] | connectors[3])) ) /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $ */
    +      {
    +         /* add last edge miter limit (L4) */
    +         control |= D2C_LIM4ENABLE | (tmask & D2C_LIM4THRESHOLD);
    +
    +         /* could be extracted from edge[2], but edge2 is not normalized */
    +         d2_triedge_setupsqrt_intern(&edge[3], (d2_point)(x2 - bbox.xmin), (d2_point)(y2 - bbox.ymin), -connectors[3], connectors[2], 0 );
    +
    +         if(0 != flip)
    +         {
    +            d2_invertlimiter_intern(&edge[3], h);
    +         }
    +
    +         if(0 != (flags & d2_lei_miter2_flip))
    +         {
    +            D2_DLISTWRITES( D2_L4START, edge[3].start + miter );
    +            D2_DLISTWRITES( D2_L4XADD , edge[3].xadd );
    +            D2_DLISTWRITES( D2_L4YADD , edge[3].yadd );
    +         }
    +         else
    +         {
    +            D2_DLISTWRITES( D2_L4START, -edge[3].start + miter );
    +            D2_DLISTWRITES( D2_L4XADD , -edge[3].xadd );
    +            D2_DLISTWRITES( D2_L4YADD , -edge[3].yadd );
    +         }
    +      }
    +   }
    +
    +   /* set register values (geometric parameters) */
    +   D2_DLISTWRITES( D2_L1START, edge[0].start );
    +   D2_DLISTWRITES( D2_L1XADD , edge[0].xadd );
    +   D2_DLISTWRITES( D2_L1YADD , edge[0].yadd );
    +
    +   if(0 != swt)
    +   {
    +      /* endpoint limiter must be in first group */
    +      D2_DLISTWRITES( D2_L5START, edge[1].start );
    +      D2_DLISTWRITES( D2_L5XADD , edge[1].xadd );
    +      D2_DLISTWRITES( D2_L5YADD , edge[1].yadd );
    +      D2_DLISTWRITES( D2_L2START, edge[2].start );
    +      D2_DLISTWRITES( D2_L2XADD , edge[2].xadd );
    +      D2_DLISTWRITES( D2_L2YADD , edge[2].yadd );
    +   }
    +   else
    +   {
    +      /* startpoint limiter must be in first group */
    +      D2_DLISTWRITES( D2_L2START, edge[1].start );
    +      D2_DLISTWRITES( D2_L2XADD , edge[1].xadd );
    +      D2_DLISTWRITES( D2_L2YADD , edge[1].yadd );
    +      D2_DLISTWRITES( D2_L5START, edge[2].start );
    +      D2_DLISTWRITES( D2_L5XADD , edge[2].xadd );
    +      D2_DLISTWRITES( D2_L5YADD , edge[2].yadd );
    +   }
    +
    +   D2_DLISTWRITES( D2_L1BAND , w16 );
    +
    +   D2_DLISTWRITEU( D2_CONTROL, control );
    +
    +   /* span delay height is approximated by linewidth */
    +   w = (d2_width)(D2_INT4((wh + ((w + 15) >> 1)) + 15));   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   if(0 != flip)
    +   {
    +      d2_startrender_bottom_intern( handle, &bbox, (d2_u32)w );
    +   }
    +   else
    +   {
    +      d2_startrender_intern( handle, &bbox, (d2_u32)w );
    +   }
    +
    +   /* include second round end */
    +   if(d2_lc_round == cap)
    +   {
    +      /* new bbox */
    +      bbox2.xmin = (d2_point) D2_FLOOR4( x2 - er );
    +      bbox2.ymin = (d2_point) D2_FLOOR4( y2 - er );
    +      bbox2.xmax = (d2_point) D2_CEIL4( x2 + er );
    +      bbox2.ymax = (d2_point) D2_CEIL4( y2 + er );
    +
    +      /* clip endpoint bbox */
    +      if(0 == d2_clipbbox_intern( handle, &bbox2 ))
    +      {
    +         return 1;
    +      }
    +
    +      /* make relative */
    +      x2 = (d2_point)(x2 - bbox2.xmin);
    +      y2 = (d2_point)(y2 - bbox2.ymin);
    +
    +      /* circle limiters */
    +      d2_circlesetup_intern(handle, ctx, 0, x2, y2, er, 0, 0, 0);
    +
    +      /* new control word */
    +      control = 
    +         D2C_LIM1ENABLE              | 
    +         D2C_QUAD1ENABLE             | 
    +         D2C_LIM3ENABLE              | 
    +         (tmask & D2C_LIM1THRESHOLD) | 
    +         D2C_LIM3THRESHOLD           | 
    +         D2C_SPANABORT               ;
    +
    +      /* restore UV and alpha limiters to fit new bbox */
    +      d2_setuppattern( handle, ctx, &bbox2, 0 );
    +      d2_setuptexture( handle, ctx, &bbox2, 0 );
    +
    +      if(0 != (ctx->alphamode & (d2_am_gradient1 | d2_am_gradient2)))
    +      {
    +         control = d2_initgradients_intern( handle, ctx, &bbox2, 3, control );
    +      }
    +
    +      /* restore seperation limiter to fit new bbox */
    +      if(0 != flip)
    +      {
    +         dx = D2_INT4(bbox2.xmin - bbox.xmin);       /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         dy = D2_INT4(bbox2.ymin - bbox.ymin) - h;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         edge[2].yadd = -edge[2].yadd;
    +      }
    +      else
    +      {
    +         dx = D2_INT4(bbox2.xmin - bbox.xmin);       /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         dy = D2_INT4(bbox2.ymin - bbox.ymin);       /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      }
    +
    +      /* D2_DLISTWRITES( D2_L3START, -edge[2].start - (dx * edge[2].xadd) - (dy * edge[2].yadd) + D2_FIX16(1) + D2_EPSILON ); */
    +      D2_DLISTWRITES( D2_L3START, 
    +                      (
    +                         (
    +                            (-edge[2].start - (dx * edge[2].xadd))
    +                            - (dy * edge[2].yadd)
    +                          )
    +                         + D2_FIX16(1)              /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +                       )
    +                      + D2_EPSILON
    +                      );
    +      D2_DLISTWRITES( D2_L3XADD , -edge[2].xadd );
    +      D2_DLISTWRITES( D2_L3YADD , -edge[2].yadd );
    +
    +      D2_DLISTWRITEU( D2_CONTROL, control );
    +
    +      d2_startrender_intern( handle, &bbox2, (d2_u32) (w >> 4) );  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline2_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags, d2_limdata *edge_buffer, d2_bbox *edge_bbox )
    +{
    +   d2_bbox bbox, bbox2;
    +   d2_limdata edge[4];
    +   d2_s32 r, l, dlx, dly, nx, ny, h;
    +   d2_s32 w1x, w1y, w2x, w2y, xs, ys, xe, ye, xp, yp;
    +   d2_s32 ax, ay, bx, by, cx, cy, dx, dy;
    +   d2_s32 t1, t2, flip, cap2;
    +   d2_u32 delay;
    +   d2_u32 cap;
    +   d2_u32 control;
    +   d2_u32 tmask;
    +
    +   /* check for parallel lines
    +    *if (w1 == w2) return d2_renderline_intern( handle, ctx, x1,y1, x2,y2, w1, d2_include_both ); */
    +
    +   /* find deltas */
    +   dlx = x2 - x1;
    +   dly = y2 - y1;
    +   if(0 == (dlx | dly))    /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +   {
    +      return 0;
    +   }
    +
    +   cap = ctx->linecap;
    +
    +   l = (65536 * 256) / d2_sqrt( (d2_u32) ( (dlx * dlx) + (dly * dly) ) );
    +
    +   nx = (-dly * l) >> 8;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ 
    +   ny = ( dlx * l) >> 8;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /*
    +     {
    +     // accurate calculation
    +     l = d2_sqrt( dlx*dlx + dly*dly );
    +     nx = (int) (((d2_int64)-dly * 65536) / l);
    +     ny = (int) (((d2_int64) dlx * 65536) / l);
    +     }
    +   */
    +
    +   /* find outer endpoints */
    +   w1x = ((nx * w1) >> 1) >> 16;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   w1y = ((ny * w1) >> 1) >> 16;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   w2x = ((nx * w2) >> 1) >> 16;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   w2y = ((ny * w2) >> 1) >> 16;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   ax = x1 + w1x;
    +   ay = y1 + w1y;
    +   bx = x2 + w2x;
    +   by = y2 + w2y;
    +   cx = x2 - w2x;
    +   cy = y2 - w2y;
    +   dx = x1 - w1x;
    +   dy = y1 - w1y;
    +
    +   /* don't render round endpoints on small lines */
    +   if(d2_lc_round == cap)
    +   {
    +      if(w1 < D2_FIX4(3))        /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      {
    +         flags |= d2_le_exclude_start;
    +      }
    +
    +      if(w2 < D2_FIX4(3))        /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      {
    +         flags |= d2_le_exclude_end;
    +      }
    +   }
    +
    +   /* simplify caps if no endpoints */
    +   if(d2_le_exclude_both == (flags & d2_le_exclude_both))
    +   {
    +      cap = d2_lc_butt;
    +   }
    +
    +   /* expand bbox to contain caps */
    +   if(d2_lc_square == cap)
    +   {
    +      if(0 == (flags & d2_le_exclude_start))
    +      {
    +         ax -= w1y;  ay -= -w1x;
    +         dx -= w1y;  dy -= -w1x;
    +      }
    +
    +      if(0 == (flags & d2_le_exclude_end))
    +      {
    +         bx += w2y;  by += -w2x;
    +         cx += w2y;  cy += -w2x;
    +      }
    +   }
    +
    +   /* find bounding box */
    +   t1 = (ax < bx) ? ax : bx;
    +   t2 = (cx < dx) ? cx : dx;
    +   bbox.xmin = (d2_point) D2_FLOOR4( (t1 < t2) ? t1 : t2 );
    +   t1 = (ax > bx) ? ax : bx;
    +   t2 = (cx > dx) ? cx : dx;
    +   bbox.xmax = (d2_point) D2_CEIL4( (t1 > t2) ? t1 : t2 );
    +   t1 = (ay < by) ? ay : by;
    +   t2 = (cy < dy) ? cy : dy;
    +   bbox.ymin = (d2_point) D2_FLOOR4( (t1 < t2) ? t1 : t2 );
    +   t1 = (ay > by) ? ay : by;
    +   t2 = (cy > dy) ? cy : dy;
    +   bbox.ymax = (d2_point) D2_CEIL4( (t1 > t2) ?  t1 : t2 );
    +
    +   /* clipping */
    +   if(0 == d2_clipbbox_intern( handle, &bbox ))
    +   {
    +      return 0;
    +   }
    +
    +   /* store original endpoints */
    +   xs = x1; ys = y1;
    +   xe = x2; ye = y2;
    +
    +   /* make relative */
    +   x1 = (d2_point)(x1 - bbox.xmin);
    +   y1 = (d2_point)(y1 - bbox.ymin);
    +   x2 = (d2_point)(x2 - bbox.xmin);
    +   y2 = (d2_point)(y2 - bbox.ymin);
    +
    +   /* calc edge interpolation parameters */
    +   edge[0].start = (( (y1 * nx) - (x1 * ny) ) >> 4) + D2_FIX16(1);   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   edge[0].xadd  = ny;
    +   edge[0].yadd  = -nx;
    +   edge[1].start = (( (x2 * ny) - (y2 * nx) ) >> 4) + (D2_FIX16(1) >> 1);  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   edge[1].xadd  = -ny;
    +   edge[1].yadd  = nx;
    +
    +   /* side parameters */
    +   if((ctx->features & (d2_feat_blur | d2_feat_aa)) == (d2_feat_blur | d2_feat_aa))
    +   {
    +      d2_triedge_setupblur_intern( &edge[2], (d2_point)(ax - bbox.xmin), (d2_point)(ay - bbox.ymin), (ax - bx), (ay - by), ctx );
    +      d2_triedge_setupblur_intern( &edge[3], (d2_point)(dx - bbox.xmin), (d2_point)(dy - bbox.ymin), (cx - dx), (cy - dy), ctx );
    +   }
    +   else
    +   {
    +      d2_triedge_setup_intern( &edge[2], (d2_point)(ax - bbox.xmin), (d2_point)(ay - bbox.ymin), (ax - bx), (ay - by), 0 );
    +      d2_triedge_setup_intern( &edge[3], (d2_point)(dx - bbox.xmin), (d2_point)(dy - bbox.ymin), (cx - dx), (cy - dy), 0 );
    +      edge[2].start += (D2_FIX16(1) >> 1);  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      edge[3].start += (D2_FIX16(1) >> 1);  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   /* apply linecap */
    +   if(d2_lc_square == cap)
    +   {
    +      if(0 == (flags & d2_le_exclude_start))
    +      {
    +         edge[0].start += ((w1 << (16 - 4)) - D2_FIX16(1)) >> 1;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +
    +      if(0 == (flags & d2_le_exclude_end))
    +      {
    +         edge[1].start += ((w2 << (16 - 4)) - D2_FIX16(1)) >> 1;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +   }
    +
    +   /* set register values (material parameters) */
    +   d2_setupmaterial_intern( handle, ctx );
    +
    +   /* determine sharing flags */
    +   tmask = ctx->thresholdmask;
    +
    +   if(d2_lc_round == cap)
    +   {
    +      if(0 == (flags & d2_le_exclude_start))
    +      {
    +         tmask |= D2C_LIM1THRESHOLD;
    +      }
    +
    +      if(0 == (flags & d2_le_exclude_end))
    +      {
    +         tmask |= D2C_LIM2THRESHOLD;
    +      }
    +   }
    +
    +   /* pattern autoalign */
    +   if(0 != (ctx->patmode & d2_pm_autoalign))
    +   {
    +      d2_gradientdata *grad;
    +
    +      grad = & ctx->patulim[0];
    +      ctx->internaldirty |= d2_dirty_upatlim;
    +
    +      grad->mode = d2_grad_linear | d2_grad_aapattern;
    +      grad->x1 = x1;
    +      grad->y1 = y1;
    +
    +      if(0 != (ctx->patmode & d2_pm_orthogonal))
    +      {
    +         grad->xadd = (edge[0].yadd << 4) / ctx->patscale;   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         grad->yadd = (-edge[0].xadd << 4) / ctx->patscale;  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +      else
    +      {
    +         grad->xadd = (edge[0].xadd << 4) / ctx->patscale;   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         grad->yadd = (edge[0].yadd << 4) / ctx->patscale;   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +
    +      grad->xadd2 = ctx->patoffset << (16 - 4);              /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +      /* pattern auto advance */
    +      if(0 != (ctx->patmode & d2_pm_advance))
    +      {
    +         ctx->patoffset += (l << 4) / ctx->patscale;         /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      }
    +   }
    +
    +   /* determine rendering direction */
    +   if((dy - cy) > 0)
    +   {
    +      dlx = dx - cx;
    +      dly = dy - cy;
    +   }
    +   else
    +   {
    +      dlx = ax - bx;
    +      dly = ay - by;
    +   }
    +
    +   if( ((dly > 0) && (dlx < 0)) || ((dly < 0) && (dlx > 0)) )
    +   {
    +      flip = 1;
    +
    +      d2_setuppattern( handle, ctx, &bbox, 1 );
    +      d2_setuptexture( handle, ctx, &bbox, 1 );
    +
    +      /* find offset from endpoint to bbox border */
    +      if(ys > ye)
    +      {
    +         delay = (d2_u32) (bbox.ymax - ys);
    +      }
    +      else
    +      {
    +         delay = (d2_u32) (bbox.ymax - ye);
    +      }
    +   }
    +   else
    +   {
    +      flip = 0;
    +
    +      d2_setuppattern( handle, ctx, &bbox, 0 );
    +      d2_setuptexture( handle, ctx, &bbox, 0 );
    +
    +      /* find offset from endpoint to bbox border */
    +      if(ys > ye)
    +      {
    +         delay = (d2_u32) (ye - bbox.ymin);
    +      }
    +      else
    +      {
    +         delay = (d2_u32) (ys - bbox.ymin);
    +      }
    +   }
    +
    +   delay += (d2_u32) ( ((w1 > w2) ? w1 : w2) >> 4 );        /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   control = 
    +      D2C_LIM1ENABLE | 
    +      D2C_LIM2ENABLE | 
    +      D2C_LIM3ENABLE | 
    +      D2C_LIM4ENABLE |
    +      (tmask & (D2C_LIM1THRESHOLD|D2C_LIM2THRESHOLD|D2C_LIM3THRESHOLD|D2C_LIM4THRESHOLD)) |
    +      D2C_SPANABORT  | 
    +      D2C_SPANSTORE  ;
    +
    +   /* check for alpha gradients */
    +   if(0 != (ctx->alphamode & (d2_am_gradient1 | d2_am_gradient2)))
    +   {
    +      control = d2_initgradients_intern( handle, ctx, &bbox, 4, control );
    +
    +      if(0 == (control & D2C_SPANSTORE))
    +      {
    +         flip = 0;
    +      }
    +   }
    +
    +   /* find most important endpoint */
    +   if(0 != (flags & d2_le_exclude_start))
    +   {
    +      /* render only endpoint */
    +      r = w2 >> 1;                             /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      xp = xe;
    +      yp = ye;
    +      l = 1;
    +      cap2 = 0;
    +   }
    +   else if (0 != (flags & d2_le_exclude_end))
    +   {
    +      /* render only startpoint */
    +      r = w1 >> 1;                             /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      xp = xs;
    +      yp = ys;
    +      l = 0;
    +      cap2 = 0;
    +   }
    +   else
    +   {
    +      /* need to render both points */
    +      cap2 = 1;
    +      if(w1 > w2)
    +      {
    +         /* startpoint  first */
    +         r = w1 >> 1;                          /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         xp = xs;
    +         yp = ys;
    +         l = 0;
    +      }
    +      else
    +      {
    +         /* endpoint first */
    +         r = w2 >> 1;                          /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         xp = xe;
    +         yp = ye;
    +         l = 1;
    +      }
    +   }
    +
    +   /* store outer edge if needed by cap later */
    +   if(0 != cap2)
    +   {
    +      edge_buffer[0] = edge[(d2_u32)l ^ 1u];
    +      *edge_bbox = bbox;
    +   }
    +
    +   /* optimize for span abort / span store */
    +   if(0 != flip)
    +   {
    +      h = D2_INT4( bbox.ymax - bbox.ymin );   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      d2_invertlimiter_intern(&edge[0], h);
    +      d2_invertlimiter_intern(&edge[1], h);
    +      d2_invertlimiter_intern(&edge[2], h);
    +      d2_invertlimiter_intern(&edge[3], h);
    +   }
    +   else
    +   {
    +      h = 0;
    +   }
    +
    +   D2_DLISTWRITEU( D2_CONTROL, control );
    +
    +   /* late blur adjustments */
    +   if( ((ctx->features & (d2_feat_blur | d2_feat_aa)) == (d2_feat_blur | d2_feat_aa)) && (cap != d2_lc_round) )
    +   {
    +      if(0 == (tmask & D2C_LIM1THRESHOLD))
    +      {
    +         edge[0].start = ((edge[0].start*16) / ctx->blurring);
    +         edge[0].xadd  = ((edge[0].xadd*16)  / ctx->blurring);
    +         edge[0].yadd  = ((edge[0].yadd*16)  / ctx->blurring);
    +      }
    +      if(0 == (tmask & D2C_LIM2THRESHOLD))
    +      {
    +         edge[1].start = ((edge[1].start*16) / ctx->blurring);
    +         edge[1].xadd  = ((edge[1].xadd*16)  / ctx->blurring);
    +         edge[1].yadd  = ((edge[1].yadd*16)  / ctx->blurring);
    +      }
    +   }
    +
    +   /* set register values (geometric parameters) */
    +   D2_DLISTWRITES( D2_L1START, edge[0].start );
    +   D2_DLISTWRITES( D2_L1XADD , edge[0].xadd );
    +   D2_DLISTWRITES( D2_L1YADD , edge[0].yadd );
    +   D2_DLISTWRITES( D2_L2START, edge[1].start );
    +   D2_DLISTWRITES( D2_L2XADD , edge[1].xadd );
    +   D2_DLISTWRITES( D2_L2YADD , edge[1].yadd );
    +   D2_DLISTWRITES( D2_L3START, edge[2].start );
    +   D2_DLISTWRITES( D2_L3XADD , edge[2].xadd );
    +   D2_DLISTWRITES( D2_L3YADD , edge[2].yadd );
    +   D2_DLISTWRITES( D2_L4START, edge[3].start );
    +   D2_DLISTWRITES( D2_L4XADD , edge[3].xadd );
    +   D2_DLISTWRITES( D2_L4YADD , edge[3].yadd );
    +
    +   /* render line part */
    +   if(0 != flip)
    +   {
    +      d2_startrender_bottom_intern( handle, &bbox, delay );
    +   }
    +   else
    +   {
    +      d2_startrender_intern( handle, &bbox, delay );
    +   }
    +
    +   if(d2_lc_round != cap)
    +   {
    +      return 1;
    +   }
    +
    +   /* find reduced bbox for endpoint */
    +   bbox2.xmin = (d2_point) D2_FLOOR4( xp - r );
    +   bbox2.ymin = (d2_point) D2_FLOOR4( yp - r );
    +   bbox2.xmax = (d2_point) D2_CEIL4( xp + r );
    +   bbox2.ymax = (d2_point) D2_CEIL4( yp + r );
    +
    +   /* endpoint clipping */
    +   if(0 != d2_clipbbox_intern( handle, &bbox2 ))
    +   {
    +      /* make relative */
    +      xp = xp - bbox2.xmin;
    +      yp = yp - bbox2.ymin;
    +
    +      /* calc circle endpoint parameters */
    +      d2_circlesetup_intern(handle, ctx, 0, (d2_point) xp, (d2_point) yp, (d2_width) r, 0, 0, 0);
    +
    +      delay = D2_CEIL4( r ) >> 4;                   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +      /* adapt line parameters to new bounding box */
    +      if(0 != flip)
    +      {
    +         nx = D2_INT4(bbox2.xmin - bbox.xmin);      /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         ny = D2_INT4(bbox2.ymin - bbox.ymin) - h;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         edge[l].yadd = -edge[l].yadd;
    +         edge[2].yadd = -edge[2].yadd;
    +         edge[3].yadd = -edge[3].yadd;
    +      }
    +      else
    +      {
    +         nx = D2_INT4(bbox2.xmin - bbox.xmin);      /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         ny = D2_INT4(bbox2.ymin - bbox.ymin);      /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      }
    +
    +      d2_setuppattern( handle, ctx, &bbox2, 0 );
    +      d2_setuptexture( handle, ctx, &bbox2, 0 );
    +
    +      D2_DLISTWRITES( D2_L3START, edge[2].start + (edge[2].xadd * nx) + (edge[2].yadd * ny) );
    +      D2_DLISTWRITES( D2_L3XADD , edge[2].xadd );
    +      D2_DLISTWRITES( D2_L3YADD , edge[2].yadd );
    +      D2_DLISTWRITES( D2_L4START, edge[3].start + (edge[3].xadd * nx) + (edge[3].yadd * ny) );
    +      D2_DLISTWRITES( D2_L4XADD , edge[3].xadd );
    +      D2_DLISTWRITES( D2_L4YADD , edge[3].yadd );
    +      D2_DLISTWRITES( D2_L5START, 
    +                      (
    +                         (
    +                            (
    +                               (
    +                                  D2_FIX16(1) - edge[l].start
    +                                )
    +                               - (edge[l].xadd * nx)
    +                             )
    +                            - (edge[l].yadd * ny)
    +                          )
    +                         + D2_EPSILON 
    +                       )
    +                      );
    +      D2_DLISTWRITES( D2_L5XADD , -edge[l].xadd );
    +      D2_DLISTWRITES( D2_L5YADD , -edge[l].yadd );
    +
    +      control = 
    +         D2C_LIM1ENABLE   | 
    +         D2C_QUAD1ENABLE  | 
    +         D2C_SPANABORT    | 
    +         (ctx->thresholdmask & (D2C_LIM1THRESHOLD | D2C_LIM3THRESHOLD | D2C_LIM4THRESHOLD)) |
    +         D2C_LIM3ENABLE   | 
    +         D2C_LIM4ENABLE   | 
    +         D2C_LIM5ENABLE   | 
    +         D2C_LIM5THRESHOLD;
    +
    +      control = d2_initgradients_intern( handle, ctx, &bbox2, 5, control );
    +
    +      D2_DLISTWRITEU( D2_CONTROL, control );
    +
    +      /* start first endpoint rendering */
    +      d2_startrender_intern( handle, &bbox2, delay );
    +   }
    +
    +   if(0 != cap2)
    +   {
    +      /* second point required too */
    +      if(1 == l)
    +      {
    +         /* startpoint second */
    +         r = w1;
    +         xp = xs;
    +         yp = ys;
    +      }
    +      else
    +      {
    +         /* endpoint second */
    +         r = w2;
    +         xp = xe;
    +         yp = ye;
    +      }
    +
    +      (void)d2_renderlinedot_intern( handle, ctx, (d2_point) xp, (d2_point) yp, (d2_width) r, 1, edge_buffer, edge_bbox );
    +   }
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderlinedot_intern( d2_devicedata *handle, const d2_contextdata *ctx, d2_point x, d2_point y, d2_width w, d2_u32 edges, const d2_limdata *edge_buffer, const d2_bbox *edge_bbox )
    +{
    +   d2_bbox bbox;
    +   d2_u32 delay, grad;
    +   d2_u32 control;
    +   d2_u32 tmask;
    +   d2_width er;
    +
    +   /* endpoint radius */
    +   er = (d2_width)((w + D2_FIX4(1)) >> 1);           /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /* circle bounding box */
    +   bbox.xmin = (d2_point) D2_FLOOR4( x - er );
    +   bbox.ymin = (d2_point) D2_FLOOR4( y - er );
    +   bbox.xmax = (d2_point) D2_CEIL4( x + er );
    +   bbox.ymax = (d2_point) D2_CEIL4( y + er );
    +
    +   /* clipping */
    +   if(0 == d2_clipbbox_intern( handle, &bbox ))
    +   {
    +      return 0;
    +   }
    +
    +   /* make relative */
    +   x = (d2_point)(x - bbox.xmin);
    +   y = (d2_point)(y - bbox.ymin);
    +
    +   /* ASSUME material is still set from line rendering */
    +   tmask = ctx->thresholdmask;
    +
    +   /* base circle setup */
    +   d2_circlesetup_intern(handle, ctx, 0, x, y, er, 0, 0, 0);
    +
    +   control = 
    +      D2C_LIM1ENABLE             | 
    +      D2C_QUAD1ENABLE            | 
    +      D2C_SPANABORT              | 
    +      (D2C_SPANSTORE*0)          | 
    +      (tmask & D2C_LIM1THRESHOLD);
    +
    +   control = d2_initgradients_intern( handle, ctx, &bbox, 2, control );
    +
    +   delay = (d2_u32) (D2_CEIL4( er ) >> 4);         /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   grad = 2;
    +
    +   /* additional edges */
    +   if(0 != edges)
    +   {
    +      d2_s32 xr, yr;
    +
    +      /* find relative change of position */
    +      xr = D2_INT4( edge_bbox->xmin - bbox.xmin );  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      yr = D2_INT4( edge_bbox->ymin - bbox.ymin );  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +      if(0 != (edges & 1))
    +      {
    +         D2_DLISTWRITES( D2_L3START, 
    +                         (
    +                            (
    +                               (
    +                                  (
    +                                     D2_FIX16(1) - edge_buffer[0].start
    +                                   )
    +                                  + (xr * edge_buffer[0].xadd)
    +                                )
    +                               + (yr * edge_buffer[0].yadd)
    +                             )
    +                            + D2_EPSILON
    +                          )
    +                         );
    +         D2_DLISTWRITES( D2_L3XADD , -edge_buffer[0].xadd );
    +         D2_DLISTWRITES( D2_L3YADD , -edge_buffer[0].yadd );
    +
    +         control |= D2C_LIM3ENABLE | D2C_LIM3THRESHOLD;
    +
    +         grad++;
    +      }
    +
    +      if(0 != (edges & 2))
    +      {
    +         D2_DLISTWRITES( D2_L4START, 
    +                         (
    +                            (
    +                               (
    +                                  (
    +                                     D2_FIX16(1) - edge_buffer[1].start
    +                                   )
    +                                  + (xr * edge_buffer[1].xadd)
    +                                )
    +                               + (yr * edge_buffer[1].yadd)
    +                             )
    +                            + D2_EPSILON
    +                          )
    +                         );
    +         D2_DLISTWRITES( D2_L4XADD , -edge_buffer[1].xadd );
    +         D2_DLISTWRITES( D2_L4YADD , -edge_buffer[1].yadd );
    +
    +         control |= D2C_LIM4ENABLE | D2C_LIM4THRESHOLD;
    +
    +         if(3 == grad)
    +         {
    +            grad++;
    +         }
    +      }
    +   }
    +
    +   /* add gradients */
    +   control = d2_initgradients_intern( handle, ctx, &bbox, grad, control );
    +
    +   /* start rendering */
    +   D2_DLISTWRITEU( D2_CONTROL, control );
    +
    +   d2_setuppattern( handle, ctx, &bbox, 0 );
    +   d2_setuptexture( handle, ctx, &bbox, 0 );
    +
    +   d2_startrender_intern( handle, &bbox, delay );
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_intern_split( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags, d2_limdata *edge_buffer, d2_bbox *edge_bbox, const d2_s32 *connectors )
    +{
    +   if(0 != (ctx->features & d2_feat_blur))
    +   {
    +      d2_limdata tmp_edge_buffer[2];
    +      d2_bbox    tmp_edge_bbox;
    +
    +      (void)d2_renderline2_intern(handle, ctx, x1, y1, x2, y2, w, w, flags, tmp_edge_buffer, &tmp_edge_bbox);
    +   }
    +   else
    +   {
    +      if ( (w >= D2_FIX4(3)) && (d2_lc_round == ctx->linecap) && ((flags & d2_le_exclude_both) != d2_le_exclude_both) )
    +      {
    +         /* FIX to avoid overflowing hw register in quad mode we split geometry. sad thing! */
    +         if(0 != d2_renderline_intern( handle, ctx, x1,y1, x2,y2, w, flags | d2_le_exclude_both | d2_lei_buffer_first_edge | d2_lei_buffer_last_edge, edge_buffer, edge_bbox, connectors) )
    +         {
    +            if(0 == (flags & d2_le_exclude_start))
    +            {
    +               (void)d2_renderlinedot_intern( handle, ctx, x1, y1, w, 1, edge_buffer, edge_bbox );
    +            }
    +
    +            if(0 == (flags & d2_le_exclude_end))
    +            {
    +               (void)d2_renderlinedot_intern( handle, ctx, x2, y2, w, 2, edge_buffer, edge_bbox );
    +            }
    +         }
    +      } 
    +      else
    +      {
    +         (void)d2_renderline_intern( handle, ctx, x1,y1, x2,y2, w, flags, edge_buffer, edge_bbox, connectors );
    +      }
    +   }
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags )
    +{
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, w, flags, edge_buffer, &edge_bbox, NULL );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_outline_I( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags )
    +{
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1, y1, x2, y2, w, flags, edge_buffer, &edge_bbox, NULL );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags )
    +{
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1, y1, x2, y2, (d2_width)(w + (D2_DEV(handle)->outlinewidth * 2)), flags, edge_buffer, &edge_bbox, NULL );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags )
    +{
    +   d2_point   sx,sy;
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 + sx), (d2_point)(y1 + sy), (d2_point)(x2 + sx), (d2_point)(y2 + sy), w, flags, edge_buffer, &edge_bbox, NULL );
    +
    +   return D2_OK;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags )
    +{
    +   d2_point   sx,sy;
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 + sx), (d2_point)(y1 + sy), (d2_point)(x2 + sx), (d2_point)(y2 + sy), w, flags, edge_buffer, &edge_bbox, NULL );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1,y1, x2,y2, w, flags, edge_buffer, &edge_bbox, NULL );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags )
    +{
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   /* render outline */
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1, y1, x2, y2, (d2_width)(w + (D2_DEV(handle)->outlinewidth * 2)), flags, edge_buffer, &edge_bbox, NULL );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, w, flags, edge_buffer, &edge_bbox, NULL);
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline2_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags )
    +{
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   (void)d2_renderline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, w1, w2, flags, edge_buffer, &edge_bbox );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline2_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags )
    +{
    +   d2_width   ow;
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   ow = (d2_width)(D2_DEV(handle)->outlinewidth * 2);
    +   (void)d2_renderline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1, y1, x2, y2, (d2_width)(w1 + ow), (d2_width)(w2 + ow), flags, edge_buffer, &edge_bbox );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline2_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags )
    +{
    +   d2_point   sx,sy;
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   (void)d2_renderline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 + sx), (d2_point)(y1 + sy), (d2_point)(x2 + sx), (d2_point)(y2 + sy), w1, w2, flags, edge_buffer, &edge_bbox );
    +
    +   return D2_OK;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline2_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags )
    +{
    +   d2_point   sx,sy;
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_renderline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 + sx), (d2_point)(y1 + sy), (d2_point)(x2 + sx), (d2_point)(y2 + sy), w1, w2, flags, edge_buffer, &edge_bbox );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, w1, w2, flags, edge_buffer, &edge_bbox );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderline2_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags )
    +{
    +   d2_width   ow;
    +   d2_limdata edge_buffer[2];
    +   d2_bbox    edge_bbox;
    +
    +   ow = (d2_width)(D2_DEV(handle)->outlinewidth * 2);
    +
    +   /* render outline */
    +   (void)d2_renderline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1, y1, x2, y2, (d2_width)(w1 + ow), (d2_width)(w2 + ow), flags, edge_buffer, &edge_bbox );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, w1, w2, flags, edge_buffer, &edge_bbox );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    diff --git a/src/drivers/dave2d/src/dave_math.c b/src/drivers/dave2d/src/dave_math.c
    new file mode 100644
    index 000000000..f8076ecc4
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_math.c
    @@ -0,0 +1,79 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_math.c (%version: 4 %)
    + *          created Tue Feb 08 10:17:38 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jul 14 14:56:42 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2007-08-29 ASc  removed tabs, add comments, changed C++ to C comments
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_math.h"
    +
    +/*-------------------------------------------------------------------------- */
    +
    +#define D2_INNER_SQRT(s)                        \
    +   temp = (y << (s)) + (1 << (((s) * 2) - 2));  \
    +   if(x >= temp)                                \
    +   {                                            \
    +      y += 1 << ((s) - 1);                      \
    +      x -= temp;                                \
    +   }(void)0                                     /* PRQA S 3412 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/
    +
    +/*--------------------------------------------------------------------------
    + * minimalistic 32->16 bit integer square root (no hw divide/multiply needed)
    + * unrolled for speed
    + * */
    +d2_s32 d2_sqrt(d2_u32 x)
    +{
    +   d2_u32 temp, y=0;
    +
    +   if (x >= 0x40000000u)
    +   {
    +      y = 0x8000u;
    +      x -= 0x40000000u;
    +   }
    +
    +   D2_INNER_SQRT (15); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT (14); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT (13); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT (12); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT (11); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT (10); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 9); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 8); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 7); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 6); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 5); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 4); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 3); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +   D2_INNER_SQRT ( 2); /* PRQA S 3112 */ /* $Misra: #MACRO_COMPILER_WARNING_NOP $*/ /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +
    +   temp = (y + y) + 1;
    +   if(x >= temp)
    +   {
    +      y++;
    +   }
    +   return (d2_s32) y;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Find next larger power of two - 1
    + * e.g. given number x=73 -> next larger power of two is 128,
    + * the result is 128-1 = 127 (number with all bits set)
    + * */
    +d2_u32 d2_pow2mask(d2_u32 x)
    +{
    +   x |= (x >> 1);
    +   x |= (x >> 2);
    +   x |= (x >> 4);
    +   x |= (x >> 8);
    +   x |= (x >> 16);
    +
    +   return x;
    +}
    diff --git a/src/drivers/dave2d/src/dave_memory.c b/src/drivers/dave2d/src/dave_memory.c
    new file mode 100644
    index 000000000..259eef0f4
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_memory.c
    @@ -0,0 +1,150 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_memory.c (%version: 8 %)
    + *          created Tue Jan 11 13:12:18 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jan 04 10:37:27 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2006-02-28 CSe  special allocation for dlist memory
    + *  2006-05-10 CSe  changed allocation of dlist memory  for systems
    + *                  with statically mapped vidmem
    + *  2006-11-07 CSe  allocate memory through new d0_ functions
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_memory.h"
    +#include "dave_base.h"
    +
    +/*--------------------------------------------------------------------------
    + * get memory from current process heap
    + * */
    +void *d2_getmem_p( d2_u32 size )
    +{
    +   return d1_allocmem(size);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * free memory from current process heap
    + * */
    +void d2_freemem_p( void *adr )
    +{
    +   d1_freemem( adr );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * resize memory from current process heap
    + *
    + * keep - set to 0 if it is not necessary to keep the original data
    + * */
    +void *d2_reallocmem_p( d2_u32 newsize, void *oldadr, d2_s32 keep )
    +{
    +   void *newadr;
    +   d2_u32 oldsize;
    +
    +   /* newsize 0 implies just a free */
    +   if(0 == newsize)
    +   {
    +      d2_freemem_p( oldadr );
    +      return (void*)0;
    +   }
    +
    +   /* query old blocksize */
    +   oldsize = d1_memsize( oldadr );
    +   if(0 == oldsize)
    +   {
    +      return (void*)0;
    +   }
    +
    +   /* realloc only if larger */
    +   if((d2_u32)newsize < oldsize)
    +   {
    +      return oldadr;
    +   }
    +
    +   newadr = d2_getmem_p( newsize );
    +   if(NULL == newadr)
    +   {
    +      return newadr;
    +   }
    +
    +   /* copy content as ints if possible */
    +   if(0 != keep)
    +   {
    +      d2_u32 i;
    +      d2_s32 *src = (d2_s32*) oldadr;
    +      d2_s32 *dst = (d2_s32*) newadr;
    +
    +      for (i=0; i<(oldsize / sizeof(d2_s32)); i++)
    +      {
    +         *dst = *src;
    +         dst++;
    +         src++;
    +      }
    +
    +      if(0 == (oldsize & (sizeof(d2_u32)-1)))
    +      {
    +         /* copy not 'int aligned' part */
    +         d2_s8 *srcc = (d2_s8*) src;
    +         d2_s8 *dstc = (d2_s8*) dst;
    +         for (i=0; i<(oldsize & (sizeof(d2_s32)-1)); i++)
    +         {
    +            *dstc = *srcc;
    +            dstc++;
    +            srcc++;
    +         }
    +      }
    +   }
    +
    +   /* release old block */
    +   d2_freemem_p(oldadr);
    +
    +   return newadr;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * get memory from display list heap
    + * */
    +void *d2_getmem_d( const d2_device *handle, d2_u32 size )
    +{
    +   d1_device *id = d2_level1interface(handle);
    +
    +   if(0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_unified))
    +   {
    +      return d1_allocvidmem( id, d1_mem_dlist, size );
    +   }
    +
    +   if(0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_mapped))
    +   {
    +      return d1_mapfromvidmem(id, d1_allocvidmem( id, d1_mem_dlist, size ));
    +   }
    +
    +   return d1_allocmem( size );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * free memory from display list heap
    + * */
    +void d2_freemem_d( const d2_device *handle, void *adr )
    +{
    +   d1_device *id = d2_level1interface(handle);
    +
    +   if(0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_unified))
    +   {
    +      d1_freevidmem( id, d1_mem_dlist, adr );
    +   }
    +
    +   else if(0 != (D2_DEV(handle)->hwmemarchitecture & d1_ma_mapped))
    +   {
    +      d1_freevidmem( id, d1_mem_dlist, d1_maptovidmem(id, adr) );
    +   }
    +   else
    +   {
    +      d1_freemem( adr );
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_pattern.c b/src/drivers/dave2d/src/dave_pattern.c
    new file mode 100644
    index 000000000..daa61c4dc
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_pattern.c
    @@ -0,0 +1,104 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_pattern.c (%version: 9 %)
    + *          created Tue Feb 15 12:41:15 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Jul 13 18:22:53 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_render.h"
    +#include "dave_pattern.h"
    +
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_setupulimiter_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox ); /* MISRA */
    +
    +static D2_INLINE void d2_setupulimiter_invert_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox ); /* MISRA */
    +
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_setupulimiter_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox )
    +{
    +   d2_s32 x, y, s;
    +
    +   if(0 != (ctx->patulim[0].mode & d2_grad_aapattern))
    +   {
    +      /* special pattern setup for autoaligned mapping using relative point, offset and direction */
    +      x = ctx->patulim[0].x1;
    +      y = ctx->patulim[0].y1;
    +      s = (((x * ctx->patulim[0].xadd) + (y * ctx->patulim[0].yadd)) >> 4) + ctx->patulim[0].xadd2; /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +   else
    +   {
    +      /* normal pattern setup using point and direction */
    +      x = ctx->patulim[0].x1 - bbox->xmin;
    +      y = ctx->patulim[0].y1 - bbox->ymin;
    +      s = ((x * ctx->patulim[0].xadd) + (y * ctx->patulim[0].yadd)) >> 4;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   D2_DLISTWRITES( D2_LUSTART, -s );
    +   D2_DLISTWRITES( D2_LUXADD , ctx->patulim[0].xadd );
    +   D2_DLISTWRITES( D2_LUYADD , ctx->patulim[0].yadd );
    +
    +   return;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_setupulimiter_invert_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox )
    +{
    +   d2_s32 x, y, s;
    +
    +   if(0 != (ctx->patulim[0].mode & d2_grad_aapattern))
    +   {
    +      /* special pattern setup for autoaligned mapping using relative point, offset and direction */
    +      x = ctx->patulim[0].x1;
    +      y = (bbox->ymax - bbox->ymin) - ctx->patulim[0].y1;
    +      s = (((x * ctx->patulim[0].xadd) - (y * ctx->patulim[0].yadd)) >> 4) + ctx->patulim[0].xadd2;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +   else
    +   {
    +      /* normal pattern setup using point and direction */
    +      x = ctx->patulim[0].x1 - bbox->xmin;
    +      y = ctx->patulim[0].y1 - bbox->ymax;
    +      s = ((x * ctx->patulim[0].xadd) + (y * ctx->patulim[0].yadd)) >> 4;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   D2_DLISTWRITES( D2_LUSTART, -s );
    +   D2_DLISTWRITES( D2_LUXADD , ctx->patulim[0].xadd );
    +   D2_DLISTWRITES( D2_LUYADD , -ctx->patulim[0].yadd );
    +
    +   return;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_setuppattern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox, d2_s32 flip )
    +{
    +   if(d2_fm_pattern == ctx->fillmode)
    +   {
    +      if(0 != flip) 
    +      {
    +         d2_setupulimiter_invert_intern( handle, ctx, bbox );
    +      }
    +      else
    +      {
    +         d2_setupulimiter_intern( handle, ctx, bbox );
    +      }
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_perfcount.c b/src/drivers/dave2d/src/dave_perfcount.c
    new file mode 100644
    index 000000000..0543548e8
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_perfcount.c
    @@ -0,0 +1,181 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_perfcount.c (%version: 5 %)
    + *          created Wed Jan 12 16:11:17 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Mar 12 15:29:23 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + *  2007-03-14 CSe  added DEVICEBUSY error when DLR is active
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs 
    + *  2008-07-16 ASt  added new performance counter events for ndoc
    + *  2012-09-25 BSp  MISRA cleanup
    + */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Profiling
    + * Performance measurement counter functions
    + *
    + * Check D2FB_PERFCOUNT bit of <d2_getrevisionhw> to see if performance counters
    + * are available.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +
    +/*--------------------------------------------------------------------------
    + * Group: Performance counting
    + * */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setperfcountevent
    + * Set the event to be counted by performance counter.
    + *
    + * Does not work while D/AVE is active! When calling this while D/AVE is active
    + * executing a display list, rendering errors or even hangups can occur.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   counter - 0 or 1: which of both available performance counters to use
    + *   event - which events the selected performance counter has to count
    + *
    + * events:
    + *  d2_pc_disable        - disable performance counter
    + *  d2_pc_davecycles     - DAVE active cycles
    + *  d2_pc_fbreads        - framebuffer read access
    + *  d2_pc_fbwrites       - framebuffer write access
    + *  d2_pc_texreads       - texture read access
    + *  d2_pc_invpixels      - invisible pixels (enumerated but selected with alpha 0%)
    + *  d2_pc_invpixels_miss - invisible pixels while internal fifo is empty (lost cycles)
    + *  d2_pc_dlrcycles      - displaylist reader active cycles
    + *  d2_pc_fbreadhits     - framebuffer read hits
    + *  d2_pc_fbreadmisses   - framebuffer read misses
    + *  d2_pc_fbwritehits    - framebuffer write hits
    + *  d2_pc_fbwritemisses  - framebuffer write misses
    + *  d2_pc_texreadhits    - texture read hits
    + *  d2_pc_texreadmisses  - texture read misses
    + *  d2_pc_clkcycles      - every clock cycle (for use as timer)
    + *  d2_pc_dlrburstreads  - displaylist reader burst reads
    + *  d2_pc_dlrwordsread   - displaylist reader words read
    + *  d2_pc_rlerewinds     - texture rle decoder rewinds
    + *  d2_pc_texburstreads  - texture cache burst reads
    + *  d2_pc_texwordsread   - texture cache words read
    + *  d2_pc_fbburstreads   - framebuffer cache burst reads
    + *  d2_pc_fbwordsread    - framebuffer cache words read
    + *  d2_pc_fbburstwrites  - framebuffer cache burst writes
    + *  d2_pc_fbwordswritten - framebuffer cache words written
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setperfcountevent( d2_device *handle, d2_u32 counter, d2_u32 event )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );    /* PRQA S 3112 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( counter < 2, D2_VALUETOOBIG ); /* PRQA S 3112 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 != ((d2_u32)d2hw_get( D2_DEV(handle)->hwid, D2_STATUS ) & D2C_DLISTACTIVE))
    +   {
    +      D2_RETERR( handle, D2_DEVICEBUSY );
    +   }
    +
    +   /* fbcache performance measurement is different for prefetching framebuffer cache */
    +   if(0 != (D2_DEV(handle)->hwrevision & D2FB_FBPREFETCH))
    +   {
    +      switch (event)
    +      {
    +         case d2_pc_fbwritehits:
    +            event = d2_pc_fbwrites;
    +            break;
    +
    +         case d2_pc_fbwritemisses:
    +            event = d2_pc_noevent;
    +            break;
    +
    +         case d2_pc_fbrwconflicts:
    +            event = d2_pc_fbwritehits;
    +            break;
    +
    +         case d2_pc_fbrwconflictcycles:
    +            event = d2_pc_fbwritemisses;
    +            break;
    +
    +         default:
    +            break;
    +      }
    +   }
    +
    +   D2_DEV(handle)->perftriggermask &= ~(0xffffu << (counter << 4));
    +   D2_DEV(handle)->perftriggermask |=  event << (counter << 4);
    +
    +   d2hw_set( D2_DEV(handle)->hwid, D2_PERFTRIGGER, (d2_s32)D2_DEV(handle)->perftriggermask );
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setperfcountvalue
    + * Set the current performance counter value.
    + *
    + * Does not work while D/AVE is active! When calling this while D/AVE is active
    + * executing a display list, rendering errors or even hangups can occur.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   counter - 0 or 1: which of both available performance counters to use
    + *   value - value to be set: 0 for reset
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_setperfcountvalue( d2_device *handle, d2_u32 counter, d2_slong value )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );     /* PRQA S 3112 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( counter < 2, D2_VALUETOOBIG );  /* PRQA S 3112 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 != ((d2_u32)d2hw_get( D2_DEV(handle)->hwid, D2_STATUS ) & D2C_DLISTACTIVE))
    +   {
    +      D2_RETERR( handle, D2_DEVICEBUSY );
    +   }
    +
    +   if(0 == counter)
    +   {
    +      d2hw_set( D2_DEV(handle)->hwid, D2_PERFCOUNT1 , value );
    +   }
    +   else
    +   {
    +      d2hw_set( D2_DEV(handle)->hwid, D2_PERFCOUNT2 , value );
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getperfcountvalue
    + * Get the current performance counter value.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   counter - 0 or 1: which of both available performance counters to use
    + *
    + * returns:
    + *   current counter register value
    + * */
    +d2_slong d2_getperfcountvalue( d2_device *handle, d2_u32 counter )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );    /* PRQA S 3112 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( counter < 2, D2_VALUETOOBIG ); /* PRQA S 3112 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == counter)
    +   {
    +      return d2hw_get( D2_DEV(handle)->hwid, D2_PERFCOUNT1 );
    +   }
    +   else
    +   {
    +      return d2hw_get( D2_DEV(handle)->hwid, D2_PERFCOUNT2 );
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_polyline.c b/src/drivers/dave2d/src/dave_polyline.c
    new file mode 100644
    index 000000000..37e6faec0
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_polyline.c
    @@ -0,0 +1,583 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_polyline.c (%version: 12 %)
    + *          created Wed Mar 15 13:48:36 2006 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Mar 08 13:22:00 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2007-03-14 NSc  removed Compiler Warning (uninitialized variables)
    + *  2008-01-09 ASc  fixed bugs to draw correct line joins
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2011-01-20 SSt  made lines and polylines thread safe (eliminated globals)
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_render.h"
    +#include "dave_line.h"
    +#include "dave_polyline.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_fixlength(d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_s32 *dx, d2_s32 *dy); /* MISRA */
    +
    +static d2_s32 d2_renderpolyline2_intern( d2_devicedata *handle, d2_contextdata *ctx, const d2_point *data, const d2_u32 *sflags, d2_u32 count, const d2_width *w, d2_u32 flags, d2_point soffx, d2_point soffy, d2_width olwidth ); /* MISRA */
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_fixlength(d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_s32 *dx, d2_s32 *dy)
    +{
    +   d2_s32 dxi, dyi, l;
    +
    +   dxi = x2 - x1;
    +   dyi = y2 - y1;
    +
    +   l = d2_sqrt( (d2_u32) ((dxi * dxi) + (dyi * dyi)) );
    +
    +   /* normalize to length 16 (for join tangent calculation) */
    +   if(0 != l)
    +   {
    +      *dx = (dxi * D2_FIX4(16)) / l;
    +      *dy = (dyi * D2_FIX4(16)) / l;
    +   }
    +   else
    +   {
    +      /* degenerate case. length 0 */
    +      *dx = dxi;
    +      *dy = dyi;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline_intern( d2_devicedata *handle, d2_contextdata *ctx, const d2_point *data, const d2_u32 *sflags, d2_u32 count, d2_width w, d2_u32 flags, d2_point soffx, d2_point soffy )
    +{
    +   d2_u32 i;
    +   d2_point px1, py1;
    +   d2_point px2, py2;
    +   const d2_point *pstart = data;
    +   d2_u32 startflag;
    +   d2_s32 dxm1=0, dym1=0;   /* normalized deltas at index-1 */
    +   d2_s32 dxp1, dyp1;    /* normalized deltas at index+1 */
    +   d2_s32 joins, dots;
    +   d2_s32 connectors[4]; /* (note) connectors might be used uninitialized, depending on flags */
    +
    +   connectors[0] = connectors[1] = connectors[2] = connectors[3] = 0;
    +
    +   /* check if linejoins have to be renderd */
    +   joins = (w > D2_FIX4(1)) ? 1 : 0;
    +
    +   if(count < 3)
    +   {
    +      joins = 0;
    +
    +      if(count < 2)
    +      {
    +         return 1;
    +      }
    +   }
    +
    +   /* check joinstyle */
    +   if(0 != joins)
    +   {
    +      switch( ctx->linejoin )
    +      {
    +         case d2_lj_none:
    +            joins = 0;
    +            dots = 0;
    +            break;
    +
    +         case d2_lj_round:
    +            dots = 1;
    +            joins = 0;
    +            break;
    +
    +         case d2_lj_bevel:
    +         case d2_lj_miter:
    +            dots = 0;
    +            break;
    +
    +         default:
    +            dots = 0;
    +            break;
    +      }
    +   }
    +   else
    +   {
    +      dots = 0;
    +   }
    +
    +   /* set correct loop conditions for closed / open polylines */
    +   if(0 != (flags & d2_le_closed))
    +   {
    +      /* startpoint is last point */
    +      px1 = (d2_point)(data[(count * 2) - 2] + soffx);
    +      py1 = (d2_point)(data[(count * 2) - 1] + soffy);
    +
    +      /* no linecap at startpoint */
    +      startflag = 0;
    +
    +      /* linejoin at startpoint, need to init deltas */
    +      if(0 != joins)
    +      {
    +         d2_fixlength((d2_point)(data[(count * 2) - 4] + soffx), (d2_point)(data[(count * 2) - 3] + soffy), px1, py1, &dxm1, &dym1);
    +      }
    +   }
    +   else
    +   {
    +      /* startpoint first point */
    +      px1 = data[0];
    +      py1 = data[1];
    +      data += 2;
    +
    +      px1 = (d2_point)(px1 + soffx);
    +      py1 = (d2_point)(py1 + soffy);
    +
    +      count--;
    +
    +      /* linecap at startpoint (only when no exclude flag is set) */
    +      startflag = ~flags & d2_le_exclude_start;
    +
    +      /* linecap at both ends - single segment polyline (only when no exclude flag is set) */
    +      if( (1 == count) && (0 != (~flags & d2_le_exclude_end)) )
    +      {
    +         startflag |= d2_le_exclude_end;
    +      }
    +
    +      dxm1 = 0;
    +      dym1 = 0;
    +   }
    +
    +   /* future delta unknown */
    +   dxp1 = 0;
    +   dyp1 = 0;
    +
    +   /* iterate over polyline */
    +   for(i=0; i<count; i++)
    +   {
    +      d2_u32 sflag;
    +      d2_s32 dx, dy;
    +      d2_s32 bSkip;
    +
    +      /* next point */
    +      px2 = data[0];
    +      py2 = data[1];
    +      data += 2;
    +
    +      px2 = (d2_point)(px2 + soffx);
    +      py2 = (d2_point)(py2 + soffy);
    +
    +      /* ignore repeated points */
    +      if( (px1 == px2) && (py1 == py2) )
    +      {
    +         bSkip = 1;
    +         /*continue;*/
    +      }
    +      else
    +      {
    +         bSkip = 0;
    +      }
    +
    +      if(0 == bSkip)
    +      {
    +
    +         /* endpoint classification (inner/outer endpoint) */
    +         sflag = d2_le_exclude_start | d2_le_exclude_end;
    +         sflag &= ~startflag;
    +
    +         if(0 != joins)
    +         {
    +            /* check if length is already known */
    +            if(0 != (dxp1 | dyp1))                      /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +            {
    +               dx = dxp1;
    +               dy = dyp1;
    +            }
    +            else
    +            {
    +               /* line length */
    +               d2_fixlength(px1, py1, px2, py2, &dx, &dy);
    +            }
    +
    +            /* check for line joins */
    +            if(d2_le_exclude_start == (sflag & d2_le_exclude_start))
    +            {
    +               /* join at start of line */
    +               sflag |= d2_lei_ext_first_edge;
    +
    +               /* bisecting line direction *2 (to avoid loosing bits) */
    +               connectors[0] =  (dym1 + dy);
    +               connectors[1] = -(dxm1 + dx);
    +            }
    +
    +            if(d2_le_exclude_end == (sflag & d2_le_exclude_end))
    +            {
    +               /* join at end of line */
    +
    +               if(i == (count - 1))                    /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +               {
    +                  /* wrap back to start */
    +                  d2_fixlength(px2, py2, (d2_point)(pstart[0] + soffx), (d2_point)(pstart[1] + soffy), &dxp1, &dyp1);
    +               }
    +               else
    +               {
    +                  /* find future delta */
    +                  d2_fixlength(px2, py2, (d2_point)(data[0] + soffx), (d2_point)(data[1] + soffx), &dxp1, &dyp1);
    +               }
    +
    +               sflag |= d2_lei_ext_last_edge;
    +
    +               /* bisecting line direction *2 (to avoid loosing bits) */
    +               connectors[2] =  (dy + dyp1);
    +               connectors[3] = -(dx + dxp1);
    +            }
    +         }
    +         else
    +         {
    +            /* delta not required. */
    +            dx = dxp1;
    +            dy = dyp1;
    +         }
    +
    +         {
    +            d2_s32 bSkipSeg;
    +
    +            if(NULL != sflags)
    +            {
    +               bSkipSeg = (*sflags == d2_sf_skip) ? 1 : 0;
    +               sflags++;
    +            }
    +            else
    +            {
    +               bSkipSeg = 0;
    +            }
    +
    +            /* check segment flag for current segment */
    +            /*if( (0 == sflags) || (*sflags++ != d2_sf_skip) )*/
    +            if(0 == bSkipSeg)
    +            {
    +               d2_limdata edge_buffer[2];
    +               d2_bbox    edge_bbox;
    +
    +               /* render segment */
    +               sflag |= d2_lei_buffer_first_edge | d2_lei_buffer_last_edge;
    +
    +               if(0 != dots)
    +               {
    +                  (void)d2_renderline_intern_split( handle, ctx, px1, py1, px2, py2, w, sflag, edge_buffer, &edge_bbox, connectors );
    +
    +                  if( (i>0) || (0 != (flags & d2_le_closed)) )
    +                  {
    +                     (void)d2_renderlinedot_intern( handle, ctx, px1, py1, w, 1, edge_buffer, &edge_bbox );
    +                  }
    +               }
    +               else
    +               {
    +                  if(0 != joins)
    +                  {
    +                     /* limit corners */
    +                     sflag |= d2_lei_miter_edge;
    +
    +                     /* check for right-turn on first endpoint */
    +                     if( ((dx * dym1) - (dxm1 * dy) ) > 0)
    +                     {
    +                        sflag |= d2_lei_miter1_flip;
    +                     }
    +
    +                     if( ((dx * dyp1) - (dxp1 * dy) ) > 0)
    +                     {
    +                        sflag |= d2_lei_miter2_flip;
    +                     }
    +                  }
    +
    +                  (void)d2_renderline_intern_split( handle, ctx, px1, py1, px2, py2, w, sflag, edge_buffer, &edge_bbox, connectors );
    +               }
    +            }
    +         }
    +
    +         /* next segment */
    +         px1 = px2;
    +         py1 = py2;
    +         dxm1 = dx;
    +         dym1 = dy;
    +
    +         /* check for line caps */
    +         if( (0 == (flags & (d2_le_closed | d2_le_exclude_end))) && (i == (count - 2)))  /* PRQA S 3382 */ /* $Misra: #MISRA_BUG_ZERO_WRAPAROUND $*/
    +         {
    +            startflag = d2_le_exclude_end;
    +         }
    +         else
    +         {
    +            startflag = 0;
    +         }
    +
    +      } /* 0 == bSkip */
    +
    +   } /* for i..count */
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_s32 d2_renderpolyline2_intern( d2_devicedata *handle, d2_contextdata *ctx, const d2_point *data, const d2_u32 *sflags, d2_u32 count, const d2_width *w, d2_u32 flags, d2_point soffx, d2_point soffy, d2_width olwidth )
    +{
    +   d2_u32 i;
    +   d2_point px1, py1;
    +   d2_point px2, py2;
    +   d2_width w1, w2;
    +
    +   /* set correct loop conditions for closed / open polylines */
    +   if(0 != (flags & d2_le_closed))
    +   {
    +      /* startpoint is last point */
    +      px1 = data[(count * 2) - 2];
    +      py1 = data[(count * 2) - 1];
    +      w1  = w[count - 1];
    +   }
    +   else
    +   {
    +      /* startpoint first point */
    +      px1 = data[0];
    +      py1 = data[1];
    +      data += 2;
    +      w1  = *w;
    +      w++;
    +      count--;
    +   }
    +
    +   px1 = (d2_point)(px1 + soffx);
    +   py1 = (d2_point)(py1 + soffy);
    +   w1  = (d2_width)(w1 + olwidth);
    +
    +   /* iterate over polyline */
    +   for (i=0; i<count; i++)
    +   {
    +      d2_s32 bSkip;
    +
    +      /* next point */
    +      px2 = data[0];
    +      py2 = data[1];
    +      data += 2;
    +      w2  = *w;
    +      w++;
    +      px2 = (d2_point)(px2 + soffx);
    +      py2 = (d2_point)(py2 + soffy);
    +      w2  = (d2_width)(w2 + olwidth);
    +
    +      /* ignore repeated points */
    +      if( (px1 == px2) && (py1 == py2) )
    +      {
    +         bSkip = 1; /*continue;*/
    +      }
    +      else
    +      {
    +         bSkip = 0;
    +      }
    +
    +      if(0 == bSkip)
    +      {
    +         d2_s32 bSkipSeg;
    +
    +         /* check segment flag for current segment */
    +         if(NULL != sflags)
    +         {
    +            bSkipSeg = (*sflags == d2_sf_skip) ? 1 : 0;
    +            sflags++;
    +         }
    +         else
    +         {
    +            bSkipSeg = 0;
    +         }
    +
    +         /*if( (0 == sflags) || (*sflags++ != d2_sf_skip) )*/
    +         if(0 == bSkipSeg)
    +         {
    +            d2_limdata edge_buffer[2];
    +            d2_bbox    edge_bbox;
    +
    +            /* render segment */
    +            d2_u32 temp_flag = d2_le_exclude_start | d2_le_exclude_end;    /* default is not to draw start and end caps */
    +
    +            if( (0 == i) && (0 == (flags & d2_le_exclude_start)) && (0 == (flags & d2_le_closed)) )
    +            {
    +               temp_flag &= ~d2_le_exclude_start;  /* draw start cap */
    +            }
    +
    +            if( (i == (count - 1)) && (0 == (flags & d2_le_exclude_end)) && (0 == (flags & d2_le_closed)) )
    +            {
    +               temp_flag &= ~d2_le_exclude_end;    /* draw end cap */
    +            }
    +
    +            (void)d2_renderline2_intern( handle, ctx, px1, py1, px2, py2, w1, w2, temp_flag, edge_buffer, &edge_bbox);
    +
    +            if( (i > 0) || (0 != (flags & d2_le_closed)) )
    +            {
    +               (void)d2_renderlinedot_intern( handle, ctx, px1, py1, w1, 0, edge_buffer, &edge_bbox );  /* render a dot at line startpos */
    +            }
    +         }
    +
    +         /* next segment */
    +         px1 = px2;
    +         py1 = py2;
    +         w1  = w2;
    +      }
    +   }
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline_solid( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags )
    +{
    +   (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, data, NULL, count, w, flags, 0, 0);
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline_shadow( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags )
    +{
    +   d2_point sx, sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, w, flags, sx, sy);
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline_outline( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags )
    +{
    +   (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, (d2_width)(w + (D2_DEV(handle)->outlinewidth * 2)), flags, 0, 0 );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline_solidshadow( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags )
    +{
    +   d2_point sx, sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, w, flags, sx, sy );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, data, NULL, count, w, flags, 0, 0 );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline_solidoutline( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags )
    +{
    +   /* render outline */
    +   (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, (d2_width)(w + (D2_DEV(handle)->outlinewidth * 2)), flags, 0, 0 );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, data, NULL, count, w, flags, 0, 0 );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline2_solid( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags )
    +{
    +   (void)d2_renderpolyline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, data, NULL, count, w, flags, 0, 0, 0 );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline2_shadow( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags )
    +{
    +   d2_point sx,sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   (void)d2_renderpolyline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, w, flags, sx, sy, 0 );
    +
    +   return D2_OK;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline2_outline( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags )
    +{
    +   (void)d2_renderpolyline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, w, flags, 0,0, (d2_width)(D2_DEV(handle)->outlinewidth * 2) );
    +
    +   return D2_OK;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline2_solidshadow( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags )
    +{
    +   d2_point sx, sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_renderpolyline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, w, flags, sx, sy, 0 );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderpolyline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, data, NULL, count, w, flags, 0, 0, 0 );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderpolyline2_solidoutline( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags )
    +{
    +   /* render outline */
    +   (void)d2_renderpolyline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count, w, flags, 0, 0, (d2_width)(D2_DEV(handle)->outlinewidth * 2) );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderpolyline2_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, data, NULL, count, w, flags, 0, 0, 0 );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    diff --git a/src/drivers/dave2d/src/dave_quad.c b/src/drivers/dave2d/src/dave_quad.c
    new file mode 100644
    index 000000000..c966d4182
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_quad.c
    @@ -0,0 +1,534 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_quad.c (%version: 9 %)
    + *          created Fri Feb 11 14:06:48 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Dec 07 13:40:33 2007 %  (%derived_by:  hh74036 %)
    + *
    + * Changes:
    + *  2007-12-07 MGe  several bugfixes in d2_renderquad_intern, removed quadconfig
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2010-09-09 MRe  added renderquad functions for solidoutlined etc. 
    + *  2010-09-27 MRe  fixed quad render function
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_viewport.h"
    +#include "dave_render.h"
    +#include "dave_pattern.h"
    +#include "dave_quad.h"
    +#include "dave_edge.h"
    +#include "dave_line.h"
    +#include "dave_texture.h"
    +#include "dave_polyline.h"
    +
    +/*--------------------------------------------------------------------------*/
    +static d2_s32 d2_renderquad_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags );
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_s32 d2_renderquad_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags )
    +{
    +   d2_bbox bbox;
    +   d2_u32 bR1, bR2, bR3, bR4;
    +   d2_s32 flip, delay;
    +   d2_u32 control;
    +   d2_s32 ssd;
    +   d2_limdata edge[4];
    +
    +   /* find deltas */
    +   d2_s32 dx1 = x2 - x1;
    +   d2_s32 dx2 = x3 - x2;
    +   d2_s32 dx3 = x4 - x3;
    +   d2_s32 dx4 = x1 - x4;
    +   d2_s32 dy1 = y2 - y1;
    +   d2_s32 dy2 = y3 - y2;
    +   d2_s32 dy3 = y4 - y3;
    +   d2_s32 dy4 = y1 - y4;
    +
    +   /* build masks from signbits */
    +   d2_u32 dxm = ((dx1 < 0) ? 1u : 0u) | ((dx2 < 0) ? 2u : 0u) | ((dx3 < 0) ? 4u : 0u) | ((dx4 < 0) ? 8u : 0u);
    +   d2_u32 dym = ((dy1 < 0) ? 1u : 0u) | ((dy2 < 0) ? 2u : 0u) | ((dy3 < 0) ? 4u : 0u) | ((dy4 < 0) ? 8u : 0u);
    +   d2_u32 idxm = dxm ^ 15u;
    +   d2_u32 idym = dym ^ 15u;
    +
    +   /* catch degenerate quad (collapsed edge) and render a triangle instead */
    +   if(0 != (idxm & idym))
    +   {
    +      if(0 == (dx1 | dy1))   /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +      {
    +         return d2_rendertri( handle, x2, y2, x3, y3, x4, y4, flags >> 1 );
    +      }
    +      if(0 == (dx2 | dy2))   /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +      {
    +         return d2_rendertri( handle, x1, y1, x3, y3, x4, y4, ((flags & 12u ) >> 1) | (flags & 1u) );
    +      }
    +      if(0 == (dx3 | dy3))   /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +      {
    +         return d2_rendertri( handle, x1, y1, x2, y2, x4, y4, ((flags & 8u) >> 1) |  (flags & 3u) );
    +      }
    +      if(0 == (dx4 | dy4))   /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +      {
    +         return d2_rendertri( handle, x1, y1, x2, y2, x3, y3, flags & 7u );
    +      }
    +   }
    +
    +   /* classify edges (right edge flags) - basically inverted dys
    +    * but using dxs instead of dys for horizontal edges */
    +   bR1 = (dy1 == 0) ? (idxm & 1u) : (idym & 1u);
    +   bR2 = (dy2 == 0) ? (idxm & 2u) : (idym & 2u);
    +   bR3 = (dy3 == 0) ? (idxm & 4u) : (idym & 4u);
    +   bR4 = (dy4 == 0) ? (idxm & 8u) : (idym & 8u);
    +
    +
    +   /* get xmin, xmax and the endposition of spanstore(ssd) */
    +   if(x1 < x2)
    +   {
    +      bbox.xmin = x1;
    +      bbox.xmax = x2;
    +      ssd = y1;
    +   }
    +   else
    +   {
    +      bbox.xmin = x2;
    +      bbox.xmax = x1;
    +      ssd = y2;
    +   }
    +
    +   if(x3 < x4)
    +   {
    +      if(bbox.xmin > x3)
    +      {
    +         bbox.xmin = x3;
    +         ssd= y3;
    +      }
    +      if(bbox.xmax < x4)
    +      {
    +         bbox.xmax = x4;
    +      }
    +   }
    +   else
    +   {
    +      if(bbox.xmin > x4)
    +      {
    +         bbox.xmin = x4;
    +         ssd = y4;
    +      }
    +
    +      if(bbox.xmax < x3)
    +      {
    +         bbox.xmax = x3;
    +      }
    +   }
    +
    +   /* get ymin , ymax */
    +   if(y1 < y2)
    +   {
    +      bbox.ymin = y1;
    +      bbox.ymax = y2;
    +   }
    +   else
    +   {
    +      bbox.ymin = y2;
    +      bbox.ymax = y1;
    +   }
    +
    +   if(y3 < y4)
    +   {
    +      bbox.ymin = ( bbox.ymin < y3 ) ? bbox.ymin : y3 ;
    +      bbox.ymax = ( bbox.ymax > y4 ) ? bbox.ymax : y4 ;
    +   }
    +   else
    +   {
    +      bbox.ymin = ( bbox.ymin < y4 ) ? bbox.ymin : y4 ;
    +      bbox.ymax = ( bbox.ymax > y3 ) ? bbox.ymax : y3 ;
    +   }
    +
    +   bbox.xmin = (d2_point) D2_FLOOR4(bbox.xmin);
    +   bbox.ymin = (d2_point) D2_FLOOR4(bbox.ymin);
    +
    +   bbox.xmax = (d2_point) D2_CEIL4(bbox.xmax);
    +   bbox.ymax = (d2_point) D2_CEIL4(bbox.ymax);
    +
    +   /* calculate spanstoredelay */ 
    +   delay = (ssd - bbox.ymin) >> 4;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /* clipping */
    +   if(0 == d2_clipbbox_intern( handle, &bbox ))
    +   {
    +      return 0;
    +   }
    +
    +   /* set register values (material parameters) */
    +   d2_setupmaterial_intern( handle, ctx );
    +
    +   /* make relative */
    +   x1 = (d2_point)(x1 - bbox.xmin);
    +   y1 = (d2_point)(y1 - bbox.ymin);
    +   x2 = (d2_point)(x2 - bbox.xmin);
    +   y2 = (d2_point)(y2 - bbox.ymin);
    +   x3 = (d2_point)(x3 - bbox.xmin);
    +   y3 = (d2_point)(y3 - bbox.ymin);
    +   x4 = (d2_point)(x4 - bbox.xmin);
    +   y4 = (d2_point)(y4 - bbox.ymin);
    +
    +   /* calc edge interpolation parameters */
    +   control = 0;
    +
    +   if(0 == (ctx->features & d2_feat_aa))
    +   {
    +      flags |= d2_all_shared;
    +   }
    +
    +   if(0 != (flags & d2_edge0_shared))
    +   {
    +      d2_triedge_setup_intern( &edge[0], x1, y1, dx1, dy1, bR1 );
    +      control |= D2C_LIM1THRESHOLD;
    +      edge[0].start += D2_FIX16(1) / 2;
    +   }
    +   else
    +   {
    +      if(0 != (ctx->features & d2_feat_blur))
    +      {
    +         d2_triedge_setupblur_intern( &edge[0], x1, y1, dx1, dy1, ctx );
    +      }
    +      else 
    +      {
    +         d2_triedge_setup_intern( &edge[0], x1, y1, dx1, dy1, bR1 );
    +         edge[0].start += D2_FIX16(1);
    +      }
    +   }
    +
    +   if(0 != (flags & d2_edge1_shared))
    +   {
    +      d2_triedge_setup_intern( &edge[1], x2, y2, dx2, dy2, bR2 );
    +      control |= D2C_LIM2THRESHOLD;
    +      edge[1].start += D2_FIX16(1) / 2;
    +   }
    +   else
    +   {
    +      if(0 != (ctx->features & d2_feat_blur))
    +      {
    +         d2_triedge_setupblur_intern( &edge[1], x2, y2, dx2, dy2, ctx );
    +      }
    +      else 
    +      {
    +         d2_triedge_setup_intern( &edge[1], x2, y2, dx2, dy2, bR2 );
    +         edge[1].start += D2_FIX16(1);
    +      }
    +   }
    +
    +   if(0 != (flags & d2_edge2_shared))
    +   {
    +      d2_triedge_setup_intern( &edge[2], x3, y3, dx3, dy3, bR3 );
    +      control |= D2C_LIM3THRESHOLD;
    +      edge[2].start += D2_FIX16(1) / 2;
    +   }
    +   else
    +   {
    +      if(0 != (ctx->features & d2_feat_blur))
    +      {
    +         d2_triedge_setupblur_intern( &edge[2], x3, y3, dx3, dy3, ctx );
    +      }
    +      else 
    +      {
    +         d2_triedge_setup_intern( &edge[2], x3, y3, dx3, dy3, bR3 );
    +         edge[2].start += D2_FIX16(1);
    +      }
    +   }
    +
    +   if(0 != (flags & d2_edge3_shared))
    +   {
    +      d2_triedge_setup_intern( &edge[3], x4, y4, dx4, dy4, bR4 );
    +      control |= D2C_LIM4THRESHOLD;
    +      edge[3].start += D2_FIX16(1) / 2;
    +   }
    +   else
    +   {
    +      if(0 != (ctx->features & d2_feat_blur))
    +      {
    +         d2_triedge_setupblur_intern( &edge[3], x4, y4, dx4, dy4, ctx );
    +      }
    +      else 
    +      {
    +         d2_triedge_setup_intern( &edge[3], x4, y4, dx4, dy4, bR4 );
    +         edge[3].start += D2_FIX16(1);
    +      }
    +   }
    +
    +   /* optimize for span abort / span store */
    +   if ( ( bbox.ymax - ssd ) < ( ssd - bbox.ymin ) )
    +   {
    +      flip = 1;
    +      delay = (bbox.ymax - ssd  ) >> 4;  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +   else
    +   {
    +      flip = 0;
    +   }
    +
    +
    +   control |= D2C_LIM1ENABLE | D2C_LIM2ENABLE | D2C_LIM3ENABLE | D2C_LIM4ENABLE | D2C_SPANABORT | D2C_SPANSTORE; 
    +
    +   /* check for alpha gradients */
    +   if(0 != (ctx->alphamode & (d2_am_gradient1 | d2_am_gradient2)))
    +   {
    +      control = d2_initgradients_intern( handle, ctx, &bbox, 4, control );
    +
    +      if(0 == (control & D2C_SPANSTORE))
    +      {
    +         flip = 0;
    +      }
    +   }
    +
    +   /* bottom-up rendering / left edges are x-decreasing */
    +   if(0 != flip)
    +   {
    +      d2_s32 h = D2_INT4( bbox.ymax - bbox.ymin );   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +      d2_invertlimiter_intern(&edge[0], h);
    +      d2_invertlimiter_intern(&edge[1], h);
    +      d2_invertlimiter_intern(&edge[2], h);
    +      d2_invertlimiter_intern(&edge[3], h);
    +      d2_setuppattern( handle, ctx, &bbox, 1 );
    +      d2_setuptexture( handle, ctx, &bbox, 1 );
    +   }
    +   else
    +   {
    +      d2_setuppattern( handle, ctx, &bbox, 0 );
    +      d2_setuptexture( handle, ctx, &bbox, 0 );
    +   }
    +
    +   /* set register values (geometric parameters) */
    +   D2_DLISTWRITES( D2_L1START, edge[0].start );
    +   D2_DLISTWRITES( D2_L1XADD , edge[0].xadd );
    +   D2_DLISTWRITES( D2_L1YADD , edge[0].yadd );
    +   D2_DLISTWRITES( D2_L2START, edge[1].start );
    +   D2_DLISTWRITES( D2_L2XADD , edge[1].xadd );
    +   D2_DLISTWRITES( D2_L2YADD , edge[1].yadd );
    +   D2_DLISTWRITES( D2_L3START, edge[2].start );
    +   D2_DLISTWRITES( D2_L3XADD , edge[2].xadd );
    +   D2_DLISTWRITES( D2_L3YADD , edge[2].yadd );
    +   D2_DLISTWRITES( D2_L4START, edge[3].start );
    +   D2_DLISTWRITES( D2_L4XADD , edge[3].xadd );
    +   D2_DLISTWRITES( D2_L4YADD , edge[3].yadd );
    +   D2_DLISTWRITEU( D2_CONTROL,  control );
    +
    +   /* start rendering */
    +   if(0 != flip)
    +   {
    +      d2_startrender_bottom_intern( handle, &bbox, (d2_u32)delay + 1 );
    +   }
    +   else
    +   {
    +      d2_startrender_intern( handle, &bbox, (d2_u32)delay + 1 );
    +   }
    +
    +   return 1;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * shared edges do not contribute to vertex tangents. to implement this
    + * a set of line/open polyline/closed polyline configurations is used
    + * depending on the shared edge configuration
    + * */
    +d2_s32 d2_renderquad_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags)
    +{
    +   d2_width wo = (d2_width)(D2_DEV(handle)->outlinewidth * 2);
    +   d2_contextdata *ctx = D2_DEV(handle)->ctxoutline;
    +   d2_point verts[4*2];
    +
    +   /* isolate sharing flags */
    +   flags = flags & (d2_edge0_shared | d2_edge1_shared | d2_edge2_shared | d2_edge3_shared);
    +
    +   /* skip invisible cases */
    +   if(wo < D2_EPSILON)
    +   {
    +      return D2_OK;
    +   }
    +
    +   /* special case all sharing combinations */
    +   switch(flags)
    +   {
    +      /* no shared edge - use a closed polyline */
    +      case 0:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x2;  verts[3] = y2;
    +         verts[4] = x3;  verts[5] = y3;
    +         verts[6] = x4;  verts[7] = y4;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 4, wo, d2_le_closed, 0, 0 );
    +         break;
    +
    +         /* single shared edge - use an open polyline */
    +      case d2_edge0_shared:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x4;  verts[3] = y4;
    +         verts[4] = x3;  verts[5] = y3;
    +         verts[6] = x2;  verts[7] = y2;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 4, wo, d2_le_exclude_both, 0, 0 );
    +         break;
    +
    +      case d2_edge1_shared:
    +         verts[0] = x2;  verts[1] = y2;
    +         verts[2] = x1;  verts[3] = y1;
    +         verts[4] = x4;  verts[5] = y4;
    +         verts[6] = x3;  verts[7] = y3;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 4, wo, d2_le_exclude_both, 0, 0 );
    +         break;
    +
    +      case d2_edge2_shared:
    +         verts[0] = x4;  verts[1] = y4;
    +         verts[2] = x1;  verts[3] = y1;
    +         verts[4] = x2;  verts[5] = y2;
    +         verts[6] = x3;  verts[7] = y3;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 4, wo, d2_le_exclude_both, 0,0 );
    +         break;
    +
    +      case d2_edge3_shared:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x2;  verts[3] = y2;
    +         verts[4] = x3;  verts[5] = y3;
    +         verts[6] = x4;  verts[7] = y4;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 4, wo, d2_le_exclude_both, 0, 0 );
    +         break;
    +
    +         /* two adjacent shared edges - use two lines */
    +      case d2_edge0_shared | d2_edge1_shared:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x4;  verts[3] = y4;
    +         verts[4] = x3;  verts[5] = y3;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_exclude_both, 0,0 );
    +         break;
    +
    +      case d2_edge1_shared | d2_edge2_shared:
    +         verts[0] = x4;  verts[1] = y4;
    +         verts[2] = x1;  verts[3] = y1;
    +         verts[4] = x2;  verts[5] = y2;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_exclude_both, 0, 0 );
    +         break;
    +
    +      case d2_edge2_shared | d2_edge3_shared:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x2;  verts[3] = y2;
    +         verts[4] = x3;  verts[5] = y3;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_exclude_both, 0, 0 );
    +         break;
    +
    +      case d2_edge3_shared | d2_edge0_shared:
    +         verts[0] = x2;  verts[1] = y2;
    +         verts[2] = x3;  verts[3] = y3;
    +         verts[4] = x4;  verts[5] = y4;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_exclude_both, 0, 0);
    +         break; 
    +
    +         /* two opposite shared edges - use a single lines */
    +      case d2_edge0_shared | d2_edge2_shared:
    +         (void)d2_renderline_outline_I( handle, x1, y1, x4, y4, wo, d2_le_exclude_both );
    +         (void)d2_renderline_outline_I( handle, x3, y3, x2, y2, wo, d2_le_exclude_both );
    +         break;
    +
    +      case d2_edge1_shared | d2_edge3_shared:
    +         (void)d2_renderline_outline_I( handle, x2, y2, x1, y1, wo, d2_le_exclude_both );
    +         (void)d2_renderline_outline_I( handle, x4, y4, x3, y3, wo, d2_le_exclude_both );
    +         break;
    +
    +         /* three shared edges - use a single lines */
    +      case d2_edge0_shared | d2_edge1_shared | d2_edge2_shared:
    +         (void)d2_renderline_outline_I( handle, x1, y1, x4, y4, wo, d2_le_exclude_both );
    +         break;
    +
    +      case d2_edge0_shared | d2_edge1_shared | d2_edge3_shared:
    +         (void)d2_renderline_outline_I( handle, x4, y4, x3, y3, wo, d2_le_exclude_both );
    +         break;
    +
    +      case d2_edge0_shared | d2_edge2_shared | d2_edge3_shared:
    +         (void)d2_renderline_outline_I( handle, x3, y3, x2, y2, wo, d2_le_exclude_both );
    +         break;
    +
    +      case d2_edge1_shared | d2_edge2_shared | d2_edge3_shared:
    +         (void)d2_renderline_outline_I( handle, x1, y1, x2, y2, wo, d2_le_exclude_both );
    +         break;
    +
    +         /* more than three shared edges - no outline at all */
    +
    +      default:
    +         break;
    +   }
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderquad_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags )
    +{
    +   (void)d2_renderquad_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1,y1, x2,y2, x3,y3, x4,y4, flags );
    +      
    +   /* HACK: replaced with rendering two triangles */
    +/*
    +  d2_rendertri_solid( handle, x1,y1, x2,y2, x3,y3, flags | d2_edge2_shared );
    +  d2_rendertri_solid( handle, x3,y3, x4,y4, x1,y1, (flags >> 2) | d2_edge2_shared );
    +*/
    + 
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderquad_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags )
    +{
    +
    +   /* render outline */
    +   (void)d2_renderquad_outline( handle, x1,y1, x2,y2, x3,y3, x4,y4, flags );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderquad_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1,y1, x2,y2, x3,y3, x4,y4, flags );
    +
    +   d2_rendertobase_intern( handle );
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderquad_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags )
    +{
    +   d2_point sx,sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_renderquad_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1+sx),(d2_point)(y1+sy), (d2_point)(x2+sx),(d2_point)(y2+sy), (d2_point)(x3+sx), (d2_point)(y3+sy), (d2_point)(x4+sx), (d2_point)(y4+sy), flags );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderquad_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags )
    +{
    +   d2_point sx,sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_renderquad_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1+sx), (d2_point)(y1+sy), (d2_point)(x2+sx), (d2_point)(y2+sy), (d2_point)(x3+sx), (d2_point)(y3+sy), (d2_point)(x4+sx), (d2_point)(y4+sy), flags );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderquad_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, x3, y3, x4, y4, flags );
    +
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    diff --git a/src/drivers/dave2d/src/dave_rbuffer.c b/src/drivers/dave2d/src/dave_rbuffer.c
    new file mode 100644
    index 000000000..c9de9976b
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_rbuffer.c
    @@ -0,0 +1,1344 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_rbuffer.c (%version: 27 %)
    + *          created Tue May 10 09:42:13 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Jan 26 13:50:26 2007 %  (%derived_by:  hh74026 %)
    + *
    + * Changes:
    + *  2005-12-22 CSe  d2_executerenderbuffer(): removed wait for finish of dlist
    + *  2006-04-12 CSe  fixed comments for correct documentation
    + *  2006-07-21 CSe  implemented d2_relocateframe()
    + *  2006-10-30 CSe  removed counting of dlist used slots
    + *  2006-11-07 CSe  changes for new 'd2_df_low_localmem' mode
    + *  2007-12-10 ASc  fix error checking in d2_newrenderbuffer
    + *  2007-12-11 ASc  fix d2_relocateframe: flush scratch buffer
    + *  2007-12-12 ASc  add buffer argument check in d2_freedumpedbuffer
    + *                  add d2_getrenderbuffersize function
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs 
    + *  2009-03-06 LBe  added flag in d2_executerenderbuffer to keep dlist for multiple execution
    + *  2011-03-10 MRe  fixed delayed error handling in d2_executerenderbuffer
    + *  2012-01-26 MRe  fixed flushing of renderbuffer when a new one is selected
    + *  2012-07-18 MRe  improved render buffer management
    + *  2012-09-25 BSp  MISRA cleanup
    + */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Render Buffers
    + * Renderbuffers (similar in concept to OpenGL display lists) are the main
    + * interface between driver and hardware.
    + *
    + * Issuing rendering commands to the D/AVE driver does not directly trigger
    + * a hardware activity but adds a set of commands to the currently _selected_
    + * Renderbuffer (see: <d2_selectrenderbuffer>).
    + *
    + * This buffer can be executed directly by the hardware. For best performance
    + * and maximum parallelism there should always be one renderbuffer executing
    + * while another one is being filled (double-buffered render buffers).
    + *
    + * The application can manage this on its own by using <d2_selectrenderbuffer>
    + * and <d2_executerenderbuffer> or make use of the utility functions and internal
    + * buffers (see: <d2_startframe> and <d2_endframe>).
    + *
    + * startframe / endframe:
    + * The recommended method using double-buffered render buffers is to use <d2_startframe> and
    + * <d2_endframe>. These functions use two internal render buffers in turn.
    + * The internal render buffers can be accessed by <d2_getrenderbuffer>.
    + * (start code)
    + * d2_startframe(handle); // --> start HW rendering of the previous frame (buffer a), switch to buffer b for all following render commands
    + *
    + * // ... now issue new render commands to buffer b while HW is rendering the previous frame from render buffer a ...
    + *
    + * d2_endframe(handle); // --> close render buffer b which has just captured all render commands, wait for HW to finish rendering of buffer a
    + *
    + * // may now propagate the rendered frame (from buffer a) to the display controller
    + * (end code)
    + *
    + * selectrenderbuffer / executerenderbuffer / flushframe:
    + * Render buffers can also be managed by the application. Use <d2_newrenderbuffer> to 
    + * allocate a new render buffer. To issue render commands a render buffer must be 
    + * selected by <d2_selectrenderbuffer>. A render buffer can then be executed by
    + * <d2_executerenderbuffer>. Before <d2_executerenderbuffer> can be called again
    + * the application has to wait for Dave to be finished by <d2_flushframe>.
    + * (start code)
    + * d2_selectrenderbuffer(handle, buffer);
    + *
    + * // issue render commands
    + *
    + * d2_executerenderbuffer(handle, buffer);
    + * d2_flushframe(handle);
    + * // propagate the rendered frame to the display controller
    + * (end code)
    + *
    + * Using a single render buffer:
    + * 
    + * Please note that when using just a single render buffer (no double-buffering) 
    + * the allocated buffer can not be freed as long as it is selected because the 
    + * buffer will be linked for internal usage. This means that another call of 
    + * <d2_selectrenderbuffer> must be issued with a second buffer to de-select the 
    + * previous buffer to avoid memory leaks. 
    + *
    + * (start code)
    + * buffer = d2_newrenderbuffer(handle, 25, 25);
    + * d2_selectrenderbuffer(handle, buffer);
    + * d2_executerenderbuffer(handle, buffer, d2_ef_default);
    + * d2_flushframe(handle);
    + * ...
    + * // select a different buffer before freeing
    + * d2_selectrenderbuffer(handle, newbuffer);
    + * d2_freerenderbuffer(handle, buffer);
    + * (end code)
    + *
    + * If no second render buffer is available and only a single render buffer 
    + * should be used the following two commands have to be called before creating 
    + * any render buffer. This will prevent internal buffer linkage!
    + * 
    + * (start code)
    + * // close internal render buffer 0
    + * d2_executerenderbuffer(locD2DHandle,d2_getrenderbuffer(locD2DHandle, 0), 0); 
    + * // close internal render buffer 1
    + * d2_executerenderbuffer(locD2DHandle,d2_getrenderbuffer(locD2DHandle, 1), 0); 
    + * ...
    + * buffer = d2_newrenderbuffer(handle, 25, 25);
    + * d2_selectrenderbuffer(handle, buffer);
    + * d2_executerenderbuffer(handle, buffer, d2_ef_default);
    + * d2_flushframe(handle);
    + * d2_freerenderbuffer(handle, buffer); // free a selected buffer
    + * (end code)
    + *
    + * However, it is recommended to use at least two render buffers, e.g. 
    + * <d2_startframe> and <d2_endframe>.
    + *
    + * executedlist:
    + * Instead of <d2_executerenderbuffer> a given Dlist can be executed directly by
    + * <d2_executedlist>.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_memory.h"
    +#include "dave_rbuffer.h"
    +
    +
    +/*--------------------------------------------------------------------------*/
    +static d2_s32 d2_resizerblayer_intern( const d2_device *handle, d2_rb_layer *layer ); /* MISRA */
    +static void d2_scratchgrowlayer_intern( d2_device *handle );
    +
    +
    +/*--------------------------------------------------------------------------
    + * Group: Renderbuffer Management */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_newrenderbuffer
    + * Create a new renderbuffer.
    + *
    + * Renderbuffers are filled by the driver but read (executed) directly by the
    + * Dave hardware. Buffers grow on demand but only shrink slowly:
    + * If a page was not used for 60 calls of <d2_executerenderbuffer>, the page
    + * is freed one at a time: The next page will not be freed before 60 further
    + * calls have elapsed.
    + *
    + * A single displaylist entry requires 20bytes of memory, choosing large
    + * page sizes is potential waste of memory while too many small pages can
    + * degrade the performance of both reading and writing to the buffer.
    + *
    + * By using <d2_getrenderbuffersize>, it is possible to query the number of used
    + * entries for a given application. This can be used to optimize the page size.
    + *
    + * The number of used pages of the renderbuffer currently used as writebuffer
    + * can be queried using <d2_getdlistblockcount>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   initialsize - number of displaylist entries in the first page (minimum is 3)
    + *   stepsize - number of displaylist entries in following pages (minimum is 3)
    + *
    + * returns:
    + *   pointer to internal renderbuffer (or NULL if failed)
    + *
    + * see also:
    + *   <d2_getrenderbuffer>, <d2_setdlistblocksize>, <d2_freerenderbuffer>
    + * */
    +d2_renderbuffer * d2_newrenderbuffer( d2_device *handle, d2_u32 initialsize, d2_u32 stepsize )
    +{
    +   d2_rbuffer *rbuffer;
    +   d2_s32 bOOM = 0;
    +
    +   /* error checking */
    +   if(NULL == handle)
    +   {
    +      return NULL;
    +   }
    +
    +   if( (initialsize <= 2) || (stepsize <= 2) )
    +   {
    +      (void)D2_SETERR(handle, D2_VALUETOOSMALL);
    +      return NULL;
    +   }
    +
    +   /* create new display list (/renderbuffer) */
    +   rbuffer = (d2_rbuffer*) d2_getmem_p( sizeof(d2_rbuffer) );
    +
    +   if(NULL != rbuffer)
    +   {
    +      rbuffer->layer[0].scratch = NULL;
    +
    +      if(0 != d2_initdlist_intern( handle, &rbuffer->baselist, initialsize ))
    +      {
    +         if(0 == D2_DEV(handle)->lowlocalmem_mode)
    +         {
    +            /* rblayer only in case of normal (no lowlocalmem mode) */
    +
    +            if(0 == d2_initrblayer_intern( handle, &rbuffer->layer[0], D2_DLISTSCRATCH ))
    +            {
    +               bOOM = 1;
    +            }
    +         }
    +      }
    +      else
    +      {
    +         bOOM = 1;
    +      }
    +   }
    +   else
    +   {
    +      bOOM = 1;
    +   }
    +
    +   if(0 == bOOM)
    +   {
    +      /* fill additional data */
    +      rbuffer->baselist.stepsize = stepsize;
    +      rbuffer->baselist.busy = 0;
    +      rbuffer->closed = 0;
    +
    +      (void)D2_SETOK( handle );
    +
    +      /* Succeeded */
    +      return rbuffer;
    +   }
    +   else
    +   {
    +      (void)D2_SETERR( handle, D2_NOMEMORY );
    +
    +      if(NULL != rbuffer)
    +      {
    +         d2_freemem_p(rbuffer);
    +      }
    +
    +      /* Failed */
    +      return NULL;
    +   }
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_freerenderbuffer
    + * Destroy and free a renderbuffer.
    + *
    + * You can only free buffers that were created by <d2_newrenderbuffer> and are
    + * not currently executed. To make sure execution has finished the application
    + * can call <d2_flushframe>.
    + *
    + * note:
    + * Please note that when using just a single render buffer (no double buffering) 
    + * the allocated buffer can not be freed as long as it is selected (see above for 
    + * more details).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   buffer - renderbuffer address
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * */
    +d2_s32 d2_freerenderbuffer( d2_device *handle,  d2_renderbuffer *buffer )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( buffer, D2_INVALIDBUFFER );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( D2_DRB(buffer)->baselist.device == D2_DEV(handle) , D2_INVALIDDEVICE ); /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* check if list is currently executed */
    +   if(0 != D2_DRB(buffer)->baselist.busy)
    +   {
    +      D2_RETERR( handle, D2_DEVICEBUSY );
    +   }
    +
    +   /* do not allow removal of default buffers */
    +   if(
    +      (D2_DEV(handle)->renderbuffer[0] == D2_DRB(buffer)) ||
    +      (D2_DEV(handle)->renderbuffer[1] == D2_DRB(buffer))
    +      )
    +   {
    +      D2_RETERR( handle, D2_DEFBUFFER );
    +   }
    +
    +   if(D2_DEV(handle)->selectedbuffer == D2_DRB(buffer))
    +   {
    +      D2_DEV(handle)->selectedbuffer = D2_DRB(D2_DEV(handle)->writelist);
    +   }
    +
    +   /* destruct all display list buffers */
    +   d2_deinitdlist_intern(&(D2_DRB(buffer)->baselist));
    +
    +   if(NULL != D2_DRB(buffer)->layer[0].scratch)
    +   {
    +      d2_freemem_p( D2_DRB(buffer)->layer[0].scratch );
    +   }
    +
    +   d2_freemem_p( buffer );
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_selectrenderbuffer
    + * Choose a renderbuffer for writing.
    + * Selecting a buffer that is currently executed will cause rendering failures.
    + *
    + * The previously selected renderbuffer is flushed.
    + * All subsequent <Rendering Functions> write to the specified renderbuffer.
    + * The buffer is finalized when <d2_executerenderbuffer> is called.
    + * The render buffer is reset for writing a new list after selection.
    + *
    + * For the usage of render buffers see <Render Buffers>.
    + *
    + * If buffer is 0 then the internal renderbuffer for writing will be selected, thus 
    + * <d2_startframe>/<d2_endframe> can be continued to use 
    + * (see also <d2_getrenderbuffer>).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   buffer - renderbuffer address or 0
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_selectrenderbuffer( d2_device *handle, d2_renderbuffer *buffer )
    +{
    +#ifdef D2_USEREGCACHE
    +   d2_s32 i;
    +#endif
    +   d2_dlist *wlist;
    +   void     *current_dlist_start;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* flush old render buffer */
    +   d2_scratch2dlist_intern(handle);
    +
    +   if(NULL != D2_DEV(handle)->lowlocalmem_mode)
    +   {
    +      d2_dlist *dlist = &D2_DEV(handle)->selectedbuffer->baselist;
    +
    +      if( (buffer != dlist)  && (0 == D2_DEV(handle)->selectedbuffer->closed) )
    +      {
    +         /* make sure to copy rest of dlist vidmem and add a jump to next slice */
    +         d2_paddlist_intern(dlist);
    +         (void)d2_insertdlistjump_intern( dlist, NULL );
    +         (void)d2_preparedlist_read_intern(handle, dlist, 0);
    +      }
    +   }
    +
    +   /* use internal writelist */
    +   if(NULL == buffer)
    +   {
    +      buffer = D2_DEV(handle)->writelist;
    +   }
    +
    +   /* reset list closed flag when selecting a render buffer */
    +   ((d2_rbuffer*)buffer)->closed = 0;
    +   
    +   /* hard change of writelist */
    +   D2_DEV(handle)->selectedbuffer = D2_DRB(buffer);
    +   wlist = & D2_DRB(buffer)->baselist;
    +   D2_DEV(handle)->srccontext = NULL;
    +
    +   if(0 != wlist->busy)
    +   {
    +      /*note - might add a flush here
    +       * list needs reset */
    +      wlist->busy = 0;
    +      d2_resetdlist_intern( wlist );
    +   }
    +
    +   if(NULL != wlist->vidmem_blocks)
    +   {
    +      /* low localmem mode: vidmem is already filled */
    +      current_dlist_start = wlist->vidmem_blocks->blocks[0];
    +   }
    +   else if( (0 != (D2_DEV(handle)->hwmemarchitecture & (d1_ma_separated | d1_ma_mapped))) &&  (NULL != wlist->firstblock->vidmem) )
    +   {
    +      current_dlist_start = wlist->firstblock->vidmem;
    +   }
    +   else
    +   {
    +      current_dlist_start = wlist->firstblock->block;
    +   }
    +
    +   /* init list of dlist start addresses */
    +   d2_clear_dlistlist_intern(handle, wlist);
    +   (void)d2_add_dlistlist_intern(handle, wlist, current_dlist_start);
    +
    +   /* invalidate register cache at start of new dlist
    +    * (inter-list optimisation is considered too risky) */
    +#ifdef D2_USEREGCACHE
    +   if(0 == (D2_DEV(handle)->flags & d2_df_no_registercaching))
    +   {
    +      for(i=0; i<D2_QUANTITY; i++)
    +      {
    +         D2_DEV(handle)->cache.valid[i] = 0;
    +      }
    +   }
    +#endif
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_executerenderbuffer
    + * Render the content of a renderbuffer.
    + *
    + * For the usage of render buffers see <Render Buffers>.
    + *
    + * Before rendering is started, the renderbuffer is prepared for execution. This
    + * involves flushing of scratch buffers, possibly merge of layers in certain render modes (see <d2_selectrendermode>)
    + * and potentially copying the display list to a dedicated video memory or at least flushing of the 
    + * CPU data caches.
    + * The buffer passed to d2_executerenderbuffer can be used for execution again by calling d2_executerenderbuffer
    + * again with the same buffer as argument. But before new render commands can be written to the buffer
    + * it must be selected by <d2_selectrenderbuffer>.
    + *
    + * Note that before calling d2_executerenderbuffer, it must be made sure that no render buffer is currently
    + * executed on the hardware. This can be done by either waiting for the respective interrupt or by calling <d2_flushframe>.
    + *
    + * Note that even when <d2_flushframe> is issued to wait for the rendering of the buffer to finish
    + * the buffer still has to be reselected (using <d2_selectrenderbuffer>) in order
    + * to use it again for rendering.
    + *
    + * Note that calling this function from inside an interrupt service routine is not recommended, as the
    + * execution time can not be foreseen. If it is called from inside the D/AVE 'display list finished' ISR anyway,
    + * it needs to be made sure that clearing the IRQ happens before the call to d2_executerenderbuffer!
    + * Register writes to the D/AVE core are not allowed while a display list is being executed.
    + *
    + * Note that if d2_ef_execute_once is used a new render buffer must be selected by <d2_selectrenderbuffer>
    + * even if it is the same render buffer.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   buffer - renderbuffer address
    + *   flags  - (not used)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * */
    +d2_s32 d2_executerenderbuffer( d2_device *handle, d2_renderbuffer *buffer, d2_u32 flags )
    +{
    +   d2_s32 errorCode=0;
    +   d2_dlist *rlist;
    +   d2_renderbuffer *selectedBuffer;
    +   (void) flags;                              /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );   /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( buffer, D2_INVALIDBUFFER );   /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( D2_DRB(buffer)->baselist.device== D2_DEV(handle) , D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* set selected buffer temporarily to buffer */
    +   selectedBuffer = D2_DEV(handle)->selectedbuffer;
    +   D2_DEV(handle)->selectedbuffer = buffer;
    +
    +   /* check if list is currently executed */
    +   if(0 != D2_DRB(buffer)->baselist.busy)
    +   {
    +      D2_RETERR( handle, D2_DEVICEBUSY );
    +   }
    +   
    +   /* new read list */
    +   rlist = & D2_DRB( buffer )->baselist;
    +
    +   /* start new list */
    +   rlist->busy = 1;
    +
    +   if(0 == D2_DRB(buffer)->closed ) 
    +   {
    +      /* reset postprocessing mode if still active */
    +      if(d2_rm_postprocess == D2_DEV(handle)->rendermode)
    +      {
    +         (void)d2_selectrendermode( handle, d2_rm_solid );
    +      }
    +
    +      /* merge in layers if they contain data */
    +      d2_layer2dlist_intern( handle );
    +
    +      (void)d2_preparedlist_read_intern( handle, rlist, 1 );
    +   }
    +
    +   D2_DRB(buffer)->closed = 1;
    +
    +   /* start new displaylist */
    +   d2hw_start( handle, rlist, 0 );
    +   rlist->busy = 0;
    +
    +   /* restore selected buffer */
    +   D2_DEV(handle)->selectedbuffer = selectedBuffer;
    +
    +   errorCode = D2_DEV(handle)->delayed_errorcode;
    +   D2_DEV(handle)->delayed_errorcode = D2_OK;  /* reset errorcode */
    +   D2_RETERR( handle, errorCode);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getrenderbuffer
    + * Return internal renderbuffers.
    + *
    + * Two renderbuffers are allocated automatically for every device. These cannot
    + * be freed manually (destruction is automatic) but can be used for rendering.
    + *
    + * Note that if internal buffers are used the utility functions <d2_startframe> and
    + * <d2_endframe> might not work as expected anymore. These functions use both internal
    + * buffers for 'double buffering' and rely on using <d2_selectrenderbuffer> exclusively.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - renderbuffer index (only 0 and 1 are valid indices)
    + *
    + * returns:
    + *   pointer to internal renderbuffer (or NULL if failed)
    + * */
    +d2_renderbuffer * d2_getrenderbuffer( d2_device *handle, d2_s32 index )
    +{
    +   d2_rbuffer *rbuffer;
    +
    +   /* error checking */
    +   if(NULL == handle)
    +   {
    +      return NULL;
    +   }
    +
    +   if( (index < 0) || (index > 1) )
    +   {
    +      (void)D2_SETERR(handle, D2_INVALIDINDEX);
    +      return NULL;
    +   }
    +
    +   /* get buffer */
    +   rbuffer = D2_DEV(handle)->renderbuffer[ index ];
    +
    +   if(NULL == rbuffer)
    +   {
    +      (void)D2_SETERR(handle, D2_INVALIDBUFFER);
    +      return NULL;
    +   }
    +
    +   (void)D2_SETOK(handle);
    +   return rbuffer;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * Group: Utility Functions */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_startframe
    + * Mark the begin of a scene.
    + *
    + * Use this function (together with <d2_endframe>) to let the driver handle
    + * render buffer execution and flipping automatically.
    + *
    + * When startframe is called the render buffer that was filled during the
    + * last frame (between previous <d2_startframe>/<d2_endframe>) is executed on the HW.
    + * New render commands that are sent after this 'startframe' are put into the other
    + * render buffer.
    + *
    + * For the usage of render buffers see <Render Buffers>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_startframe( d2_device *handle )
    +{
    +   d2_s32 errorCode=0;
    +   d2_dlist *rlist, *wlist;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* backup current pointers */
    +   rlist = D2_DEV(handle)->readlist;
    +   wlist = D2_DEV(handle)->writelist;
    +
    +   /* start rendering of last frame's writelist */
    +   errorCode = d2_executerenderbuffer( handle, wlist, 0 );
    +
    +   /* prepare old readlist for writing */
    +   (void)d2_selectrenderbuffer( handle, rlist );
    +
    +   /* hard-swap read and write buffers */
    +   D2_DEV(handle)->readlist  = wlist;
    +   D2_DEV(handle)->writelist = rlist;
    +
    +   D2_RETERR( handle, errorCode);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_endframe
    + * Mark the end of a scene.
    + *
    + * Use this function (together with <d2_startframe>) to let the driver handle
    + * render buffer execution and flipping automatically.
    + *
    + * Endframe makes sure the previous frame (the one started on the HW by the last
    + * call of <d2_startframe>) has been rendered completely. A wait for the HW
    + * is done if necessary.
    + * The render buffer just filled with render commands (since the last <d2_startframe>)
    + * is logically closed.
    + *
    + * For the usage of render buffers see <Render Buffers>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_endframe( d2_device *handle )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* wait for rendering to end */
    +   (void)d2_flushframe( handle );
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_relocateframe
    + * Change framebuffer for render commands already issued.
    + *
    + * This function can be used to change the target framebuffer of all d2
    + * render commands that have been issued since the last <d2_startframe>.
    + *
    + * It does only work if framebuffer format and size stay the same and only
    + * a single framebuffer has been set used <d2_framebuffer> since the
    + * frame has been started.
    + * The current framebuffer is _not_ changed, this would require a
    + * call to <d2_framebuffer> afterwards.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ptr - new address of the top left pixel (coordinate 0,0)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * note:
    + *   Intention of this function is to support an immediate flush to a hidden
    + *   framebuffer when the frame currently assembled was initially prepared
    + *   for the currently displayed framebuffer.
    + *   Use <d2_layermerge> to take care about outline and solid parts.
    + *
    + *   This function can only be used when double word clearing is
    + *   disabled (see: <d2_opendevice>) and 'low localmem' mode is not enabled
    + *   (see: <d2_lowlocalmemmode>)! 
    + *
    + * note:
    + *   If <d2_adddlist> (d2_al_no_copy) commands have been used these added 
    + *   dlists are not changed.
    + *
    + * */
    +extern d2_s32 d2_relocateframe( d2_device *handle, const void *ptr )
    +{
    +   d2_u32          adrmask;
    +   d2_dlist_block *blk, *lastBlk;
    +   d2_dlist_entry *lastEntry;
    +   d2_s8 *         oldPtr;
    +  
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ptr, D2_NOVIDEOMEM );        /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   d2_scratch2dlist_intern(handle);
    +
    +   blk     = D2_DEV(handle)->selectedbuffer->baselist.firstblock;
    +   lastBlk = D2_DEV(handle)->selectedbuffer->baselist.currentblock;
    +   oldPtr  = (d2_s8*)D2_DEV(handle)->framebuffer;
    +
    +   if(ptr == oldPtr)
    +   {
    +      D2_RETOK(handle);
    +   }
    +
    +   while(NULL != blk)
    +   {
    +      d2_u32 argument = 0;
    +      d2_dlist_entry *entry = blk->block;
    +
    +      lastEntry = (d2_dlist_entry*)((d2_s32*)entry + (blk->quantity*(sizeof(d2_dlist_entry)/sizeof(d2_s32))));  /* step through all entries in the block */
    +
    +      while(entry < lastEntry)  
    +      {
    +         adrmask = entry->address.mask;
    +
    +         if(0 != (adrmask & 0x80808080u))
    +         {
    +            /* contains special indices */
    +            if(adrmask == 0x80808080u)
    +            {
    +               /* completely empty -> skip */
    +               entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +            }
    +            else if(0 != (adrmask & 0x00008000u))
    +            {
    +               /* index1 only */
    +               if(D2_DLISTSTART == (adrmask & 0xffu))
    +               {
    +                  /* catch special case of display list jump */
    +                  entry = lastEntry; /*break;*/ /* skip this block */
    +               }
    +               else
    +               {
    +                  /* normal rewrite */
    +                  if(D2_ORIGIN == (adrmask & 0xffu))
    +                  {
    +                     entry->value[0] = (d2_s32) (((d2_s8*)entry->value[0] - oldPtr) + (d2_s8*)ptr);
    +                  }
    +
    +                  entry = (d2_dlist_entry*) ((d2_s32*)entry + 2);
    +               }
    +            }
    +            else if(0 != (adrmask & 0x00800000u))
    +            {
    +               /* index1&2 only */
    +               if(0xffu == (adrmask & 0xffu))
    +               {
    +                  /* end of list word */
    +                  argument = (adrmask >> 8) & 0xffu;
    +
    +                  if( (0 != (argument & 2u)) || (0 != (argument & 4u)) ) /* special bit 1 or 2 set? */
    +                  {
    +                     /* just a flush. keep on reading */
    +                     entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +                     /*continue;*/
    +                  } 
    +                  else
    +                  {   /* special bit 0 must be set */
    +                     /* terminate */
    +                     entry = lastEntry; /*break;*/
    +                  }
    +               }
    +               else 
    +               {
    +                  if(D2_ORIGIN == (adrmask & 0xffu))
    +                  {
    +                     entry->value[0] = (d2_s32) (((d2_s8*)entry->value[0] - oldPtr) + (d2_s8*)ptr);
    +                  }
    +                  
    +                  if((D2_ORIGIN<<8) == (adrmask & 0xff00u))
    +                  {
    +                     entry->value[1] = (d2_s32) (((d2_s8*)entry->value[1] - oldPtr) + (d2_s8*)ptr);
    +                  }
    +                  
    +                  entry = (d2_dlist_entry*) ((d2_s32*)entry + 3);
    +               }
    +            }
    +            else if (0 != (adrmask & 0x80000000u))
    +            {
    +               /* index1,2,3 only */
    +               if(D2_ORIGIN == (adrmask & 0xffu))
    +               {
    +                  entry->value[0] = (d2_s32) (((d2_s8*)entry->value[0] - oldPtr) + (d2_s8*)ptr);
    +               }
    +
    +               if((D2_ORIGIN<<8) == (adrmask & 0xff00u))
    +               {
    +                  entry->value[1] = (d2_s32) (((d2_s8*)entry->value[1] - oldPtr) + (d2_s8*)ptr);
    +               }
    +
    +               if((D2_ORIGIN<<16) == (adrmask & 0xff0000u))
    +               {
    +                  entry->value[2] = (d2_s32) (((d2_s8*)entry->value[2] - oldPtr) + (d2_s8*)ptr);
    +               }
    +
    +               entry = (d2_dlist_entry*) ((d2_s32*)entry + 4);
    +            }
    +            else
    +            {
    +               /* end of list word */
    +               if(0xffu == (adrmask & 0xffu))
    +               {
    +                  /* get eol argument */
    +                  argument = (adrmask >> 8) & 0xffu;
    +
    +                  if( (argument == 2u) || (argument == 4u) )
    +                  {
    +                     /* just a flush. keep on reading */
    +                     entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +                  }
    +                  else
    +                  {
    +                     /* terminate */
    +                     entry = lastEntry; /*break;*/
    +                  }
    +               }
    +               else
    +               {
    +                  /* invalid case, no index used */
    +                  entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +               }
    +            }
    +         } /* if(0 != (adrmask & 0x80808080u)) */
    +         else
    +         {
    +            /* contains simple indices only */
    +            if(D2_ORIGIN == (adrmask & 0xffu))
    +            {
    +               entry->value[0] = (d2_s32) (((d2_s8*)entry->value[0] - oldPtr) + (d2_s8*)ptr);
    +            }
    +
    +            if((D2_ORIGIN<< 8) == (adrmask & 0x0000ff00u))
    +            {
    +               entry->value[1] = (d2_s32) (((d2_s8*)entry->value[1] - oldPtr) + (d2_s8*)ptr);
    +            }
    +
    +            if((D2_ORIGIN<<16) == (adrmask & 0x00ff0000u))
    +            {
    +               entry->value[2] = (d2_s32) (((d2_s8*)entry->value[2] - oldPtr) + (d2_s8*)ptr);
    +            }
    +
    +            if((D2_ORIGIN<<24) == (adrmask & 0xff000000u) )
    +            {
    +               entry->value[3] = (d2_s32) (((d2_s8*)entry->value[3] - oldPtr) + (d2_s8*)ptr);
    +            }
    +
    +            /* next entry */
    +            entry++;
    +         }
    +
    +      } /* while entry < lastEntry */
    +
    +      if(0 != (argument & 1u))
    +      {
    +         blk = NULL; /*break;*/
    +      }
    +      else
    +      {
    +         blk = (blk == lastBlk) ? NULL : blk->next;
    +      }
    +
    +   } /* while (NULL != blk) */
    +
    +   D2_RETOK(handle);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_dumprenderbuffer
    + * Copy the content of a renderbuffer into user memory.
    + *
    + * The entire renderbuffer is stored as one flat dave displaylist in memory.
    + * Writes to the displaylist control register (display list jumps) are removed
    + * and replaced by the code following at the new address - this way the dumped
    + * list can be relocated in memory.
    + *
    + * Note that the application has to free the memory allocated for a dumped list
    + * using <d2_freedumpedbuffer>.
    + *
    + * This function can only be used when double word clearing is
    + * disabled (see: <d2_opendevice>) and 'low localmem' mode is not enabled (see: <d2_lowlocalmemmode>).
    + *
    + * note:
    + * Use <d2_layermerge> to take care about outline and solid parts.
    + *
    + * note:
    + *  d2_dumprenderbuffer does not work correctly if <d2_adddlist> (d2_al_no_copy)
    + *  commands have been used. 
    + *  Use <d2_adddlist> (d2_al_copy) instead if you want to get dlists with the
    + *  desired content.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   buffer - renderbuffer address
    + *   rdata - pointer to memory (filled by function)
    + *   rsize - size of memory in bytes (filled by function)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_dumprenderbuffer( d2_device *handle, d2_renderbuffer *buffer, void **rdata, d2_s32 *rsize )
    +{
    +   d2_u32           adrmask;
    +   d2_dlist       * dlist;
    +   d2_u32           used;
    +   d2_s32           *writePtr;
    +   d2_dlist_block * blk, *lastBlk;
    +   d2_dlist_entry * write, *lastEntry;
    + 
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( buffer, D2_INVALIDBUFFER );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( rdata, D2_NULLPOINTER );     /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( rsize, D2_NULLPOINTER );     /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   d2_scratch2dlist_intern(handle);
    +
    +   /* prepare list and measure size */
    +   dlist = & D2_DRB(buffer)->baselist;
    +
    +   /* pad to next full entry */
    +   d2_paddlist_intern( dlist );
    +
    +   /* count used entries if list is still in use */
    +   used = dlist->currentblock->quantity - dlist->blocksize;
    +   blk = dlist->firstblock;
    +
    +   while(blk != dlist->currentblock)
    +   {
    +      used += blk->quantity;
    +      blk = blk->next;
    +   }
    +
    +   if(0 == used)
    +   {
    +      /* empty buffer */
    +      *rdata = NULL;
    +      *rsize = 0;
    +      D2_RETOK(handle);
    +   }
    +
    +   /* get memory (inc additional storage for terminator) */
    +   *rdata   = d2_getmem_p( sizeof(d2_dlist_entry) * (used + 1) );
    +
    +   /* setup pointers to destination buffer */
    +   write    = (d2_dlist_entry *) *rdata;
    +   writePtr = (d2_s32*) *rdata;
    +
    +   blk      = D2_DEV(handle)->selectedbuffer->baselist.firstblock;
    +   lastBlk  = D2_DEV(handle)->selectedbuffer->baselist.currentblock;
    +
    +   while(NULL != blk)
    +   {
    +      d2_u32 argument = 0;
    +      d2_dlist_entry *entry = blk->block;
    +
    +      if(blk == lastBlk)
    +      {
    +         lastEntry = dlist->position;            /* use insert postion of current block */
    +      }
    +      else
    +      {
    +         lastEntry = entry + blk->quantity;      /* full block: use end position */
    +      }
    +
    +      while(entry < lastEntry)  
    +      {
    +         adrmask = entry->address.mask;
    +
    +         if(0 != (adrmask & 0x80808080u))
    +         {
    +            /* contains special indices */
    +            if(0x80808080u == adrmask)
    +            {
    +               /* completely empty -> skip */
    +               *writePtr = (d2_s32) entry->address.mask;
    +               writePtr++;
    +               entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +            }
    +            else if(0 != (adrmask & 0x00008000u))
    +            {
    +               /* index1 only */
    +               if(D2_DLISTSTART == (adrmask & 0xffu))
    +               {
    +                  /* catch special case of display list jump */
    +                  break; /* skip this block */
    +               } 
    +               writePtr[0] = (d2_s32) entry->address.mask;
    +               writePtr[1] = entry->value[0];
    +               writePtr += 2;
    +               entry = (d2_dlist_entry*) ((d2_s32*)entry + 2);
    +            }
    +            else if (0 != (adrmask & 0x00800000u))
    +            {
    +               /* index1&2 only */
    +               if(0xffu == (adrmask & 0xffu))
    +               {
    +                  /* end of list word */
    +                  argument = (adrmask >> 8) & 0xffu;
    +
    +                  if( (0 != (argument & 2u)) || (0 != (argument & 4u)) ) /* special bit 1 or 2 set? */
    +                  {
    +                     /* just a flush. keep on reading */
    +                     *writePtr = (d2_s32) entry->address.mask;
    +                     writePtr++;
    +                     entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +                     /*continue;*/
    +                  }
    +                  else
    +                  {   /* special bit 0 must be set */
    +                     /* terminate */
    +                     entry = lastEntry; /*break;*/
    +                  }
    +               }
    +               else
    +               {
    +                  writePtr[0] = (d2_s32) entry->address.mask;
    +                  writePtr[1] = entry->value[0];
    +                  writePtr[2] = entry->value[1];
    +                  writePtr += 3;
    +                  entry = (d2_dlist_entry*) ((d2_s32*)entry + 3);
    +               }
    +            }
    +            else if(0 != (adrmask & 0x80000000u))
    +            {
    +               /* index1,2,3 only */
    +               writePtr[0] = (d2_s32) entry->address.mask;
    +               writePtr[1] = entry->value[0];
    +               writePtr[2] = entry->value[1];
    +               writePtr[3] = entry->value[2];
    +               writePtr += 4;
    +               entry = (d2_dlist_entry*) ((d2_s32*)entry + 4);
    +            }
    +            else
    +            {
    +               /* end of list word */
    +               if(0xffu == (adrmask & 0xffu))
    +               {
    +                  /* get eol argument */
    +                  argument = (adrmask >> 8) & 0xffu;
    +
    +                  if( (argument == 2u) || (argument == 4u) )
    +                  {
    +                     /* just a flush. keep on reading */
    +                     *writePtr = (d2_s32) entry->address.mask;
    +                     writePtr++;
    +                     entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +                  }
    +                  else
    +                  {
    +                     /* terminate */
    +                     entry = lastEntry; /*break;*/
    +                  }
    +               }
    +               else
    +               {
    +                  /* invalid case, no index used */
    +                  entry = (d2_dlist_entry*) ((d2_s32*)entry + 1);
    +               }
    +            }
    +         } /* if(0 != (adrmask & 0x80808080u)) */
    +         else
    +         {
    +            /* contains simple indices only */
    +            writePtr[0] = (d2_s32) entry->address.mask;
    +            writePtr[1] = entry->value[0];
    +            writePtr[2] = entry->value[1];
    +            writePtr[3] = entry->value[2];
    +            writePtr[4] = entry->value[3];
    +            writePtr += 5;
    +
    +            /* next entry */
    +            entry++;
    +         }
    +
    +      } /* while(entry < lastEntry) */
    +
    +      if(0 != (argument & 1u))
    +      {
    +         blk = NULL; /*break;*/
    +      }
    +      else
    +      {
    +         blk = (blk == lastBlk) ? NULL : blk->next;
    +      }
    +
    +   } /* while (NULL != blk) */
    +
    +   write = (d2_dlist_entry*) writePtr;
    +
    +   /* add terminator */
    +   write->address.mask = 0x8f8f03ffu;
    +   write->value[0] = (d2_s32) D2_DEV(handle)->framebuffer;
    +   write->value[1] = (d2_s32) ( (D2_DEV(handle)->fbheight << 16) | D2_DEV(handle)->fbwidth );
    +   write->value[2] = 0;
    +   write->value[3] = 0;
    +   write++;
    +
    +   /* adjust size */
    +   *rsize = (d2_s32) (((d2_s8 *) write) - ((d2_s8 *) (*rdata)));
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getrenderbuffersize
    + * Query the number of allocated display list entries.
    + * Each display list entry is based on one address word and 4 data
    + * words (20 bytes).
    + * This function can be used to profile an application and optimize the
    + * page sizes set via <d2_setdlistblocksize> or <d2_newrenderbuffer>.
    + * It is recommended to call this function only directly before
    + * <d2_executerenderbuffer>, when all required commands are inside the
    + * render buffer.
    + *
    + * This function can only be used when 'low localmem' mode is not enabled (see: <d2_lowlocalmemmode>).
    + *
    + * note:
    + *   If <d2_adddlist> (d2_al_no_copy) commands have been used these added 
    + *   dlists are not counted.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   rb     - pointer to renderbuffer
    + *
    + * returns:
    + *   the number of allocated display list entries, or 0 if an error occurs
    + * */
    +d2_u32 d2_getrenderbuffersize(d2_device *handle, d2_renderbuffer *rb)
    +{
    +   d2_dlist *dlist;
    +   d2_dlist_block *cblock;
    +   d2_u32 used;
    +   d2_rbuffer *buffer = (d2_rbuffer *) rb;
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE ); /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATEP( buffer, D2_INVALIDBUFFER ); /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   d2_scratch2dlist_intern( handle );
    +
    +   /* prepare list and measure size */
    +   dlist = & buffer->baselist;
    +
    +   /* pad to next full entry */
    +   d2_paddlist_intern( dlist );
    +
    +   if(NULL != dlist->vidmem_blocks) 
    +   {
    +      used = dlist->count >> 2;
    +   }
    +   else
    +   {
    +      /* count used entries if list is still in use */
    +      used = dlist->currentblock->quantity - dlist->blocksize;
    +      cblock = dlist->firstblock;
    +
    +      while(cblock != dlist->currentblock)
    +      {
    +         used += cblock->quantity;
    +         cblock = cblock->next;
    +      }
    +   }
    +
    +   return used + 1;  /* add one to consider display list end entry */
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_freedumpedbuffer
    + * free a chunk of memory returned from d2_dumprenderbuffer.
    + *
    + * Dumped renderbuffers must be released using this function. Passing a
    + * NULL pointer for 'data' is accepted and does nothing.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *  data - pointer to memory (created by <d2_dumprenderbuffer>)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_freedumpedbuffer( d2_device *handle, void *data )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( data,   D2_INVALIDBUFFER );  /* PRQA S 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +#ifndef _DEBUG
    +   if(NULL != data)
    +#endif /* _DEBUG */
    +   {
    +      d2_freemem_p( data );
    +   }
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +d2_s32 d2_initrblayer_intern( const d2_device *handle, d2_rb_layer *layer, d2_u32 size )
    +{
    +   /* unused parameter */
    +   (void) handle;           /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +
    +   /* alloc scratch space */
    +   layer->scratch = (d2_dlist_scratch_entry*) d2_getmem_p( size * sizeof(d2_dlist_scratch_entry) );
    +
    +   if(NULL == layer->scratch)
    +   {
    +      return 0;
    +   }
    +
    +   /* initialize */
    +   layer->freesize = size;
    +   layer->fullsize = size;
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +static d2_s32 d2_resizerblayer_intern( const d2_device *handle, d2_rb_layer *layer )
    +{
    +   void *newadr;
    +   d2_u32 newsize, inc;
    +
    +   /* unused parameter */
    +   (void) handle;           /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +
    +   /* simple groth heuristic : double the size each time it reaches its limit */
    +   newsize = layer->fullsize << 1;
    +   newadr = d2_reallocmem_p( newsize * sizeof(d2_dlist_scratch_entry), layer->scratch, 1 );
    +
    +   if(NULL == newadr)
    +   {
    +      return 0;
    +   }
    +
    +   /* update layerinfo struct */
    +   inc = newsize - layer->fullsize;
    +   layer->freesize += inc;
    +   layer->fullsize  = newsize;
    +   layer->scratch   = newadr;
    +
    +   return (d2_s32) inc;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +static void d2_scratchgrowlayer_intern( d2_device *handle )
    +{
    +   d2_s32 inc;
    +   d2_devicedata *d2_dev = D2_DEV(handle);
    +
    +   inc = d2_resizerblayer_intern( d2_dev, & d2_dev->selectedbuffer->layer[0] );
    +
    +   if(0 == inc)
    +   {
    +      /* increasing the buffer failed. merge the existing data into
    +       * main display list as a 'best we can do' action. might destroy
    +       * order but does at least keep all primitives. */
    +
    +      d2_layer2dlist_intern( handle );
    +      d2_dev->dlscratch_cnt = (d2_s32) d2_dev->selectedbuffer->layer[0].freesize;
    +      d2_dev->dlscratch_pos = d2_dev->dlscratch_base;
    +      return;
    +   }
    +
    +   /* make new free space available for further scratch entries */
    +   d2_dev->dlscratch_cnt += inc;
    +   d2_dev->dlscratch_pos  = (d2_dev->dlscratch_pos - d2_dev->dlscratch_base) + d2_dev->selectedbuffer->layer[0].scratch;
    +   d2_dev->dlscratch_base = d2_dev->selectedbuffer->layer[0].scratch;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * note - switches may not be nested (on a single device) as there is only
    + *       one level of backup (no need for a stack).
    + *     functions should never leave rendering in 'rendertolayer' mode
    + *     when returning into application code
    + * */
    +void d2_rendertolayer_intern( d2_device *handle )
    +{
    +   d2_devicedata *d2_dev = D2_DEV(handle);
    +   d2_rb_layer *rblayer;
    +
    +   /* avoid layered buffering on lowmem configuration */
    +   if(0 != d2_dev->lowlocalmem_mode)
    +   {
    +      return;
    +   }
    +
    +   /* switch target scratch buffer and buffer mode for buffered rendering */
    +   rblayer = &d2_dev->selectedbuffer->layer[0];
    +
    +   rblayer->backup_base = d2_dev->dlscratch_base;
    +   rblayer->backup_pos  = d2_dev->dlscratch_pos;
    +   rblayer->backup_cnt  = d2_dev->dlscratch_cnt;
    +   rblayer->backup_hook = d2_dev->dlscratch_hook;
    +
    +   d2_dev->dlscratch_base = rblayer->scratch;
    +   d2_dev->dlscratch_pos  = rblayer->scratch + (rblayer->fullsize - rblayer->freesize);
    +   d2_dev->dlscratch_cnt  = (d2_s32) rblayer->freesize;
    +   d2_dev->dlscratch_hook = &d2_scratchgrowlayer_intern;
    +}
    +
    +void d2_rendertobase_intern( d2_device *handle )
    +{
    +   d2_devicedata *d2_dev = D2_DEV(handle);
    +   d2_rb_layer *rblayer;
    +
    +   /* avoid layered buffering on lowmem configuration */
    +   if(0 != d2_dev->lowlocalmem_mode)
    +   {
    +      return;
    +   }
    +
    +   /* switch target scratch buffer back to normal */
    +   rblayer = &d2_dev->selectedbuffer->layer[0];
    +   rblayer->freesize = (d2_u32) d2_dev->dlscratch_cnt;
    +
    +   d2_dev->dlscratch_base = rblayer->backup_base;
    +   d2_dev->dlscratch_pos  = rblayer->backup_pos;
    +   d2_dev->dlscratch_cnt  = rblayer->backup_cnt;
    +   d2_dev->dlscratch_hook = rblayer->backup_hook;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +void d2_layer2dlist_intern( d2_device *handle )
    +{
    +   d2_devicedata *d2_dev = D2_DEV(handle);
    +   d2_rb_layer *rblayer;
    +   d2_s32 targetlayer;
    +
    +   /* avoid layered buffering on lowmem configuration */
    +   if(0 != d2_dev->lowlocalmem_mode)
    +   {
    +      return;
    +   }
    +
    +   rblayer = &d2_dev->selectedbuffer->layer[0];
    +
    +   if(rblayer->freesize == rblayer->fullsize)
    +   {
    +      return;
    +   }
    +
    +   targetlayer = (d2_dev->dlscratch_hook == &d2_scratchgrowlayer_intern) ? 1 : 0;
    +
    +   /* flush base scratch first */
    +   if(0 != targetlayer)
    +   {
    +      d2_rendertobase_intern(handle);
    +   }
    +
    +   d2_scratch2dlist_intern( handle );
    +   d2_rendertolayer_intern(handle);
    +
    +   /* copy scratch buffer to display list
    +    * use with layer as active scratch buffer */
    +   d2_scratch2dlist_intern( handle );
    +
    +   d2_dev->dlscratch_cnt = (d2_s32) rblayer->fullsize;
    +
    +   if(0 == targetlayer)
    +   {
    +      d2_rendertobase_intern(handle);
    +   }
    +
    +   /* clear layer */
    +   rblayer->freesize = rblayer->fullsize;
    +}
    diff --git a/src/drivers/dave2d/src/dave_render.c b/src/drivers/dave2d/src/dave_render.c
    new file mode 100644
    index 000000000..50ed50fa0
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_render.c
    @@ -0,0 +1,1213 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_render.c (%version: 46 %)
    + *          created Wed Jan 12 15:24:41 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Jan 05 14:55:54 2007 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2006-04-12 CSe  fixed comments for correct documentation
    + *  2007-08-31 ASc  removed tabs, changed C++ to C comments, updated
    + *                  description for d2_renderpolygon 
    + *  2007-12-07 MGe  Enabled usage of renderquad
    + *  2008-01-07 ASc  added nullpointer check to several functions
    + *  2008-01-12 ASc  fixed bug in d2_rendertristrip
    + *  2008-06-12 MRe  added CLUT256 and color keying
    + *  2009-02-17 MRe  added d2_wf_concave as flag for d2_renderwedge
    + *  2010-09-09 MRe  added renderquad functions
    + *  2011-09-05 MRe  fix pipeline wait if cr2 change 
    + *  2012-09-25 BSp  MISRA cleanup
    + *  2017-07-27 HFu  clearly commented and renamed d2_insertwait...dlist_intern functions 
    + */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Rendering Functions
    + * There is a rendering function for each supported geometric shape.
    + *
    + * Rendering functions are the only functions that cause entries into the
    + * <Render Buffers>. Material and mode changes translate into hardware register
    + * access only when something is actually rendered.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_render.h"
    +#include "dave_box.h"
    +#include "dave_line.h"
    +#include "dave_triangle.h"
    +#include "dave_quad.h"
    +#include "dave_circle.h"
    +#include "dave_wedge.h"
    +#include "dave_texture.h"
    +#include "dave_polyline.h"
    +#include "dave_triarray.h"
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_checkwaitpipeline_intern( d2_devicedata *handle, d2_u32 cr2 );
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_checkwaitpipeline_intern( d2_devicedata *handle, d2_u32 cr2 )
    +{
    +   d2_u32 cr2_blend_wait_mask = D2C_WRITEALPHA2 | D2C_WRITEALPHA1 | D2C_BDFA | D2C_BDIA | D2C_BSFA | D2C_BSIA | D2C_USE_ACB | D2C_WRITEFORMAT3 | D2C_WRITEFORMAT2 | D2C_WRITEFORMAT1;
    +   if( ((D2_DEV(handle)->cr2) & cr2_blend_wait_mask) != (cr2 & cr2_blend_wait_mask) )
    +   {
    +      (void)d2_insertwaitpipedlist_intern(handle);
    +   }
    +   D2_DEV(handle)->cr2 = cr2;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_rendertrifan_intern( d2_device *handle, d2_fp_triangle rtri, const d2_point *vert, const d2_u32 *flags, d2_u32 count)
    +{
    +   d2_u32 i;
    +   d2_u32 share;
    +   d2_point px1, py1, px2, py2, px3, py3;
    +
    +   px1 = vert[0];  py1 = vert[1];  /* center point */
    +   px2 = vert[2];  py2 = vert[3];  /* first support point */
    +
    +   vert += 4;
    +
    +   for(i=0; i<count; i++)
    +   {
    +      /* final vertex */
    +      px3 = vert[0];  py3 = vert[1];
    +      vert += 2;
    +
    +      /* compute shared edges */
    +      if(0 == i)
    +      {
    +         share = d2_edge2_shared;
    +      }
    +      else
    +      {
    +         share = d2_edge0_shared | d2_edge2_shared;
    +      }
    +
    +      if(i == (count - 1))
    +      {
    +         share &= ~d2_edge2_shared;
    +      }
    +
    +      if(NULL != flags)
    +      {
    +         share |= *flags;
    +         flags++;
    +      }
    +
    +      rtri( handle, px1, py1, px2, py2, px3, py3, share );
    +
    +      /* shift vertices */
    +      px2 = px3;
    +      py2 = py3;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_setupmaterial_intern( d2_devicedata *handle, d2_contextdata *ctx )
    +{
    +   d2_s32 i;
    +   d2_s32 clut_entries;
    +   d2_u32 cr2_value;
    +
    +   /* check if material setup can be skipped */
    +   if ((handle->srccontext == ctx) && ((ctx->internaldirty & d2_dirty_material) == 0))
    +   {
    +      /* last material setup was from same context and context settings have not changed */
    +      return;
    +   }
    +
    +   /* update dirty flags */
    +   handle->srccontext = ctx;
    +   ctx->internaldirty &=  (d2_u8)~((d2_u8)d2_dirty_material); /* PRQA S 4130 */ /* $Misra: #MISRA_BUG_UNSIGNED_BITWISE_NOT $*/
    +
    +   if (ctx->alphablendflags == d2_blendf_blendcolor2) 
    +   {
    +      ctx->cr2mask &= ~(D2C_WRITEALPHA2 | D2C_WRITEALPHA1); /* 00 = use alpha from color2 */
    +      D2_DLISTWRITEU( D2_COLOR2, ((d2_u32)ctx->basealpha[1] << 24) );
    +   }
    +
    +   /* see Mantis issue #1416: when the RLE unit enable bit is reset from 1 to 0 with no request
    +      from the texture cache for a non-RLE texture following, a race condition may occor.
    +      So we make sure we only disable the RLE unit when really non-RLE texturing is following */
    +   cr2_value = ctx->cr2mask | D2C_RLE_ENABLE;
    +
    +   /* setup material */
    +   switch (ctx->fillmode)
    +   {
    +      case d2_fm_color:
    +         D2_DLISTWRITEU( D2_COLOR1, (ctx->basecolor[0] | ctx->constalpha) );
    +
    +         d2_checkwaitpipeline_intern( handle, cr2_value );
    +
    +         D2_DLISTWRITEU( D2_CONTROL2, cr2_value );
    +         break;
    +
    +      case d2_fm_twocolor:
    +         D2_DLISTWRITEU( D2_COLOR1, (ctx->basecolor[0] | ctx->constalpha) );
    +
    +         if(ctx->alphablendflags == d2_blendf_blendcolor2)
    +         {
    +            D2_DLISTWRITEU( D2_COLOR2, (ctx->basecolor[1] | ((d2_u32)ctx->basealpha[1] << 24)) );
    +         }
    +         else
    +         {
    +            D2_DLISTWRITEU( D2_COLOR2, (ctx->basecolor[1] | ctx->constalpha) );
    +         }
    +
    +         cr2_value |= D2C_BC2;
    +         d2_checkwaitpipeline_intern( handle, cr2_value );
    +
    +         D2_DLISTWRITEU( D2_CONTROL2, cr2_value );
    +         break;
    +
    +      case d2_fm_pattern:
    +         if(0 != (ctx->internaldirty & d2_dirty_premalpha_p))
    +         {
    +            d2_calcpatternalpha_intern( ctx );
    +         }
    +
    +         D2_DLISTWRITEU(  D2_COLOR1, (ctx->premalpha[0] | ctx->basecolor[0]) );
    +         D2_DLISTWRITEU(  D2_COLOR2, (ctx->premalpha[1] | ctx->basecolor[1]) );
    +         D2_DLISTWRITES(  D2_PATTERN, ctx->pattern );
    +
    +         cr2_value |= D2C_PATTERNENABLE | ctx->patmodemask;
    +         d2_checkwaitpipeline_intern( handle, cr2_value );
    +
    +         D2_DLISTWRITEU( D2_CONTROL2, cr2_value );
    +         break;
    +
    +      case d2_fm_texture:
    +         if(0 != (ctx->internaldirty & d2_dirty_premalpha_t))
    +         {
    +            d2_calctexturealpha_intern( ctx );
    +         }
    +
    +         D2_DLISTWRITEU(  D2_COLOR1, ctx->texcolreg[0] );
    +
    +         if(ctx->alphablendflags == d2_blendf_blendcolor2) 
    +         {
    +            D2_DLISTWRITEU(  D2_COLOR2, ( (ctx->texcolreg[1] & 0xffffffu) | (((d2_u32)ctx->basealpha[1]) << 24) ) );
    +         }
    +         else
    +         {
    +            D2_DLISTWRITEU(  D2_COLOR2, ctx->texcolreg[1] );
    +         }
    +
    +         /* in case of RLE wait for pipeline complete before setting new texture origin */
    +         if( (0 != (ctx->rlemask & D2C_RLE_ENABLE)) || (0 != D2_DEV(handle)->lasttextwasrle) )
    +         {
    +            (void)d2_insertwaitfulldlist_intern( D2_DEV(handle) );
    +         }
    +         D2_DEV(handle)->lasttextwasrle = (d2_s8)((ctx->rlemask & D2C_RLE_ENABLE) != 0);
    +         
    +         D2_DLISTWRITEU(  D2_TEXORIGIN, ctx->texbase );
    +         D2_DLISTWRITES(  D2_TEXPITCH, ctx->texpitch );
    +         D2_DLISTWRITEU(  D2_TEXMASK, ctx->texwrapmask );
    +         D2_DLISTWRITEU(  D2_TEXCLUT_OFFSET, ctx->texclutoffset);
    +
    +
    +         if(0 != (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +         {
    +            if(0 != (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT256))
    +            {
    +               clut_entries = MAX_CLUT256_ENTRIES;
    +            }
    +            else 
    +            {
    +               clut_entries = MAX_CLUT16_ENTRIES;
    +            }
    +
    +            if(NULL != ctx->texclut_cached)
    +            {
    +               if(handle->srcclut != ctx->texclut_cached)
    +               {
    +                  ctx->texclutupload = 1;
    +               }
    +            }
    +            else if( (NULL != ctx->texclut) && (handle->srcclut != ctx->texclut) )
    +            {
    +               ctx->texclutupload = 1;
    +            }
    +            else
    +            {
    +               /* empty else block to satisfy MISRA rule 14.10/2004 */
    +            }
    +
    +            if( (0 != ctx->texclutupload) && (NULL != ctx->texclut_cached) )
    +            {
    +               D2_DLISTWRITEU( D2_TEXCLUT_ADDR, 0 );
    +
    +               for(i = 0; i < clut_entries; i++)
    +               {
    +                  D2_DLISTWRITEU( D2_TEXCLUT_DATA, ctx->texclut_cached[i] );
    +               }
    +
    +               ctx->texclutupload = 0;
    +               handle->srcclut = ctx->texclut_cached;
    +            }
    +            else if( (0 != ctx->texclutupload) && (NULL != ctx->texclut) )
    +            {
    +               D2_DLISTWRITEU( D2_TEXCLUT_ADDR, 0 );
    +
    +               for(i = 0; i < clut_entries; i++)
    +               {
    +                  D2_DLISTWRITEU( D2_TEXCLUT_DATA, ctx->texclut[i] );
    +               }
    +
    +               ctx->texclutupload = 0;
    +               handle->srcclut = ctx->texclut;
    +            }
    +            else
    +            {
    +               /* empty else block to satisfy MISRA rule 14.10/2004 */
    +            }
    +         }
    +
    +         /* color keying: */
    +         if(0 != (D2_DEV(handle)->hwrevision & D2FB_COLORKEY) )
    +         {
    +            if (ctx->colkeymask == D2C_COLKEY_ENABLE)
    +            {
    +               D2_DLISTWRITEU( D2_COLKEY, ctx->colorkey );
    +            }
    +         }
    +
    +         cr2_value = D2C_TEXTUREENABLE |
    +                   ctx->cr2mask      |
    +                   ctx->texmodemask  | 
    +                   ctx->rlemask      | 
    +                   ctx->clutmask     | 
    +                   ctx->colkeymask;
    +
    +         d2_checkwaitpipeline_intern( handle, cr2_value );
    +
    +         D2_DLISTWRITEU( D2_CONTROL2, cr2_value );
    +         break;
    +
    +      default:
    +         break;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_startrender_intern( d2_devicedata *handle, const d2_bbox *bbox, d2_u32 delay )
    +{
    +   d2_s32 w,h;
    +
    +   /* find size */
    +   w = D2_INT4( bbox->xmax - bbox->xmin ) + 1;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   h = D2_INT4( bbox->ymax - bbox->ymin ) + 1;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /* set registers */
    +   D2_DLISTWRITEU(  D2_PITCH, ( ((d2_u16)handle->pitch) + (((d2_u16)delay) * 65536u) ) ); /*note : and can be avoided if pitch forced to be >0 */
    +   D2_DLISTWRITES(  D2_SIZE,  (h * 65536) + w );
    +
    +   /* start rendering */
    +   switch(handle->bpp)
    +   {
    +      case 1:
    +         D2_DLISTWRITEU(  D2_ORIGIN, ( ((d2_s8*)handle->framebuffer) + D2_INT4(bbox->xmin) + (D2_INT4(bbox->ymin) * handle->pitch) ) );  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         break;
    +
    +      case 2:
    +         D2_DLISTWRITEU(  D2_ORIGIN, ( ((d2_s16*)handle->framebuffer) + D2_INT4(bbox->xmin) + (D2_INT4(bbox->ymin) * handle->pitch) ) );   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         break;
    +
    +      case 4:
    +         D2_DLISTWRITEU(  D2_ORIGIN, ( ((d2_s32*)handle->framebuffer) + D2_INT4(bbox->xmin) + (D2_INT4(bbox->ymin) * handle->pitch) ) );   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         break;
    +
    +      default:
    +         break;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_startrender_bottom_intern( d2_devicedata *handle, const d2_bbox *bbox, d2_u32 delay )
    +{
    +   d2_s32 w,h;
    +
    +   /* find size */
    +   w = D2_INT4( bbox->xmax - bbox->xmin ) + 1;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   h = D2_INT4( bbox->ymax - bbox->ymin ) + 1;   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /* set registers */
    +   D2_DLISTWRITES(  D2_PITCH, ( ((d2_s32)((d2_u16)(-handle->pitch))) ) + (((d2_s16)delay) * 65536) );
    +   D2_DLISTWRITES(  D2_SIZE,  (h * 65536) + w );
    +
    +   /* start rendering */
    +   switch (handle->bpp)
    +   {
    +      case 1:
    +         D2_DLISTWRITEU(  D2_ORIGIN, ( ((d2_s8*)handle->framebuffer) + D2_INT4(bbox->xmin) + (D2_INT4(bbox->ymax) * handle->pitch) ) );  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         break;
    +
    +      case 2:
    +         D2_DLISTWRITEU(  D2_ORIGIN, ( ((d2_s16*)handle->framebuffer) + D2_INT4(bbox->xmin) + (D2_INT4(bbox->ymax) * handle->pitch) ) );   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         break;
    +
    +      case 4:
    +         D2_DLISTWRITEU(  D2_ORIGIN, ( ((d2_s32*)handle->framebuffer) + D2_INT4(bbox->xmin) + (D2_INT4(bbox->ymax) * handle->pitch) ) );   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         break;
    +
    +      default:
    +         break;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: Direct Rendering */
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_clear
    + * Render fill the entire framebuffer with a single color.
    + *
    + * The current cliprect is used to determine framebuffer dimensions.
    + * Clearing is the only function that bypasses the current solid context
    + * and renders plain color - regardless of blendmodes, fillmodes and other
    + * attributes.
    + *
    + * Because clearing does bypass the context material settings it is
    + * the only function that includes both alpha and color in the 32bit 'color'
    + * argument. The most significant byte is used to fill the framebuffer alpha
    + * channel if one is present.
    + *
    + * To clear using all context attributes simply use <d2_renderbox>.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   color - fill color and alpha
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_clear( d2_device *handle, d2_color color )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   (void)d2_clearbox_solid( handle, color );
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_renderbox
    + * Render a rectangle.
    + *
    + * Nothing is rendered if width or height are 0. Subpixel positions and
    + * fractional sizes are supported.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x1,y1 - top left corner (fixedpoint)
    + *   w - width of rectangle in pixels (fixedpoint)
    + *   h - height of rectangle in pixels (fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_renderbox( d2_device *handle, d2_point x1, d2_point y1, d2_width w, d2_width h )
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch(D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_renderbox_solid(handle, x1, y1, w, h);
    +         break;
    +      case d2_rm_outline :        err = d2_renderbox_outline(handle, x1, y1, w, h);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_renderbox_solidoutline(handle, x1, y1, w, h);
    +         break;
    +      case d2_rm_shadow :         err = d2_renderbox_shadow(handle, x1, y1, w, h);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_renderbox_solidshadow(handle, x1, y1, w, h);
    +         break;
    +      case d2_rm_postprocess:     err = d2_renderbox_solid(handle, x1, y1, w, h);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_renderline
    + * Render a wide line.
    + *
    + * Subpixel positions and fractional widths are supported.
    + *
    + * To modify the lineend styles use <d2_setlinecap>, but note that only included
    + * endpoints will get a cap. So if d2_lf_exclude_end is specified and linecap
    + * is set to round - the endpoint will not get rounded.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x1,y1 - startpoint (fixedpoint)
    + *   x2,y2 - endpoint (fixedpoint)
    + *   w - width of line in pixels (fixedpoint)
    + *   flags - additional lineend flags
    + *
    + * lineend flags:
    + *   d2_le_exclude_start - startpoint is not part of the line
    + *   d2_le_exclude_end   - endpoint is not part of the line
    + *   d2_le_exclude_none  - start and endpoint are part of the line
    + *   d2_le_exclude_both  - start and endpoint are not part of the line
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_renderline2>, <d2_setlinecap>
    + * */
    +d2_s32 d2_renderline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w, d2_u32 flags )
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch(D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_renderline_solid(handle, x1, y1, x2,y2, w, flags);
    +         break;
    +      case d2_rm_outline :        err = d2_renderline_outline(handle, x1, y1, x2,y2, w, flags);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_renderline_solidoutline(handle, x1, y1, x2,y2, w, flags);
    +         break;
    +      case d2_rm_shadow :         err = d2_renderline_shadow(handle, x1, y1, x2,y2, w, flags);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_renderline_solidshadow(handle, x1, y1, x2,y2, w, flags);
    +         break;
    +      case d2_rm_postprocess:     err = d2_renderline_solid(handle, x1, y1, x2,y2, w, flags);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_renderline2
    + * Render a wide line with 2 different widths.
    + *
    + * Line can have two different width at start and endpoint, forming a trapezoid. If both widths are
    + * equal it is faster to use <d2_renderline> instead.
    + * Subpixel positions and fractional widths are supported.
    + *
    + * To modify the lineend styles use <d2_setlinecap>, but note that only included
    + * endpoints will get a cap. So if d2_lf_exclude_end is specified and linecap
    + * is set to round - the endpoint will not get rounded.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x1,y1 - startpoint (fixedpoint)
    + *   x2,y2 - endpoint (fixedpoint)
    + *   w1 - width of line in pixels at startpoint (fixedpoint)
    + *   w2 - width of line in pixels at endpoint (fixedpoint)
    + *   flags - additional lineend flags
    + *
    + * lineend flags:
    + *   d2_le_exclude_start - startpoint is not part of the line
    + *   d2_le_exclude_end   - endpoint is not part of the line
    + *   d2_le_exclude_none  - start and endpoint are part of the line
    + *   d2_le_exclude_both  - start and endpoint are not part of the line
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_renderline>, <d2_setlinecap>
    + * */
    +d2_s32 d2_renderline2(  d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_width w1, d2_width w2, d2_u32 flags )
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch(D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_renderline2_solid(handle, x1, y1, x2,y2, w1,w2, flags);
    +         break;
    +      case d2_rm_outline :        err = d2_renderline2_outline(handle, x1, y1, x2,y2, w1,w2, flags);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_renderline2_solidoutline(handle, x1, y1, x2,y2, w1,w2, flags);
    +         break;
    +      case d2_rm_shadow :         err = d2_renderline2_shadow(handle, x1, y1, x2,y2, w1,w2, flags);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_renderline2_solidshadow(handle, x1, y1, x2,y2, w1,w2, flags);
    +         break;
    +      case d2_rm_postprocess:     err = d2_renderline2_solid(handle, x1, y1, x2,y2, w1,w2, flags);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_rendertri
    + * Render a triangle.
    + *
    + * Triangles must be specified with clockwise orientation. Subpixel positions are supported.
    + * In order to get correct antialiasing and outlines shared edges must be specified using
    + * edge flags.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x1,y1 - first point (fixedpoint)
    + *   x2,y2 - second point (fixedpoint)
    + *   x3,y3 - third point (fixedpoint)
    + *   flags - triangle edge flags
    + *
    + * triangle edge flags:
    + * d2_edge0_shared - edge from (x1,y1) - (x2,y2) is shared
    + * d2_edge1_shared - edge from (x2,y2) - (x3,y3) is shared
    + * d2_edge2_shared - edge from (x3,y3) - (x1,y1) is shared
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_rendertri( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags )
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch(D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_rendertri_solid(handle, x1, y1, x2,y2, x3,y3, flags);
    +         break;
    +      case d2_rm_outline :        err = d2_rendertri_outline(handle, x1, y1, x2,y2, x3,y3, flags);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_rendertri_solidoutline(handle, x1, y1, x2,y2, x3,y3, flags);
    +         break;
    +      case d2_rm_shadow :         err = d2_rendertri_shadow(handle, x1, y1, x2,y2, x3,y3, flags);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_rendertri_solidshadow(handle, x1, y1, x2,y2, x3,y3, flags);
    +         break;
    +      case d2_rm_postprocess:     err = d2_rendertri_solid(handle, x1, y1, x2,y2, x3,y3, flags);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_renderquad
    + * Render a quadrangle.
    + *
    + * A quadrangle is a convex four-sided polygon (quadrilateral is the precise mathematical term).
    + * Quadrangles must be specified with clockwise orientation. Subpixel positions are supported.
    + * In order to get correct antialiasing and outlines shared edges must be specified using
    + * edge flags.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x1,y1 - first point (fixedpoint)
    + *   x2,y2 - second point (fixedpoint)
    + *   x3,y3 - third point (fixedpoint)
    + *   x4,y4 - fourth point (fixedpoint)
    + *   flags - quadrangle edge flags
    + *
    + * triangle edge flags:
    + * d2_edge0_shared - edge from (x1,y1) - (x2,y2) is shared
    + * d2_edge1_shared - edge from (x2,y2) - (x3,y3) is shared
    + * d2_edge2_shared - edge from (x3,y3) - (x4,y4) is shared
    + * d2_edge3_shared - edge from (x4,y4) - (x1,y1) is shared
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_renderquad( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_point x4, d2_point y4, d2_u32 flags )
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch (D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_renderquad_solid(handle, x1, y1, x2,y2, x3,y3, x4,y4, flags);
    +         break;
    +      case d2_rm_outline :        err = d2_renderquad_outline(handle, x1, y1, x2,y2, x3,y3, x4,y4, flags);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_renderquad_solidoutline(handle, x1, y1, x2,y2, x3,y3, x4,y4, flags);
    +         break;
    +      case d2_rm_shadow :         err = d2_renderquad_shadow(handle, x1, y1, x2,y2, x3,y3, x4,y4, flags);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_renderquad_solidshadow(handle, x1, y1, x2,y2, x3,y3, x4,y4, flags);
    +         break;
    +      case d2_rm_postprocess:     err = d2_renderquad_solid(handle, x1, y1, x2,y2, x3,y3, x4,y4, flags);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_rendercircle
    + * Render a circle or circle ring.
    + *
    + * Circles are directly rasterized and not reduced to linear parts by the hardware.
    + * Subpixel positions, radii and widths are supported.
    + * Nonantialiased circle rings with a fractional width below 1 pixel will
    + * have drop outs (missing pixels).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x,y - center (fixedpoint)
    + *   r - radius (fixedpoint)
    + *   w - width or 0 for a solid circle (fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_rendercircle( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w )
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( r > 0, D2_VALUENEGATIVE );    /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( w >= 0, D2_VALUENEGATIVE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch (D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_rendercircle_solid(handle, x, y, r, w );
    +         break;
    +      case d2_rm_outline :        err = d2_rendercircle_outline(handle, x, y, r, w );
    +         break;
    +      case d2_rm_solid_outlined : err = d2_rendercircle_solidoutline(handle, x, y, r, w );
    +         break;
    +      case d2_rm_shadow :         err = d2_rendercircle_shadow(handle, x, y, r, w );
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_rendercircle_solidshadow(handle, x, y, r, w );
    +         break;
    +      case d2_rm_postprocess:     err = d2_rendercircle_solid(handle, x, y, r, w );
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_renderwedge
    + * Render a circle arc or circle ring arc.
    + *
    + * Same as <d2_rendercircle> but clipped by two additional linear boundaries, resulting in an
    + * arc.
    + * As default the two half planes form an intersected area for the clipping region. 
    + * For angles > 180 deg the flag d2_wf_concave must be used.
    + * When the flag d2_wf_concave is set the two half planes form a united, concave area.
    + * In order to get correct antialiasing and outlines shared edges must be specified using
    + * edge flags (only linear edges can be shared).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x,y - center (fixedpoint)
    + *   r - radius (fixedpoint)
    + *   w - width or 0 for a solid circle (fixedpoint)
    + *  nx1, ny1 - normal vector of first edge (16:16 fixedpoint)
    + *  nx2, ny2 - normal vector of second edge (16:16 fixedpoint)
    + *  flags - edge sharing and concave flags
    + *
    + * circle wedge flags:
    + * d2_edge0_shared - first edge is shared
    + * d2_edge1_shared - second edge is shared
    + * d2_wf_concave - defines that the clipping region forms a united area for angles > 180 deg
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * note:
    + *   d2_renderwedge internally calls <d2_setclipgradient> for drawing wedges and will
    + *   overwrite the clip gradient settings!
    + *
    + * remarks:
    + *   The figure below shows four examples of different wedges and the corresponding normal vectors (n1, n2).
    + *   In order to get correct antialiasing all vectors must be normalized to a length of one.
    + *   (see wedge.png)
    + *
    + * example:
    + * (start code)
    + * ...
    + * d2_setcolor(handle, 0, 0x0000ff);
    + * d2_renderwedge(handle, 100<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,   -46340, -46340,   0);
    + * d2_renderwedge(handle, 200<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    0<<16, -1<<16,   0);
    + * d2_renderwedge(handle, 300<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    46340, -46340,   0);
    + * d2_renderwedge(handle, 400<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    1<<16,  0<<16,   0);
    + * ...
    + * (end code)
    + *
    + * remarks:
    + *   The figure below shows the same examples but with d2_wf_concave set.
    + *   (see wedgeconcave.png)
    + *
    + * example:
    + * (start code)
    + * ...
    + * d2_setcolor(handle, 0, 0x0000ff);
    + * d2_renderwedge(handle, 100<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,   -46340, -46340,   d2_wf_concave);
    + * d2_renderwedge(handle, 200<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    0<<16, -1<<16,   d2_wf_concave);
    + * d2_renderwedge(handle, 300<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    46340, -46340,   d2_wf_concave);
    + * d2_renderwedge(handle, 400<<4, 100<<4, 50<<4, 0,    1<<16, 0<<16,    1<<16,  0<<16,   d2_wf_concave);
    + * ...
    + * (end code)
    + * */
    +d2_s32 d2_renderwedge( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags )
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( r > 0, D2_VALUENEGATIVE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( w >= 0, D2_VALUENEGATIVE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch (D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_renderwedge_solid(handle, x, y, r, w, nx1,ny1, nx2,ny2, flags);
    +         break;
    +      case d2_rm_outline :        err = d2_renderwedge_outline(handle, x, y, r, w, nx1,ny1, nx2,ny2, flags);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_renderwedge_solidoutline(handle, x, y, r, w, nx1,ny1, nx2,ny2, flags);
    +         break;
    +      case d2_rm_shadow :         err = d2_renderwedge_shadow(handle, x, y, r, w, nx1,ny1, nx2,ny2, flags);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_renderwedge_solidshadow(handle, x, y, r, w, nx1,ny1, nx2,ny2, flags);
    +         break;
    +      case d2_rm_postprocess:     err = d2_renderwedge_solid(handle, x, y, r, w, nx1,ny1, nx2,ny2, flags);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: Buffer Rendering
    + * */
    +
    +/* function: d2_renderpolyline
    + * Render a polyline
    + *
    + * Line segments inside the polyline are connected as defined by <d2_setlinejoin>
    + * and endpoints of the polyline are using the current linecap style set by <d2_setlinecap>.
    + * If the line is closed (d2_le_closed) it has no endpoints and therefore no linecaps.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   data - pointer to an array of 2*'count' d2_point values ('count' x,y pairs)
    + *   count - number of vertices
    + *   w - width of polyline
    + *   flags -  additional lineend flags
    + *
    + * lineend flags:
    + *   d2_le_exclude_start - first point is not part of the polyline
    + *   d2_le_exclude_end - last point is not part of the polyline
    + *   d2_le_closed - polyline has no start or endpoint, last vertex is connected back to first
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_setlinecap>, <d2_setlinejoin>
    + * */
    +d2_s32 d2_renderpolyline( d2_device *handle, const d2_point *data, d2_u32 count, d2_width w, d2_u32 flags)
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( count > 0, D2_VALUENEGATIVE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( w >= 0, D2_VALUENEGATIVE );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( data, D2_NULLPOINTER );         /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch (D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_renderpolyline_solid(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_outline :        err = d2_renderpolyline_outline(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_renderpolyline_solidoutline(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_shadow :         err = d2_renderpolyline_shadow(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_renderpolyline_solidshadow(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_postprocess:     err = d2_renderpolyline_solid(handle, data, count, w, flags);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +
    +/* function: d2_renderpolyline2
    + * Render a polyline with multiple width
    + *
    + * Similar to <d2_renderpolyline> but a width can be supplied for each vertex.
    + * Line segments inside the polyline are connected by round line joins and endpoints of
    + * the polyline are using the current linecap style set by <d2_setlinecap>.
    + * If the line is closed (d2_le_closed) it has no endpoints and therefore no linecaps.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   data - pointer to an array of 2*'count' d2_point values ('count' x,y pairs)
    + *   count - number of vertices
    + *   w - pointer width to an array of 'count' d2_width values (width for each vertex)
    + *   flags -  additional lineend flags
    + *
    + * lineend flags:
    + *   d2_le_exclude_start - first point is not part of the polyline
    + *   d2_le_exclude_end - last point is not part of the polyline
    + *   d2_le_closed - polyline has no start or endpoint, last vertex is connected back to first
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_setlinecap>, <d2_setlinejoin>, <d2_renderpolyline>
    + * */
    +d2_s32 d2_renderpolyline2( d2_device *handle, const d2_point *data, d2_u32 count, const d2_width *w, d2_u32 flags)
    +{
    +   d2_s32 err = D2_ILLEGALMODE;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( count > 0, D2_VALUENEGATIVE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( w, D2_NULLPOINTER );            /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( data, D2_NULLPOINTER );         /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   switch (D2_DEV(handle)->rendermode)
    +   {
    +      case d2_rm_solid :          err = d2_renderpolyline2_solid(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_outline :        err = d2_renderpolyline2_outline(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_solid_outlined : err = d2_renderpolyline2_solidoutline(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_shadow :         err = d2_renderpolyline2_shadow(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_solid_shadow :   err = d2_renderpolyline2_solidshadow(handle, data, count, w, flags);
    +         break;
    +      case d2_rm_postprocess:     err = d2_renderpolyline2_solid(handle, data, count, w, flags);
    +         break;
    +
    +      default:
    +         break;
    +   }
    +   D2_RETERR(handle, err);
    +}
    +
    +
    +/* function: d2_rendertrilist
    + * Render a polygon from a triangle list.
    + *
    + * Each triangle must be defined in clockwise order. In order to get correct antialiasing
    + * and outlines, shared edges must be specified using edge flags (see: <d2_rendertri> for flag
    + * definition).
    + * There is one flagbyte per triangle. If no sharing is required (e.g. no antialiasing)
    + * you can pass NULL for the 'flags' pointer.
    + *
    + * (see trilist.gif)
    + * For each triangle 3 vertices are specified in the data array.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   data - pointer to an array of 6*count d2_point values (3*count x,y pairs)
    + *  flags - pointer to an array to count bytes containing edgesharing flags or NULL.
    + *           If NULL is passed it is assumed that no edges are shared.
    + *   count - number of triangles
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *  <d2_rendertri>, <d2_rendertrifan>, <d2_rendertristrip>
    + * */
    +d2_s32 d2_rendertrilist( d2_device *handle, const d2_point *data, const d2_u32 *flags, d2_u32 count)
    +{
    +   d2_u32 share;
    +   d2_u32 i;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( count > 0, D2_VALUENEGATIVE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( data, D2_NULLPOINTER );         /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* simple loop */
    +   share = 0;
    +
    +   for(i=0; i<count; i++)
    +   {
    +      d2_point px1, py1, px2, py2, px3, py3;
    +
    +      px1 = data[0];  py1 = data[1];
    +      px2 = data[2];  py2 = data[3];
    +      px3 = data[4];  py3 = data[5];
    +
    +      data += 6;
    +
    +      if(NULL != flags)
    +      {
    +         share = *flags;
    +         flags++;
    +      }
    +
    +      (void)d2_rendertri( handle, px1, py1, px2, py2, px3, py3, share );
    +   }
    +
    +   return 0;
    +}
    +
    +/* function: d2_rendertristrip
    + * Render a polygon from a triangle strip.
    + *
    + * When rendering connected structures using a set of triangles a triangle strip can be
    + * used instead of a triangle list (<d2_rendertrilist>). The advantage is that for every
    + * triangle except the first one only one additional vertex has to be specified.
    + * The other two vertices are reused from the previous triangle. See diagram for explanation:
    + *
    + * (see tristrip.gif)
    + * Triangles rendered from the order given above are :
    + * - 1,2,3
    + * - 2,4,3
    + * - 3,4,5
    + * - 4,6,5
    + *
    + * Note that every second triangle is flipped automatically in order to keep them all
    + * in clockwise orientation.
    + * Internal edges are automatically flagged as shared but you can still specify a flag
    + * for each triangle in order to define additional shared edges.
    + * There is one flagbyte per triangle. If no additional sharing information is required
    + * you can pass NULL for the 'flags' pointer.
    + *
    + * The first triangle must be defined in clockwise order (others will then be clockwise as well).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   data - pointer to an array of 2*count+4 d2_point values (count+2 x,y pairs)
    + *   flags - pointer to an array to count bytes containing edgesharing flags or NULL
    + *   count - number of triangles
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *  <d2_rendertri>, <d2_rendertrifan>, <d2_rendertrilist>
    + * */
    +d2_s32 d2_rendertristrip( d2_device *handle, const d2_point *data, const d2_u32 *flags, d2_u32 count)
    +{
    +   d2_u32 i;
    +   d2_s32 flip;
    +   d2_u32 share;
    +   d2_point px1, py1, px2, py2, px3, py3;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );      /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( count > 0, D2_VALUENEGATIVE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( data, D2_NULLPOINTER );          /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* first points */
    +   px1 = data[0];  py1 = data[1];
    +   px2 = data[2];  py2 = data[3];
    +
    +   data += 4;
    +
    +   flip = 0;
    +
    +   for(i=0; i<count; i++)
    +   {
    +      /* third point */
    +      px3 = data[0];  py3 = data[1];
    +
    +      data += 2;
    +
    +      if(0 == flip)
    +      {
    +         /* compute shared edges */
    +         if(0 == i)
    +         {
    +            share = d2_edge1_shared;
    +         }
    +         else
    +         {
    +            share = d2_edge0_shared | d2_edge1_shared;
    +         }
    +
    +         if(i == (count - 1))
    +         {
    +            share &= ~d2_edge1_shared;
    +         }
    +
    +         if(NULL != flags)
    +         {
    +            share |= *flags;
    +            flags++;
    +         }
    +
    +         /* render flipped */
    +         (void)d2_rendertri( handle, px1, py1, px2, py2, px3, py3, share );
    +         flip = 1;
    +      }
    +      else
    +      {
    +         /* compute shared edges */
    +         share = d2_edge1_shared | d2_edge2_shared;
    +
    +         if(i == (count - 1))
    +         {
    +            share &= ~d2_edge1_shared;
    +         }
    +
    +         if(NULL != flags)
    +         {
    +            share |= *flags;
    +            flags++;
    +         }
    +
    +         /* render normal */
    +         (void)d2_rendertri( handle, px1, py1, px3, py3, px2, py2, share );
    +         flip = 0;
    +      }
    +
    +      /* shift vertices */
    +      px1 = px2;
    +      py1 = py2;
    +      px2 = px3;
    +      py2 = py3;
    +   }
    +
    +   return 0;
    +}
    +
    +/* function: d2_rendertrifan
    + * Render a polygon from a triangle fan
    + *
    + * When rendering connected structures where all triangles share a common vertex a triangle fan
    + * can be used instead of a triangle list (<d2_rendertrilist>). The advantage is that for every
    + * triangle except the first one only one additional vertex has to be specified.
    + * The other two vertices are reused from the previous triangle and the common base vertex.
    + * See diagram for explanation:
    + *
    + * (see trifan.gif)
    + * Triangles rendered from the order given above are :
    + * - 1,2,3
    + * - 1,3,4
    + * - 1,4,5
    + *
    + * Internal edges are automatically flagged as shared but you can still specify a flag
    + * for each triangle in order to define additional shared edges.
    + * There is one flagbyte per triangle. If no additional sharing information is required
    + * you can pass NULL for the 'flags' pointer.
    + *
    + * The first triangle must be defined in clockwise order (others will then be clockwise as well).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   data - pointer to an array of 2*count+4 d2_point values (count+2 x,y pairs)
    + *   flags - pointer to an array to count bytes containing edgesharing flags or NULL
    + *   count - number of triangles
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *  <d2_rendertri>, <d2_rendertrilist>, <d2_rendertristrip>
    + * */
    +d2_s32 d2_rendertrifan( d2_device *handle, const d2_point *data, const d2_u32 *flags, d2_u32 count)
    +{
    +   d2_u32 rmode;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );    /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( count > 0, D2_VALUENEGATIVE ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( data, D2_NULLPOINTER );        /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   rmode = D2_DEV(handle)->rendermode;
    +
    +   /* render shadow part */
    +   if(0 != (rmode & d2_rm_shadow))
    +   {
    +      d2_rendertrifan_intern( handle, &d2_rendertri_shadow, data, flags, count);
    +   }
    +
    +   /* render solid   part */
    +   if(0 != (rmode & d2_rm_solid))
    +   {
    +      if(0 != (rmode & (d2_rm_shadow | d2_rm_outline)))
    +      {
    +         d2_rendertolayer_intern( handle );
    +      }
    +
    +      d2_rendertrifan_intern( handle, &d2_rendertri_solid, data, flags, count);
    +
    +      if(0 != (rmode & (d2_rm_shadow | d2_rm_outline)))
    +      {
    +         d2_rendertobase_intern( handle );
    +      }
    +   }
    +
    +   /* render outline */
    +   if(0 != (rmode & d2_rm_outline))
    +   {
    +      (void)d2_renderpolyline_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, data, NULL, count + 2, D2_DEV(handle)->outlinewidth, d2_le_closed, 0,0 );
    +   }
    +
    +   return 0;
    +}
    +
    +/* function: d2_renderpolygon
    + * Render a convex polygon
    + *
    + * All vertices have to be in clockwise order. If seperation into monoton
    + * subregions is required, internal edges will be flagged as 'shared'
    + * automatically.
    + * Outer edges are always nonshared for now.
    + *
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   data - pointer to an array of d2_point values (count x,y pairs)
    + *   count - number of points
    + *   flags - reserved (should be NULL)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_renderpolygon( d2_device *handle, const d2_point *data, d2_u32 count, d2_u32 flags)
    +{
    +   (void)flags; /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +
    +   /* quick hack. will work with convex polys only */
    +   if(count > 2)
    +   {
    +      return d2_rendertrifan( handle, data, NULL, (count - 2));
    +   }
    +   else
    +   {
    +      return D2_VALUENEGATIVE;
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_texture.c b/src/drivers/dave2d/src/dave_texture.c
    new file mode 100644
    index 000000000..969223228
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_texture.c
    @@ -0,0 +1,1428 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_texture.c (%version: 21 %)
    + *          created Wed Jul 06 14:57:59 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Tue Dec 12 14:50:45 2006 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2006-03-08 CSe  added argb1555 format
    + *  2007-09-20 ASc  rem. C++ comments, fixed d2_settexturemapping params 
    + *  2008-04-30 MRe  added RLE and subbyte formats
    + *  2008-06-12 MRe  added CLUT256 and color keying
    + *  2011-06-16 MRe  added Alpha4, Alpha2, Alpha1 texture formats
    + *  2012-09-05 MRe  added check for Alpha4, Alpha2, Alpha1 texture formats
    + *  2012-09-25 BSp  MISRA cleanup
    + */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Texture Functions
    + * Modify texture mapping settings
    + *
    + * Texture attributes are part of the context (see: <Context Functions>) but
    + * a single context might contain multiple mapping attributes if multiple
    + * texture hardware units are present.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_texture.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_textureoperator( const d2_contextdata *ctx, d2_u32 index, d2_u32 mode, d2_alpha *c1, d2_alpha *c2); /* MISRA */
    +static D2_INLINE void d2_setupuvlimiter_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox ); /* MISRA */
    +static D2_INLINE void d2_setupuvlimiter_invert_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox ); /* MISRA */
    +
    +
    +/*--------------------------------------------------------------------------
    + * Group: Texture Attribute Writes */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexture
    + * Specify the source for texture mapping.
    + *
    + * The specified texture is used only when <d2_setfillmode> is set to *d2_fm_texture*
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ptr - address of the top left texel (coordinate 0,0)
    + *   pitch - number of texels (*not bytes*) per scanline
    + *   width - width of texture in texels (equal or less than pitch)
    + *   height - height of texture in texels
    + *   format - texel encoding type (texture format)
    + *
    + * texture formats:
    + *
    + *   d2_mode_alpha8   - monochrome 8bit per pixel
    + *   d2_mode_alpha4    - monochrome 4bit per pixel
    + *   d2_mode_alpha2    - monochrome 2bit per pixel
    + *   d2_mode_alpha1    - monochrome 1bit per pixel
    + *   d2_mode_rgb565   - colored 16bit per pixel (alpha is blue)
    + *   d2_mode_argb8888 - colored 32bit per pixel
    + *   d2_mode_rgba8888 - colored 32bit per pixel
    + *   d2_mode_rgb888   -  (same as d2_mode_argb8888)
    + *   d2_mode_argb4444 - colored 16bit per pixel
    + *   d2_mode_rgba4444 - colored 16bit per pixel
    + *   d2_mode_rgb444   -  (same as d2_mode_argb4444)
    + *   d2_mode_argb1555 - colored 16bit per pixel
    + *   d2_mode_rgba5551 - colored 16bit per pixel
    + *   d2_mode_rgb555   -  (same as d2_mode_argb1555)
    + *   d2_mode_ai44     - colored, palletized 8bit per pixel, (4 bit alpha, 4 bit indexed RGB: see <d2_settexclut>)
    + *   d2_mode_i8        - colored, palletized 8bit per pixel (palette is used if d2_mode_clut is also set)
    + *   d2_mode_i4        - colored, palletized 4bit per pixel (palette is used if d2_mode_clut is also set)
    + *   d2_mode_i2        - colored, palletized 2bit per pixel (palette is used if d2_mode_clut is also set)
    + *   d2_mode_i1        - colored, palletized 1bit per pixel (palette is used if d2_mode_clut is also set)
    + *
    + * additional flags (can be combined with all above formats) :
    + *
    + *   d2_mode_clut     -  Enables the color look up table (for d2_mode_i8 through d2_mode_i1) (see <d2_settexclut>).
    + *
    + * Modes d2_mode_rgb888, d2_mode_rgb444 and d2_mode_rgb555 can be used as well.
    + * In this case alpha information has to be ignored by setting a <d2_settextureoperation> of d2_to_one for alpha.
    + *
    + * If the CLUT is not enabled with an indexed color format (d2_mode_i8 to d2_mode_i1), the index is written directly to the framebuffer.
    + * The index can be combined with the offset, see <d2_settexclut_offset>.
    + *
    + * In case of d2_mode_alpha4 to d2_mode_alpha1 bits are MSB aligned and replicated to the lower bits of the 8 bit format of the internal A, R, G and B channels.
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * note:
    + *   Please notice that a cache flush using 'd1_cacheblockflush' might be necessary if memory contents were changed before!
    + *   To avoid problems you can use the d1 driver memory management functions 'd1_copytovidmem' or 'd1_copyfromvidmem',
    + *   which implicitly do a cache flush.
    + * */
    +d2_s32 d2_settexture( d2_device *handle, void *ptr, d2_s32 pitch, d2_s32 width, d2_s32 height, d2_u32 format )
    +{
    +   d2_u32 format_noflags = ((format & ~d2_mode_rle) & ~d2_mode_clut);
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );         /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ptr, D2_NOVIDEOMEM );               /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( pitch >= 0, D2_VALUENEGATIVE );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( width >= 0, D2_VALUENEGATIVE );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( height >= 0, D2_VALUENEGATIVE );    /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +   ctx->texpitch = pitch;
    +   ctx->texwidth = width;
    +   ctx->texheight = height;
    +   ctx->texbase = ptr;
    +   ctx->texsubppb = 0;
    +
    +   if( (0 != (format & d2_mode_rle)) && (0 == (D2_DEV(handle)->hwrevision & D2FB_RLEUNIT)) )
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   if( (0 != (format & d2_mode_clut)) && (0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT)) )
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   if( 
    +      (
    +         (d2_mode_alpha4 == format_noflags)  ||
    +         (d2_mode_alpha2 == format_noflags)  ||
    +         (d2_mode_alpha1 == format_noflags) 
    +       )
    +      && (
    +         (0 == (D2_DEV(handle)->hwrevision & D2FB_SWDAVE)) && 
    +         ((D2_DEV(handle)->hwrevision & 0xffu) < 0x0au) 
    +          )
    +       )
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +
    +   /* calc bpp and mask */
    +   switch(format_noflags)
    +   {
    +      case d2_mode_alpha8:
    +         ctx->tbstylemask = 0;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         break;
    +
    +      case d2_mode_rgb565:
    +         ctx->tbstylemask = D2C_READFORMAT1;
    +         ctx->texbpp = 2;
    +         ctx->rlebpp = 2;
    +         break;
    +
    +      case d2_mode_argb8888:
    +      case d2_mode_rgb888:
    +         ctx->tbstylemask = D2C_READFORMAT2;
    +         ctx->texbpp = 4;
    +         ctx->rlebpp = 4;
    +
    +         if(d2_mode_rgb888 == format_noflags)
    +         {
    +            ctx->rlebpp = 3;
    +         }
    +         break;
    +
    +      case d2_mode_rgba8888:
    +         ctx->tbstylemask = D2C_READFORMAT3 | D2C_READFORMAT2;
    +         ctx->texbpp = 4;
    +         ctx->rlebpp = 4;
    +         break;
    +
    +      case d2_mode_argb4444:
    +      case d2_mode_rgb444:
    +         ctx->tbstylemask = D2C_READFORMAT2 | D2C_READFORMAT1;
    +         ctx->texbpp = 2;
    +         ctx->rlebpp = 2;
    +         break;
    +
    +      case d2_mode_rgba4444:
    +         ctx->tbstylemask = D2C_READFORMAT3 | D2C_READFORMAT2 | D2C_READFORMAT1;
    +         ctx->texbpp = 2;
    +         ctx->rlebpp = 2;
    +         break;
    +
    +      case d2_mode_argb1555:
    +      case d2_mode_rgb555:
    +         ctx->tbstylemask = D2C_READFORMAT3;
    +         ctx->texbpp = 2;
    +         ctx->rlebpp = 2;
    +         break;
    +
    +      case d2_mode_rgba5551:
    +         ctx->tbstylemask = D2C_READFORMAT4;
    +         ctx->texbpp = 2;
    +         ctx->rlebpp = 2;
    +         break;
    +
    +      case d2_mode_ai44:
    +         if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +         {
    +            D2_RETERR( handle, D2_ILLEGALMODE );
    +         }
    +         ctx->tbstylemask = D2C_READFORMAT3 | D2C_READFORMAT1;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         break;
    +
    +      case d2_mode_i8:
    +         if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +         {
    +            D2_RETERR( handle, D2_ILLEGALMODE );
    +         }
    +         ctx->tbstylemask = D2C_READFORMAT4 | D2C_READFORMAT1;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         break;
    +
    +      case d2_mode_i4:
    +         if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +         {
    +            D2_RETERR( handle, D2_ILLEGALMODE );
    +         }
    +         ctx->tbstylemask = D2C_READFORMAT4 | D2C_READFORMAT2;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         ctx->texsubppb = 2;
    +         break;
    +
    +      case d2_mode_i2:
    +         if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +         {
    +            D2_RETERR( handle, D2_ILLEGALMODE );
    +         }
    +         ctx->tbstylemask = D2C_READFORMAT4 | D2C_READFORMAT2 | D2C_READFORMAT1;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         ctx->texsubppb = 4;
    +         break;
    +
    +      case d2_mode_i1:
    +         if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +         {
    +            D2_RETERR( handle, D2_ILLEGALMODE );
    +         }
    +         ctx->tbstylemask = D2C_READFORMAT4 | D2C_READFORMAT3;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         ctx->texsubppb = 8;
    +         break;
    +
    +      case d2_mode_alpha4:
    +         ctx->tbstylemask = D2C_READFORMAT4 | D2C_READFORMAT3 | D2C_READFORMAT1;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         ctx->texsubppb = 2;
    +         break;
    +
    +      case d2_mode_alpha2:
    +         ctx->tbstylemask = D2C_READFORMAT4 | D2C_READFORMAT3 | D2C_READFORMAT2;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         ctx->texsubppb = 4;
    +         break;
    +
    +      case d2_mode_alpha1:
    +         ctx->tbstylemask = D2C_READFORMAT4 | D2C_READFORMAT3 | D2C_READFORMAT2 | D2C_READFORMAT1;
    +         ctx->texbpp = 1;
    +         ctx->rlebpp = 1;
    +         ctx->texsubppb = 8;
    +         break;
    +
    +      default:
    +         break;
    +   }
    +
    +   if(0 != (format & d2_mode_rle))
    +   {
    +      ctx->rlemask  = D2C_RLE_ENABLE;
    +      ctx->rlemask |= ((d2_u32) ctx->rlebpp - 1) * D2C_RLEFORMAT1;
    +   }
    +   else
    +   {
    +      ctx->rlemask = 0;
    +   }
    +
    +   if( (0 != (format & d2_mode_clut)) || (d2_mode_ai44 == format_noflags) )
    +   {
    +      ctx->clutmask  |= D2C_CLUT_ENABLE;
    +   }
    +   else
    +   {
    +      ctx->clutmask &= ~D2C_CLUT_ENABLE;
    +   }
    +
    +   ctx->cr2mask = 
    +      D2_DEV(handle)->fbstylemask | 
    +      ctx->blendmask              | 
    +      ctx->tbstylemask            | 
    +      ctx->alphablendmask         | 
    +      ctx->rlemask                | 
    +      ctx->clutmask               | 
    +      ctx->colkeymask;
    +
    +   ctx->internaldirty |= d2_dirty_texlim;
    +   d2_calctexturemask_intern( ctx );
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexturemode
    + * Define texture addressing details.
    + *
    + * Texture wrapping will work with texture dimensions that are integer powers
    + * of two only (2,4,8,16,32,..). Other sizes will wrap at the next higher power
    + * of two.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   mode - any combination of texture mode bits (default is d2_tm_filter, see below)
    + *
    + * texture mode bits:
    + *
    + *  d2_tm_wrapu - wrap texture on U axis (x-direction)
    + *  d2_tm_wrapv - wrap texture on V axis (y-direction)
    + *  d2_tm_filteru - apply linear filter on U axis (x-direction)
    + *  d2_tm_filterv - apply linear filter in V axis (y-direction)
    + *  d2_tm_filter - apply bilinear filter (both axis)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_settexturemode( d2_device *handle, d2_u32 mode )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );      /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (mode < 256), D2_INVALIDENUM );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +
    +   ctx->texmodemask = 0;
    +
    +   if(0 != (mode & d2_tm_filteru))
    +   {
    +      ctx->texmodemask |= D2C_TEXTUREFILTERX;
    +   }
    +
    +   if(0 != (mode & d2_tm_filterv))
    +   {
    +      ctx->texmodemask |= D2C_TEXTUREFILTERY;
    +   }
    +
    +   if(0 == (mode & d2_tm_wrapu))
    +   {
    +      ctx->texmodemask |= D2C_TEXTURECLAMPX;
    +   }
    +
    +   if(0 == (mode & d2_tm_wrapv))
    +   {
    +      ctx->texmodemask |= D2C_TEXTURECLAMPY;
    +   }
    +
    +   /* store */
    +   ctx->texmode = (d2_u8) (mode & (d2_tm_wrapu | d2_tm_wrapv | d2_tm_filteru | d2_tm_filterv));
    +   d2_calctexturemask_intern( ctx );
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settextureoperation
    + * Choose texture operation for each channel.
    + *
    + * Textures can be 'colorized' by a varity of operations. A textureoperation
    + * can be defined for each channel (a,r,g,b) individually.
    + * Depending on the chosen operation one or two additional parameters
    + * have to be set using <d2_settexopparam>.
    + *
    + * The default setting is d2_to_one, d2_to_copy, d2_to_copy, d2_to_copy
    + * and will therfore ignore any alpha information in the texture.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   amode - texture operation for alpha channel
    + *   rmode - texture operation for red channel
    + *   gmode - texture operation for green channel
    + *   bmode - texture operation for blue channel
    + *
    + * texture operations:
    + *   d2_to_zero - replace channel data with zero (no parameters)
    + *   d2_to_one - replace channel data with one (no parameters)
    + *   d2_to_replace - replace channel data with a constant (p1)
    + *   d2_to_copy - copy channel data unchanged (no parameters)
    + *   d2_to_invert - invert channel data (no parameters)
    + *   d2_to_multiply - multiply channel data with a constant (p1)
    + *   d2_to_invmultiply - multiply inverted data with a constant (p1)
    + *   d2_to_blend - use channel data to blend between two constants (p1,p2)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_settexopparam>
    + * */
    +d2_s32 d2_settextureoperation( d2_device *handle, d2_u8 amode, d2_u8 rmode, d2_u8 gmode, d2_u8 bmode )
    +{
    +   d2_contextdata *ctx;
    +
    +   if(NULL != handle)
    +   {
    +      /*D2_VALIDATE( handle, D2_INVALIDDEVICE );*/
    +
    +      D2_CHECKERR( (amode < 8u), D2_INVALIDENUM );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +      D2_CHECKERR( (rmode < 8u), D2_INVALIDENUM );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +      D2_CHECKERR( (gmode < 8u), D2_INVALIDENUM );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +      D2_CHECKERR( (bmode < 8u), D2_INVALIDENUM );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +      ctx = D2_DEV(handle)->ctxselected;
    +      ctx->internaldirty |= d2_dirty_material;
    +
    +      ctx->texamode = amode;
    +      ctx->texrmode = rmode;
    +      ctx->texgmode = gmode;
    +      ctx->texbmode = bmode;
    +
    +      /* update precalculated values */
    +      d2_setuptextureblend_intern( handle, ctx );
    +
    +      D2_RETOK( handle );
    +   }
    +   else
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexopparam
    + * Set texture operation parameter.
    + *
    + * Several texture operations require additional constants. See <d2_settextureoperation>
    + * for a list and description of all operations and their constants.
    + * The index parameter selects the color channels for which new parameters are to be set.
    + *
    + * Both constant have to be in the range of 0 .. 255 unused constants (e.g. p2 in most
    + * operations) are ignored.
    + * Note that several color channel indices can be or'ed together.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - color channel index / indices
    + *   p1 - parameter 'p1' (see: <d2_settextureoperation>)
    + *   p2 - parameter 'p2' (see: <d2_settextureoperation>)
    + *
    + * color channel indices:
    + *   d2_cc_alpha - alpha channel
    + *   d2_cc_red - red channel
    + *   d2_cc_green - green channel
    + *   d2_cc_blue - blue channel
    + *   d2_cc_rgb - all channels except alpha
    + *   d2_cc_all - all channels
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *   <d2_settextureoperation>
    + * */
    +d2_s32 d2_settexopparam( d2_device *handle, d2_u32 index, d2_u32 p1, d2_u32 p2 )
    +{
    +   d2_contextdata *ctx;
    +
    +   /* (note) some compilers (e.g. MSVC) do not issue a warning if an actual function argument exceeds the datatype range
    +           (i.e. p1/p2 are 8bit unsigneds but passing 500 (test_texture_operations testcase) compiles without warnings) */
    +
    +
    +#ifndef _DEBUG
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +#endif /* _DEBUG */
    +   
    +   if(NULL != handle)
    +   {
    +      d2_alpha ap1, ap2;
    +      /* D2_CHECKERR( p1 >= 0, D2_VALUENEGATIVE ); */
    +      /* D2_CHECKERR( p2 >= 0, D2_VALUENEGATIVE ); */
    +      D2_CHECKERR( p1 < 256, D2_VALUETOOBIG );       /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +      D2_CHECKERR( p2 < 256, D2_VALUETOOBIG );       /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +      ap1 = (d2_alpha) p1;
    +      ap2 = (d2_alpha) p2;
    +
    +      ctx = D2_DEV(handle)->ctxselected;
    +      ctx->internaldirty |= d2_dirty_material;
    +
    +      /* store parameters */
    +      if(0 != (index & d2_cc_alpha))
    +      {
    +         ctx->texop_p1[0] = ap1;
    +         ctx->texop_p2[0] = ap2;
    +      }
    +
    +      if(0 != (index & d2_cc_red))
    +      {
    +         ctx->texop_p1[1] = ap1;
    +         ctx->texop_p2[1] = ap2;
    +      }
    +
    +      if(0 != (index & d2_cc_green))
    +      {
    +         ctx->texop_p1[2] = ap1;
    +         ctx->texop_p2[2] = ap2;
    +      }
    +
    +      if(0 != (index & d2_cc_blue))
    +      {
    +         ctx->texop_p1[3] = ap1;
    +         ctx->texop_p2[3] = ap2;
    +      }
    +
    +      /* update precalculated values */
    +      d2_setuptextureblend_intern( handle, ctx );
    +
    +      D2_RETOK( handle );
    +   }
    +   else
    +   {
    +      return D2_INVALIDDEVICE;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexturemapping
    + * Define texture mapping.
    + *
    + * This is the most basic function to setup the texture mapping frame of
    + * reference. You can directly specify the texture increments in u and v
    + * direction for stepping on the x or y axis.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x , y - position of the (u0,v0) texel on screen (fixedpoint)
    + *   u0, v0 - initial texture coordinates (valid at point x,y) (16:16 fixedpoint)
    + *   dxu, dxv - texture increment for a step in x direction (16:16 fixedpoint)
    + *   dyu, dyv - texture increment for a step in y direction (16:16 fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_settexturemapping( d2_device *handle, d2_point x, d2_point y, d2_s32 u0, d2_s32 v0, d2_s32 dxu, d2_s32 dyu, d2_s32 dxv, d2_s32 dyv )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +
    +   ctx->texlim[0].x1    = x;
    +   ctx->texlim[0].y1    = y;
    +   ctx->texlim[0].xadd2 = u0;
    +   ctx->texlim[0].yadd2 = v0;
    +   ctx->texlim[0].xadd  = dxu;
    +   ctx->texlim[0].yadd  = dyu; /* dxv in previous version */
    +   /* limiter2 x1,y1,xadd2,yadd2 omitted (identical to limiter1) */
    +   ctx->texlim[1].xadd  = dxv; /* dyu in previous version */
    +   ctx->texlim[1].yadd  = dyv;
    +
    +   ctx->internaldirty |= d2_dirty_texlim;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexelcenter
    + * Set texel center offset.
    + *
    + * Default texel center is top left corner (0.0 , 0.0)
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   x , y - subpixel position of the texel center (fixedpoint)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_settexelcenter( d2_device *handle, d2_point x, d2_point y )
    +{
    +   d2_contextdata *ctx;
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   ctx->internaldirty |= d2_dirty_material;
    +
    +   ctx->texcenterx = x << (16 - 4);  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   ctx->texcentery = y << (16 - 4);  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexclut
    + * Set texture colour palette pointer.
    + *
    + * For indexed texture formats (see: <d2_settexture>), a colour look-up table
    + * is used. This function registers a pointer to a ARGB CLUT (32 bit values, format 0xAARRGGBB)
    + * with the current context. The size of the CLUT must be 16 resp. 256 words (see note).
    + * 
    + * The pointer needs to be persistent, as the table is not immediately copied to the context.
    + * It is read once before the next object using textures is rendered or if <d2_settexclut_part> is used.
    + * If the CLUT is changed later on, d2_settexclut has to be called again to trigger a new
    + * upload.
    + *
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   clut   - persistent pointer to CLUT
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * note:
    + *   size of CLUT: -  16 x 32bit if feature bit D2FB_TEXCLUT256 = 0 (see <d2_getrevisionhw>)
    + *   size of CLUT: - 256 x 32bit if feature bit D2FB_TEXCLUT256 = 1 (see <d2_getrevisionhw>)
    + *
    + *   the parameter clut can be NULL. If the CLUT was cached then the allocated memory will be freed (see: <d2_settexclut_part>)
    + *
    + * see also:
    + *   <d2_settexture>, <d2_settexclut_part>
    + * */
    +d2_s32 d2_settexclut( d2_device *handle, d2_color* clut )
    +{
    +   d2_s32 i;
    +   d2_s32 clut_entries;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   D2_DEV(handle)->ctxselected->texclut = clut;
    +
    +   if(NULL == clut)
    +   {
    +      D2_DEV(handle)->ctxselected->texclutupload = 0;
    +      
    +      if(NULL != D2_DEV(handle)->ctxselected->texclut_cached)
    +      {
    +         d1_freemem(D2_DEV(handle)->ctxselected->texclut_cached);  
    +         D2_DEV(handle)->ctxselected->texclut_cached = NULL;
    +      }
    +   }
    +   else
    +   {
    +      if(0 != (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT256))
    +      {
    +         clut_entries = MAX_CLUT256_ENTRIES;
    +      }
    +      else 
    +      {
    +         clut_entries = MAX_CLUT16_ENTRIES;
    +      }
    +
    +      if(NULL != D2_DEV(handle)->ctxselected->texclut_cached)
    +      {
    +         for (i=0; i<clut_entries; i++)
    +         {
    +            D2_DEV(handle)->ctxselected->texclut_cached[i] = D2_DEV(handle)->ctxselected->texclut[i];
    +         }
    +      }
    +
    +      D2_DEV(handle)->ctxselected->texclutupload = 1;
    +      D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +   }
    +
    +   D2_RETOK( handle );
    +}
    + 
    +/*--------------------------------------------------------------------------
    + * function: d2_settexclut_part
    + * Set a part of the color lookup table.
    + *
    + * Only parts of the CLUT can be set or overridden.
    + * The CLUT content will be cached in the current context.
    + * If a pointer to a CLUT was given by <d2_settexclut> this CLUT contents is first copied to the context.
    + * The contents of clut_part is then copied to the cached CLUT starting at start_index with a length of length.
    + *
    + * The size of the CLUT is 256 resp. 16 (if feature bit D2FB_TEXCLUT256 = 1 resp. = 0 (see <d2_getrevisionhw>))
    + *
    + * parameters:
    + *   handle      - device pointer (see: <d2_opendevice>)
    + *   clut_part   - pointer to a segment for the CLUT
    + *   start_index - start index of the CLUT where clut_part will be copied to (0..size-1)
    + *   length      - number of CLUT entries to be copied (1..size)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + *
    + * see also:
    + *   <d2_settexclut>
    + * */
    +d2_s32 d2_settexclut_part( d2_device *handle, const d2_color* clut_part, d2_u32 start_index, d2_u32 length )
    +{
    +   d2_u32 i;
    +   d2_u32 max_index;
    +   d2_color** pclut_cached = &(D2_DEV(handle)->ctxselected->texclut_cached);
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   if(0 != (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT256) )
    +   {
    +      max_index = 256u;
    +   }
    +   else
    +   {
    +      max_index = 16u;
    +   }
    +
    +   if(NULL == clut_part)
    +   {
    +      D2_RETERR( handle, D2_NULLPOINTER);
    +   }
    +
    +   D2_CHECKERR( start_index            <  max_index, D2_VALUETOOBIG );       /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( length                 >          0, D2_VALUENEGATIVE );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( length                 <= max_index, D2_VALUETOOBIG );       /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (start_index + length) <= max_index, D2_VALUETOOBIG );       /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(NULL == *pclut_cached)
    +   {
    +      /* allocate the CLUT cache */
    +      *pclut_cached = (d2_color*)d1_allocmem(max_index * sizeof(d2_color));   
    +
    +      if(NULL == *pclut_cached)
    +      {
    +         D2_RETERR( handle, D2_NOMEMORY );
    +      }
    +
    +      /* initialize the CLUT cache */
    +      if(NULL != D2_DEV(handle)->ctxselected->texclut)
    +      {
    +         for(i=0; i<max_index; i++)
    +         {
    +            (*pclut_cached)[i] = D2_DEV(handle)->ctxselected->texclut[i];
    +         }
    +      }
    +
    +      else
    +      {
    +         for(i=0; i<max_index; i++)
    +         {
    +            (*pclut_cached)[i] = 0;
    +         }
    +      }
    +   }
    +
    +   /* copy the part to the CLUT cache */
    +   for(i=0; i<length; i++)
    +   {
    +      (*pclut_cached)[i+start_index] = clut_part[i];
    +   }
    +
    +   D2_DEV(handle)->ctxselected->texclutupload = 1;
    +   D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_writetexclut_direct
    + * Write a part of the color lookup table directly to the render buffer.
    + *
    + * Only parts of the CLUT can be set.
    + * The contents of clut_part is written directly to the render buffer starting at start_index with a length of length.
    + *
    + * The size of the CLUT is 256 resp. 16 (if feature bit D2FB_TEXCLUT256 = 1 resp. = 0 (see <d2_getrevisionhw>))
    + *
    + * parameters:
    + *   handle      - device pointer (see: <d2_opendevice>)
    + *   clut_part   - pointer to a segment for the CLUT
    + *   start_index - start index of the CLUT where clut_part will be written to (0..size-1)
    + *   length      - number of CLUT entries to write (1..size)
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * note:
    + *   - no data needs to be cached
    + *   - clut_part does not need to be persistent
    + *   - a context switch does not restore the contents of the CLUT
    + *
    + * see also:
    + *   <d2_settexclut> <d2_settexclut_part>
    + * */
    +d2_s32 d2_writetexclut_direct( d2_device *handle, const d2_color* clut_part, d2_u32 start_index, d2_u32 length )
    +{
    +   d2_u32 i;
    +   d2_u32 max_index;
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT) )
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   if(0 != (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT256))
    +   {
    +      max_index = 256u;
    +   }
    +   else
    +   {
    +      max_index = 16u;
    +   }
    +
    +   (void) max_index; /* suppress warning about unused variable in non-debug mode */
    +   if(NULL == clut_part)
    +   {
    +      D2_RETERR( handle, D2_NULLPOINTER);
    +   }
    +
    +   D2_CHECKERR( start_index            <  max_index, D2_VALUETOOBIG );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( length                 >          0, D2_VALUENEGATIVE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( length                 <= max_index, D2_VALUETOOBIG );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( (start_index + length) <= max_index, D2_VALUETOOBIG );     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   D2_DLISTWRITEU( D2_TEXCLUT_ADDR, start_index );
    +
    +   for(i=0; i<length; i++)
    +   {
    +      D2_DLISTWRITEU( D2_TEXCLUT_DATA, clut_part[i] );
    +   }
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexclut_offset
    + * Set index offset for indexed texture formats.
    + *
    + * For the indexed texture formats d2_mode_i4, d2_mode_i2 and d2_mode_i1 (see: <d2_settexture>)
    + * an offset to the color index can be used. 
    + *
    + * The offset is an 8 bit resp. 4 bit value (if feature bit D2FB_TEXCLUT256 = 1 resp. = 0 (see <d2_getrevisionhw>))
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   offset - offset to index (default = 0); will be or'ed with the index of the texel
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + *
    + * see also:
    + *  <d2_settexclut>  <d2_settexture>
    + * */
    +d2_s32 d2_settexclut_offset( d2_device *handle, d2_u32 offset )
    +{
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );              /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   offset &= 0xffu;
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT256))
    +   {
    +      D2_CHECKERR( offset         < 16, D2_VALUETOOBIG ); /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +      offset &= 0x0fu;
    +   }
    +
    +   D2_DEV(handle)->ctxselected->texclutoffset = (d2_u8)offset;
    +   D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_settexclut_format
    + * Set color format of texture CLUT.
    + *
    + * The Color lookup table has 256 entries of 32 bit color values. Each color value is coded as ARGB8888. 
    + * In case of RGB565 the CLUT 256x32bit is divided into a lower and an upper part for 256 16bit color entries. 
    + * One 32bit word contains two successive 16bit color entries.
    + * The lower 16 bit contain the first color entry and the upper 16 bit contain the next color entry.
    + * The upper part of the CLUT can be accessed by the texture unit by setting the texclut_offset to 0x80.
    + * When loading the CLUT 32bit words are written to the RAM. In this 16bit mode the driver has to take care to write the correct data.
    + *
    + * If the feature bit D2FB_TEXCLUT256 = 0 the format applies to 16 entries of 32 bit (see <d2_getrevisionhw>).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   format - color format
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + *
    + * color formats:
    + *
    + *   d2_mode_argb8888 - colored 32bit per pixel (default)
    + *   d2_mode_rgb565   - colored 16bit per pixel (alpha is blue)
    + *
    + * see also:
    + *   <d2_settexclut> <d2_settexture>
    + * */
    +d2_s32 d2_settexclut_format( d2_device *handle, d2_u32 format )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_TEXCLUT))
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   if(d2_mode_rgb565 == format)
    +   {
    +      ctx->clutmask  |= D2C_CLUTFORMAT1;
    +   }
    +   else
    +   {
    +      ctx->clutmask &= ~D2C_CLUTFORMAT1;
    +   }
    +
    +   D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_setcolorkey
    + * Set the color for color keying.
    + *
    + * Color keying compares every RGB value of a texture pixel with color_key.
    + * If the values are equal then Alpha as well as R, G and B are set to 0 to mark the pixel transparent.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   enable - enables color keying
    + *   color_key  - RGB value of color key 
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * note:
    + *   colorkeying is available if the feature bit D2FB_COLORKEY is set (see <d2_getrevisionhw>)
    + *
    + * see also:
    + *   <d2_settexture>
    + * */
    +d2_s32 d2_setcolorkey( d2_device *handle, d2_s32 enable, d2_color color_key )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 == (D2_DEV(handle)->hwrevision & D2FB_COLORKEY))
    +   {
    +      D2_RETERR( handle, D2_ILLEGALMODE );
    +   }
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +
    +   ctx->colorkey = color_key & 0x00ffffffu;
    +
    +   if(0 != enable)
    +   {
    +      ctx->colkeymask  = D2C_COLKEY_ENABLE;
    +   }
    +   else
    +   {
    +      ctx->colkeymask  = 0;
    +   }
    +
    +   D2_DEV(handle)->ctxselected->internaldirty |= d2_dirty_material;
    +
    +   D2_RETOK( handle );
    +}
    +
    +/*--------------------------------------------------------------------------
    + * Group: Texture Attribute Queries */
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_gettextureoperationa
    + * Query texture operation for alpha channel.
    + *
    + * See <d2_settextureoperation> for a list of texture operations
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   texture operation. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_gettextureoperationr>, <d2_gettextureoperationg>, <d2_gettextureoperationb>
    + * */
    +d2_u8 d2_gettextureoperationa( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->texamode;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_gettextureoperationr
    + * Query texture operation for red channel.
    + *
    + * See <d2_settextureoperation> for a list of texture operations
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   texture operation. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_gettextureoperationa>, <d2_gettextureoperationg>, <d2_gettextureoperationb>
    + * */
    +d2_u8 d2_gettextureoperationr( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->texrmode;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_gettextureoperationg
    + * Query texture operation for green channel.
    + *
    + * See <d2_settextureoperation> for a list of texture operations
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   texture operation. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_gettextureoperationa>, <d2_gettextureoperationr>, <d2_gettextureoperationb>
    + * */
    +d2_u8 d2_gettextureoperationg( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->texgmode;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_gettextureoperationb
    + * Query texture operation for blue channel.
    + *
    + * See <d2_settextureoperation> for a list of texture operations
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *
    + * returns:
    + *   texture operation. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_gettextureoperationa>, <d2_gettextureoperationr>, <d2_gettextureoperationg>
    + * */
    +d2_u8 d2_gettextureoperationb( d2_device *handle )
    +{
    +   d2_u8 ret;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   ret = D2_DEV(handle)->ctxselected->texbmode;
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_gettexopparam1
    + * Query texture operation parameter p1.
    + *
    + * See <d2_settexopparam> and <d2_settextureoperation> for details
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - color channel index
    + *
    + * color channel indices:
    + *   d2_cc_alpha - alpha channel
    + *   d2_cc_red - red channel
    + *   d2_cc_green - green channel
    + *   d2_cc_blue - blue channel
    + *
    + * returns:
    + *   texture operation parameter p1. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_settexopparam>
    + * */
    +d2_alpha d2_gettexopparam1( d2_device *handle, d2_u32 index )
    +{
    +   d2_alpha ret = (d2_alpha) D2_OK;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 != (index & d2_cc_alpha))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p1[0];
    +   }
    +
    +   if(0 != (index & d2_cc_red))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p1[1];
    +   }
    +
    +   if(0 != (index & d2_cc_green))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p1[2];
    +   }
    +
    +   if(0 != (index & d2_cc_blue))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p1[3];
    +   }
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_gettexopparam2
    + * Query texture operation parameter p2.
    + *
    + * See <d2_settexopparam> and <d2_settextureoperation> for details
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   index - color channel index
    + *
    + * color channel indices:
    + *   d2_cc_alpha - alpha channel
    + *   d2_cc_red - red channel
    + *   d2_cc_green - green channel
    + *   d2_cc_blue - blue channel
    + *
    + * returns:
    + *   texture operation parameter p2. undefined in
    + *   case of an error (check with <d2_geterror> or <d2_geterrorstring>)
    + *
    + * see also:
    + *   <d2_settexopparam>
    + * */
    +d2_alpha d2_gettexopparam2( d2_device *handle, d2_u32 index )
    +{
    +   d2_alpha ret = (d2_alpha)D2_OK;
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 != (index & d2_cc_alpha))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p2[0];
    +   }
    +
    +   if(0 != (index & d2_cc_red))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p2[1];
    +   }
    +
    +   if(0 != (index & d2_cc_green))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p2[2];
    +   }
    +
    +   if(0 != (index & d2_cc_blue))
    +   {
    +      ret = D2_DEV(handle)->ctxselected->texop_p2[3];
    +   }
    +
    +   (void)D2_SETOK( handle );
    +   return ret;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_textureoperator( const d2_contextdata *ctx, d2_u32 index, d2_u32 mode, d2_alpha *c1, d2_alpha *c2)
    +{
    +   switch(mode)
    +   {
    +      case d2_to_zero:
    +         *c1 = 0x00u; *c2 = 0x00u;
    +         break;
    +
    +      case d2_to_one:
    +         *c1 = 0xffu; *c2 = 0xffu;
    +         break;
    +
    +      case d2_to_replace:
    +         *c1 = ctx->texop_p1[index]; *c2 = ctx->texop_p1[index];
    +         break;
    +
    +      case d2_to_copy:
    +         *c1 = 0x00u; *c2 = 0xffu;
    +         break;
    +
    +      case d2_to_invert:
    +         *c1 = 0xffu; *c2 = 0x00u;
    +         break;
    +
    +      case d2_to_multiply:
    +         *c1 = 0x00u; *c2 = ctx->texop_p1[index];
    +         break;
    +
    +      case d2_to_invmultiply:
    +         *c1 = ctx->texop_p1[index]; *c2 = 0x00u;
    +         break;
    +
    +      case d2_to_blend:
    +         *c1 = ctx->texop_p1[index]; *c2 = ctx->texop_p2[index];
    +         break;
    +         
    +      default:
    +         break;
    +   }
    +}
    +
    +/*--------------------------------------------------------------------------
    + * precalculate color register settings for current texture blendmode
    + * */
    +void d2_setuptextureblend_intern( const d2_devicedata *handle, d2_contextdata *ctx )
    +{
    +   d2_alpha c1 = 0 , c2 = 0;
    +   d2_color b1, b2;
    +
    +   /* unused parameter */
    +   (void) handle;   /* PRQA S 3112 */ /* $Misra: #COMPILER_WARNING $*/
    +
    +   /* build alpha channel operands */
    +   d2_textureoperator( ctx, 0, ctx->texamode, &c1, &c2);
    +   b1 = (d2_u32)c1 << 24;
    +   b2 = (d2_u32)c2 << 24;
    +
    +   /* build red channel operands */
    +   d2_textureoperator( ctx, 1, ctx->texrmode, &c1, &c2);
    +   b1 |= (d2_u32)c1 << 16;
    +   b2 |= (d2_u32)c2 << 16;
    +
    +   /* build green channel operands */
    +   d2_textureoperator( ctx, 2, ctx->texgmode, &c1, &c2);
    +   b1 |= (d2_u32)c1 << 8;
    +   b2 |= (d2_u32)c2 << 8;
    +
    +   /* build blue channel operands */
    +   d2_textureoperator( ctx, 3, ctx->texbmode, &c1, &c2);
    +   b1 |= (d2_u32)c1;
    +   b2 |= (d2_u32)c2;
    +
    +   /* writeback */
    +   ctx->texmodecl[0] = b1;
    +   ctx->texmodecl[1] = b2;
    +
    +   /* mark as dirty */
    +   ctx->internaldirty |= d2_dirty_premalpha_t;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +void d2_calctexturealpha_intern( d2_contextdata *ctx )
    +{
    +   d2_u32 texAlpha;
    +   d2_color tc1, tc2;
    +
    +   texAlpha = ctx->constalpha >> 8;
    +   tc1 = ((texAlpha * (ctx->texmodecl[0] >> 24)) + 0x00ffffffu) & 0xff000000u;
    +   tc2 = ((texAlpha * (ctx->texmodecl[1] >> 24)) + 0x00ffffffu) & 0xff000000u;
    +
    +   ctx->texcolreg[0] = (ctx->texmodecl[0] & 0x00ffffffu) | tc1;
    +   ctx->texcolreg[1] = (ctx->texmodecl[1] & 0x00ffffffu) | tc2;
    +
    +   ctx->internaldirty &= ~d2_dirty_premalpha_t & 255u;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * */
    +void d2_calctexturemask_intern( d2_contextdata *ctx )
    +{
    +   d2_u32 xmask, ymask;
    +
    +   if(0 != (ctx->texmode & d2_tm_wrapu))
    +   {
    +      /* wrapping. find next larger power of two - 1 */
    +      xmask = (d2_u32) d2_pow2mask( (d2_u32) ctx->texwidth - 1 );
    +   }
    +   else
    +   {
    +      /* clamping */
    +      xmask = (d2_u32) (ctx->texwidth - 1);
    +   }
    +
    +   if(0 != (ctx->texmode & d2_tm_wrapv))
    +   {
    +      /* wrapping. find next larger power of two - 1 */
    +      ymask = (d2_u32) d2_pow2mask( (d2_u32) ctx->texheight - 1 );
    +      ymask = (d2_u32) d2_pow2mask( (d2_u32)((d2_s32)ymask * ctx->texpitch) );
    +   }
    +   else
    +   {
    +      /* clamping */
    +      ymask = (d2_u32) (ctx->texheight - 1);
    +      ymask = (d2_u32) ((d2_s32)ymask * ctx->texpitch);
    +   }
    +
    +   /* store */
    +   ctx->texwrapmask = (ymask << 11) | (xmask & 0x7ffu);
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_setupuvlimiter_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox )
    +{
    +   d2_s32 x, y, s1, s2, xa, ya;
    +
    +   x = ctx->texlim[0].x1 - bbox->xmin;
    +   y = ctx->texlim[0].y1 - bbox->ymin;
    +   s1 = -( ((x * ctx->texlim[0].xadd) + (y * ctx->texlim[0].yadd)) >> 4);   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s2 = -( ((x * ctx->texlim[1].xadd) + (y * ctx->texlim[1].yadd)) >> 4);   /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   s1 += ctx->texcenterx + ctx->texlim[0].xadd2;
    +   s2 += ctx->texcentery + ctx->texlim[0].yadd2;
    +
    +   D2_DLISTWRITES( D2_LUSTART, s1 );
    +   D2_DLISTWRITES( D2_LUXADD , ctx->texlim[0].xadd );
    +   D2_DLISTWRITES( D2_LUYADD , ctx->texlim[0].yadd );
    +
    +   xa = ctx->texlim[1].xadd;
    +   ya = ctx->texlim[1].yadd;
    +   D2_DLISTWRITES( D2_LVSTARTI, (s2 >> 16) * ctx->texpitch );     /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   D2_DLISTWRITEU( D2_LVSTARTF, (d2_u16)s2 );
    +
    +   D2_DLISTWRITES( D2_LVXADDI, (xa >> 16) * ctx->texpitch );      /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   D2_DLISTWRITES( D2_LVYADDI, (ya >> 16) * ctx->texpitch );      /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   D2_DLISTWRITEU( D2_LVYXADDF, ((d2_u16)xa) | (((d2_u32)((d2_u16)ya)) << 16) );
    +
    +   return;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static D2_INLINE void d2_setupuvlimiter_invert_intern( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox )
    +{
    +   d2_s32 x, y, s1 , s2, xa, ya;
    +
    +   x = ctx->texlim[0].x1 - bbox->xmin;
    +   y = ctx->texlim[0].y1 - bbox->ymax;
    +   s1 = -( ((x * ctx->texlim[0].xadd) + (y * ctx->texlim[0].yadd)) >> 4);    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   s2 = -( ((x * ctx->texlim[1].xadd) + (y * ctx->texlim[1].yadd)) >> 4);    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   s1 += ctx->texcenterx + ctx->texlim[0].xadd2;
    +   s2 += ctx->texcentery + ctx->texlim[0].yadd2;
    +
    +   D2_DLISTWRITES( D2_LUSTART, s1 );
    +   D2_DLISTWRITES( D2_LUXADD , ctx->texlim[0].xadd );
    +   D2_DLISTWRITES( D2_LUYADD , -ctx->texlim[0].yadd );
    +
    +   xa = ctx->texlim[1].xadd;
    +   ya = -ctx->texlim[1].yadd;
    +   D2_DLISTWRITES( D2_LVSTARTI, (s2 >> 16) * ctx->texpitch );             /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   D2_DLISTWRITEU( D2_LVSTARTF, (d2_u16)s2 );
    +
    +   D2_DLISTWRITES( D2_LVXADDI, (xa >> 16) * ctx->texpitch );              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   D2_DLISTWRITES( D2_LVYADDI, (ya >> 16) * ctx->texpitch );              /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   D2_DLISTWRITEU( D2_LVYXADDF, ((d2_u16)xa) | (((d2_u32)((d2_u16)ya)) << 16) );  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +   return;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +void d2_setuptexture( d2_devicedata *handle, const d2_contextdata *ctx, const d2_bbox *bbox, d2_s32 flip )
    +{
    +   if(d2_fm_texture == ctx->fillmode)
    +   {
    +      if(0 != flip)
    +      {
    +         d2_setupuvlimiter_invert_intern( handle, ctx, bbox );
    +      }
    +      else
    +      {
    +         d2_setupuvlimiter_intern( handle, ctx, bbox );
    +      }
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_triangle.c b/src/drivers/dave2d/src/dave_triangle.c
    new file mode 100644
    index 000000000..9a565360f
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_triangle.c
    @@ -0,0 +1,437 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_triangle.c (%version: 18 %)
    + *          created Mon Jan 24 16:13:27 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Feb 19 16:12:50 2007 %  (%derived_by:  hh74036 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_viewport.h"
    +#include "dave_render.h"
    +#include "dave_pattern.h"
    +#include "dave_triangle.h"
    +#include "dave_edge.h"
    +#include "dave_line.h"
    +#include "dave_texture.h"
    +#include "dave_polyline.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_s32 d2_rendertri_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags ); /* MISRA */
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_s32 d2_rendertri_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags )
    +{
    +   d2_bbox bbox;
    +   d2_u32 bR1, bR2, bR3;
    +   d2_u32 dxb1, dxb2;
    +   d2_u32 control, delay;
    +   d2_limdata edge[3];
    +
    +   /* find deltas */
    +   d2_s32 dx1 = x2 - x1;
    +   d2_s32 dx2 = x3 - x2;
    +   d2_s32 dx3 = x1 - x3;
    +   d2_s32 dy1 = y2 - y1;
    +   d2_s32 dy2 = y3 - y2;
    +   d2_s32 dy3 = y1 - y3;
    +
    +   /* build masks from signbits */
    +   d2_u32 dxm = ((dx1 < 0) ? 1u : 0) | ((dx2 < 0) ? 2u : 0) | ((dx3 < 0) ? 4u : 0);
    +   d2_u32 dym = ((dy1 < 0) ? 1u : 0) | ((dy2 < 0) ? 2u : 0) | ((dy3 < 0) ? 4u : 0);
    +   d2_u32 idxm = dxm ^ 7u;
    +   d2_u32 idym = dym ^ 7u;
    +
    +   /* catch degenerate triangle (zero area) */
    +   if(0 != (idxm & idym))
    +   {
    +      if(
    +         (0 == ( (dx1 | dy1) & ~7 )) ||    /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +         (0 == ( (dx2 | dy2) & ~7 )) ||    /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +         (0 == ( (dx3 | dy3) & ~7 ))       /* PRQA S 4130 */ /* $Misra: #PERF_BITWISE $*/
    +         )
    +      {
    +         return 0;
    +      }
    +   }
    +
    +   /* classify edges (right edge flags) - basically inverted dys
    +    * but using dxs instead of dys for horizontal edges */
    +   bR1 = (0 == dy1) ? (idxm & 1u) : (idym & 1u);
    +   bR2 = (0 == dy2) ? (idxm & 2u) : (idym & 2u);
    +   bR3 = (0 == dy3) ? (idxm & 4u) : (idym & 4u);
    +
    +   /* find x minimum */
    +   switch(dxm & (idxm >> 1))
    +   {
    +      case 0: bbox.xmin = (d2_point) D2_FLOOR4( x1 ); break;
    +      case 1: bbox.xmin = (d2_point) D2_FLOOR4( x2 ); break;
    +      case 2: bbox.xmin = (d2_point) D2_FLOOR4( x3 ); break;
    +      default:
    +         break;
    +   }
    +
    +   /* find x maximum */
    +   switch(idxm & (dxm >> 1))
    +   {
    +      case 0: bbox.xmax = (d2_point) D2_CEIL4( x1 ); break;
    +      case 1: bbox.xmax = (d2_point) D2_CEIL4( x2 ); break;
    +      case 2: bbox.xmax = (d2_point) D2_CEIL4( x3 ); break;
    +      default:
    +         break;
    +   }
    +
    +   /* find y minimum */
    +   switch (dym & (idym >> 1))
    +   {
    +      case 0: bbox.ymin = (d2_point) D2_FLOOR4( y1 ); break;
    +      case 1: bbox.ymin = (d2_point) D2_FLOOR4( y2 ); break;
    +      case 2: bbox.ymin = (d2_point) D2_FLOOR4( y3 ); break;
    +      default:
    +         break;
    +   }
    +
    +   /* find y maximum */
    +   switch(idym & (dym >> 1))
    +   {
    +      case 0: bbox.ymax = (d2_point) D2_CEIL4( y1 ); break;
    +      case 1: bbox.ymax = (d2_point) D2_CEIL4( y2 ); break;
    +      case 2: bbox.ymax = (d2_point) D2_CEIL4( y3 ); break;
    +      default:
    +         break;
    +   }
    +
    +   /* clipping */
    +   if(0 == d2_clipbbox_intern( handle, &bbox ))
    +   {
    +      return 0;
    +   }
    +
    +   /* set register values (material parameters) */
    +   d2_setupmaterial_intern( handle, ctx );
    +
    +   /* make relative */
    +   x1 = (d2_point)(x1 - bbox.xmin);
    +   y1 = (d2_point)(y1 - bbox.ymin);
    +   x2 = (d2_point)(x2 - bbox.xmin);
    +   y2 = (d2_point)(y2 - bbox.ymin);
    +   x3 = (d2_point)(x3 - bbox.xmin);
    +   y3 = (d2_point)(y3 - bbox.ymin);
    +
    +   /* calc edge interpolation parameters */
    +   control = 0u;
    +
    +   if(0 != (flags & d2_edge0_shared))
    +   {
    +      d2_triedge_setup_intern( &edge[0], x1, y1, dx1, dy1, bR1 );
    +      control |= D2C_LIM1THRESHOLD;
    +      edge[0].start += D2_FIX16(1) / 2;
    +   }
    +   else
    +   {
    +      if(0 != (ctx->features & d2_feat_blur))
    +      {
    +         d2_triedge_setupblur_intern( &edge[0], x1, y1, dx1, dy1, ctx );
    +      }
    +      else
    +      {
    +         d2_triedge_setup_intern( &edge[0], x1, y1, dx1, dy1, bR1 );
    +         edge[0].start += D2_FIX16(1);
    +      }
    +   }
    +
    +   if(0 != (flags & d2_edge1_shared))
    +   {
    +      d2_triedge_setup_intern( &edge[1], x2, y2, dx2, dy2, bR2 );
    +      control |= D2C_LIM2THRESHOLD;
    +      edge[1].start += D2_FIX16(1) / 2;
    +   }
    +   else
    +   {
    +      if(0 != (ctx->features & d2_feat_blur))
    +      {
    +         d2_triedge_setupblur_intern( &edge[1], x2, y2, dx2, dy2, ctx );
    +      }
    +      else
    +      {
    +         d2_triedge_setup_intern( &edge[1], x2, y2, dx2, dy2, bR2 );
    +         edge[1].start += D2_FIX16(1);
    +      }
    +   }
    +
    +   if(0 != (flags & d2_edge2_shared))
    +   {
    +      d2_triedge_setup_intern( &edge[2], x3, y3, dx3, dy3, bR3 );
    +      control |= D2C_LIM3THRESHOLD;
    +      edge[2].start += D2_FIX16(1) / 2;
    +   }
    +   else
    +   {
    +      if(0 != (ctx->features & d2_feat_blur))
    +      {
    +         d2_triedge_setupblur_intern( &edge[2], x3, y3, dx3, dy3, ctx );
    +      }
    +      else
    +      {
    +         d2_triedge_setup_intern( &edge[2], x3, y3, dx3, dy3, bR3 );
    +         edge[2].start += D2_FIX16(1);
    +      }
    +   }
    +
    +   /* handle nonantialiased */
    +   if(0 == (ctx->features & d2_feat_aa))
    +   {
    +      control |= D2C_LIM1THRESHOLD | D2C_LIM2THRESHOLD | D2C_LIM3THRESHOLD;
    +   }
    +
    +   /* optimize for span abort / span store */
    +   dxb1 = (dxm & dym);
    +   delay = 0u;
    +
    +   if(0 != (bR1 ^ (bR2 >> 1) ^ (bR3 >> 2)))
    +   {
    +      /* two edges left */
    +      dxb2 = (idym | dxm );
    +
    +      if( (0u != dxb1) && (7u != dxb2))
    +      {
    +         d2_s32 pymid, pymax;
    +
    +         pymax = bbox.ymax - bbox.ymin;
    +
    +         /* left edges have different directions
    +          * find mid y scanline (ymid - ymin) */
    +         switch( (dym & (idym >> 1)) ^ (idym & (dym >> 1)) )
    +         {
    +            case 1: pymid = y3; break;
    +            case 2: pymid = y2; break;
    +            case 3: pymid = y1; break;
    +            default:
    +               pymid = y1; break; /* MISRA */
    +         }
    +
    +         /* find larger half (note: could improve heuristics to consider whole area) */
    +         if(pymid > (pymax / 2))
    +         {
    +            dxb1 = 0; /* bottom-up */
    +            delay = (d2_u32)D2_INT4(pymax - pymid) + 1u;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         }
    +         else
    +         {
    +            delay = (d2_u32)D2_INT4(pymid) + 1u;            /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +         }
    +      }
    +   }
    +
    +   /* setup rasterization flags */
    +   control |= D2C_LIM1ENABLE | D2C_LIM2ENABLE | D2C_LIM3ENABLE | D2C_SPANABORT;
    +
    +   /* disable spanstore for thin geometry (not supported in hw anyway) */
    +   if( (bbox.xmax - bbox.xmin) >= D2_FIX4(4) )              /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   {
    +      control |= D2C_SPANSTORE;
    +   }
    +
    +   /* check for alpha gradients */
    +   if(0 != (ctx->alphamode & (d2_am_gradient1 | d2_am_gradient2)))
    +   {
    +      control = d2_initgradients_intern( handle, ctx, &bbox, 3, control );
    +
    +      if(0 == (control & D2C_SPANSTORE))
    +      {
    +         dxb1 = 1u;
    +      }
    +   }
    +
    +   /* bottom-up rendering / left edges are x-decreasing */
    +   if(0 == dxb1)
    +   {
    +      d2_s32 h = D2_INT4( bbox.ymax - bbox.ymin );    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +      d2_invertlimiter_intern(&edge[0], h);
    +      d2_invertlimiter_intern(&edge[1], h);
    +      d2_invertlimiter_intern(&edge[2], h);
    +      d2_setuppattern( handle, ctx, &bbox, 1 );
    +      d2_setuptexture( handle, ctx, &bbox, 1 );
    +   }
    +   else
    +   {
    +      d2_setuppattern( handle, ctx, &bbox, 0 );
    +      d2_setuptexture( handle, ctx, &bbox, 0 );
    +   }
    +
    +   /* set register values (geometric parameters) */
    +   D2_DLISTWRITES( D2_L1START, edge[0].start );
    +   D2_DLISTWRITES( D2_L1XADD , edge[0].xadd );
    +   D2_DLISTWRITES( D2_L1YADD , edge[0].yadd );
    +   D2_DLISTWRITES( D2_L2START, edge[1].start );
    +   D2_DLISTWRITES( D2_L2XADD , edge[1].xadd );
    +   D2_DLISTWRITES( D2_L2YADD , edge[1].yadd );
    +   D2_DLISTWRITES( D2_L3START, edge[2].start );
    +   D2_DLISTWRITES( D2_L3XADD , edge[2].xadd );
    +   D2_DLISTWRITES( D2_L3YADD , edge[2].yadd );
    +
    +   D2_DLISTWRITEU( D2_CONTROL, control );
    +
    +   /* start rendering */
    +   if(0 == dxb1)
    +   {
    +      d2_startrender_bottom_intern( handle, &bbox, delay + 1u );
    +   }
    +   else
    +   {
    +      d2_startrender_intern( handle, &bbox, delay + 1u );
    +   }
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendertri_solid( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags )
    +{
    +   (void)d2_rendertri_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, x3, y3, flags );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendertri_shadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags )
    +{
    +   d2_point sx,sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   (void)d2_rendertri_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 + sx), (d2_point)(y1 + sy), (d2_point)(x2 + sx), (d2_point)(y2 + sy), (d2_point)(x3 + sx), (d2_point)(y3 + sy), flags );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendertri_solidshadow( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags )
    +{
    +   d2_point sx,sy;
    +
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_rendertri_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x1 + sx), (d2_point)(y1 + sy), (d2_point)(x2 + sx), (d2_point)(y2 + sy), (d2_point)(x3 + sx), (d2_point)(y3 + sy), flags );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_rendertri_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, x3, y3, flags );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + * shared edges do not contribute to vertex tangents. to implement this
    + * a set of line/open polyline/closed polyline configurations is used
    + * depending on the shared edge configuration
    + * */
    +d2_s32 d2_rendertri_outline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags )
    +{
    +   d2_width wo = (d2_width)(D2_DEV(handle)->outlinewidth * 2);
    +   d2_contextdata *ctx = D2_DEV(handle)->ctxoutline;
    +   d2_point verts[3*2];
    +
    +   /* isolate sharing flags */
    +   flags &= (d2_edge0_shared | d2_edge1_shared | d2_edge2_shared);
    +
    +   /* skip invisible cases */
    +   if(wo < D2_EPSILON)
    +   {
    +      return D2_OK;
    +   }
    +
    +   /* special case all sharing combinations */
    +   switch(flags)
    +   {
    +      /* no shared edge - use a closed polyline */
    +      case 0:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x2;  verts[3] = y2;
    +         verts[4] = x3;  verts[5] = y3;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_closed, 0,0 );
    +         break;
    +
    +         /* single shared edge - use an open polyline */
    +      case d2_edge0_shared:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x3;  verts[3] = y3;
    +         verts[4] = x2;  verts[5] = y2;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_exclude_both, 0,0 );
    +         break;
    +
    +      case d2_edge1_shared:
    +         verts[0] = x2;  verts[1] = y2;
    +         verts[2] = x1;  verts[3] = y1;
    +         verts[4] = x3;  verts[5] = y3;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_exclude_both, 0,0 );
    +         break;
    +
    +      case d2_edge2_shared:
    +         verts[0] = x1;  verts[1] = y1;
    +         verts[2] = x2;  verts[3] = y2;
    +         verts[4] = x3;  verts[5] = y3;
    +         (void)d2_renderpolyline_intern( D2_DEV(handle), ctx, verts, NULL, 3, wo, d2_le_exclude_both, 0,0 );
    +         break;
    +
    +         /* two shared edges - use a single line */
    +      case d2_edge0_shared | d2_edge1_shared:
    +         (void)d2_renderline_outline_I( handle, x1, y1, x3, y3, wo, d2_le_exclude_both );
    +         break;
    +
    +      case d2_edge0_shared | d2_edge2_shared:
    +         (void)d2_renderline_outline_I( handle, x2, y2, x3, y3, wo, d2_le_exclude_both );
    +         break;
    +
    +      case d2_edge1_shared | d2_edge2_shared:
    +         (void)d2_renderline_outline_I( handle, x1, y1, x2, y2, wo, d2_le_exclude_both );
    +         break;
    +
    +         /* more than two shared edges - no outline at all */
    +
    +      default:
    +         break;
    +   }
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_rendertri_solidoutline( d2_device *handle, d2_point x1, d2_point y1, d2_point x2, d2_point y2, d2_point x3, d2_point y3, d2_u32 flags )
    +{
    +   /* render outline */
    +   (void)d2_rendertri_outline( D2_DEV(handle), x1, y1, x2, y2, x3, y3, flags );
    +
    +   /* render solid [base part] */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_rendertri_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x1, y1, x2, y2, x3, y3, flags );
    +
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    diff --git a/src/drivers/dave2d/src/dave_utility.c b/src/drivers/dave2d/src/dave_utility.c
    new file mode 100644
    index 000000000..30b37bd9b
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_utility.c
    @@ -0,0 +1,470 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_utility.c (%version: 8 %)
    + *          created Tue Jul 19 12:53:28 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Thu Nov 16 10:56:45 2006 %  (%derived_by:  hh74040 %)
    + *
    + * Changes:
    + *  2007-12-07 ASc  add error checking to d2_utility_perspectivewarp() 
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs 
    + *  2012-09-25 BSp  MISRA cleanup
    + *  2016-06-29 MHo  bugfix in fbblitcopy: handle SRC below DST in case of overlapping rects correctly in presence of an asymmetric clip rect
    + *  2017-07-27 HFu  bugfix in fbblitcopy: corrected wait-insert to full wait instead of pipeline only
    + */
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Utility Functions
    + * Triangle mapping and perspective warp operations
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_texture.h"
    +#include "dave_utility.h"
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_utility_maptriangle
    + * This function uses d2_settexturemapping to map a texture on a triangle.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   points - ptr to array of six floats containing the screen positions (x,y pairs)
    + *   uvs - ptr to array of six floats containing the texture coordinates (u,v pairs)
    + *
    + * Please remember that this function has to access the current texture details
    + * (width, height and pitch) in order to calculate a correct mapping. So the
    + * final texture must be active in the selected context at the time
    + * d2_utility_maptriangle is called.
    + * d2_utility_maptriangle is internally using d2_settexturemapping
    + * and is overwriting the current values.
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * see also:
    + *  <d2_settexturemapping> */
    +d2_s32 d2_utility_maptriangle( d2_device *handle, const d2_f32 *points, const d2_f32 *uvs )
    +{
    +   d2_contextdata *ctx;
    +   d2_s32 dxu, dxv, dyu, dyv;
    +   d2_f32 d, dx, dy;
    +   d2_f32 tw, th;
    +
    +   ctx = D2_DEV(handle)->ctxselected;
    +   tw = ((d2_f32)ctx->texwidth) * 65536.0f;
    +   th = ((d2_f32)ctx->texheight) * 65536.0f;
    +
    +   d = 
    +      (
    +         (points[0 * 2] - points[2 * 2]) 
    +         * 
    +         (points[(1 * 2) + 1] - points[(2 * 2) + 1])
    +       )
    +      -
    +      (
    +         (points[1 * 2] - points[2*2])
    +         *
    +         (points[(0 * 2) + 1] - points[(2 * 2) + 1])
    +       )
    +      ;
    +   /* validate. if d==0 use dxyuv=0 [no area triangle] */
    +   dx = tw / d;
    +   dy = th / d;
    +
    +   dxu = (d2_s32)
    +      (
    +         (
    +            (
    +               (
    +                  uvs[0 * 2]
    +                  -
    +                  uvs[2 * 2]
    +                )
    +               *
    +               (
    +                  points[(1 * 2) + 1]
    +                  -
    +                  points[(2 * 2) + 1]
    +                )
    +             )
    +            -
    +            (
    +               (
    +                  uvs[1 * 2]
    +                  -
    +                  uvs[2 * 2]
    +                )
    +               *
    +               (
    +                  points[(0 * 2) + 1]
    +                  -
    +                  points[(2 * 2) + 1]
    +                )
    +             )
    +          )
    +         * dx
    +       );
    +
    +   dxv = (d2_s32)
    +      (
    +         (
    +            (
    +               (
    +                  uvs[(0 * 2) + 1]
    +                  -
    +                  uvs[(2 * 2) + 1]
    +                )
    +               *
    +               (
    +                  points[(1 * 2) + 1]
    +                  -
    +                  points[(2 * 2) + 1]
    +                )
    +             )
    +            - 
    +            (
    +               (
    +                  uvs[(1 * 2) + 1]
    +                  -
    +                  uvs[(2 * 2) + 1]
    +                )
    +               *
    +               (
    +                  points[(0 * 2) + 1]
    +                  - 
    +                  points[(2 * 2) + 1]
    +                )
    +             )
    +          )
    +         * dy
    +       );
    +   
    +   dyu = (d2_s32)
    +      (
    +         (
    +            (
    +               (
    +                  uvs[1 * 2]
    +                  -
    +                  uvs[2 * 2]
    +                )
    +               *
    +               (
    +                  points[0 * 2]
    +                  -
    +                  points[2 * 2]
    +                )
    +             )
    +            -
    +            (
    +               (
    +                  uvs[0 * 2]
    +                  -
    +                  uvs[2 * 2]
    +                )
    +               *
    +               (
    +                  points[1 * 2]
    +                  -
    +                  points[2 * 2]
    +                )
    +             )
    +          )
    +         * dx
    +       );
    +
    +   dyv = (d2_s32)
    +      (
    +         (
    +            (
    +               (
    +                  uvs[(1 * 2) + 1]
    +                  -
    +                  uvs[(2 * 2) + 1]
    +                )
    +               *
    +               (
    +                  points[0 * 2]
    +                  -
    +                  points[2 * 2]
    +                )
    +             )
    +            -
    +            (
    +               (
    +                  uvs[(0 * 2) + 1]
    +                  -
    +                  uvs[(2 * 2) + 1]
    +                )
    +               *
    +               (
    +                  points[1 * 2]
    +                  -
    +                  points[2 * 2]
    +                )
    +             )
    +          )
    +         * dy
    +       );
    +       
    +   
    +   return d2_settexturemapping( handle, (d2_point) (points[0] * 16), (d2_point) (points[1] * 16), (d2_s32)(uvs[0] * tw), (d2_s32)(uvs[1] * th), dxu, dyu, dxv, dyv );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_utility_perspectivewarp
    + * Copies an image in perspective manner to a destination rectangle.
    + *
    + * d2_utility_perspectivewarp is internally using d2_settexturemapping
    + * and is overwriting the current values.
    + *
    + * (see pwe.gif)
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   srcwidth - width of source rectangle in pixels
    + *   srcheight - heigth of source rectangle in pixels
    + *   srcx - x position in source bitmap
    + *   srcy - y position in source bitmap
    + *   dstwidth - width of destination rectangle in pixels
    + *   dstheight - height of destination rectangle in pixels
    + *   dstx - x position in destination bitmap
    + *   dsty - y position in destination bitmap
    + *   wt - 1/z (z>1) value in 16 Bit fraction (z=2 -> wt=65536/2)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * example:
    + * Copy a 256x256 source texture into a 640x480 destination rectangle:
    + *
    + * (start code)
    + * ...
    + * d2_settexture( handle, texture, 256, 256, 256, d2_mode_rgb565 );
    + * d2_settexturemode( handle, 0 );
    + * d2_setfillmode( handle, d2_fm_texture );
    + * d2_utility_perspectivewarp(  handle, 256, 256, 0, 0, 640, 480, 0, 0, 65536/4 );
    + * ...
    + * (end code)
    + *
    + * limitations:
    + * This function is not meant for dynamic perspective animations.
    + *
    + * see also:
    + *  <d2_settexturemapping>
    + * */
    +d2_s32 d2_utility_perspectivewarp( d2_device *handle, d2_u16 srcwidth, d2_u16 srcheight, d2_s16 srcx, d2_s16 srcy, d2_s16 dstwidth, d2_s16 dstheight, d2_s16 dstx, d2_s16 dsty, d2_u16 wt )
    +{
    +   d2_u32 y;
    +   d2_u32 pu  = 0;
    +   d2_u32 pv  = 0;
    +   d2_u32 aw  = (d2_u32) ( (65536 - wt) / dstheight );
    +   d2_u32 ayv = (d2_u32) ( (1 << 16) / dstheight );
    +   d2_u32 axu = wt;
    +   d2_u32 ayu = (d2_u32) ( (32767 - (wt >> 1)) / dstheight );
    +
    +   for(y=0; y<(d2_u32)dstheight; y++ )
    +   {
    +      d2_s32 result;
    +      d2_u32 tty = ((pv << 16) / wt) * srcheight;
    +      d2_u32 tlx = ((pu << 16) / wt) * srcwidth;
    +      d2_u32 dxu = (d2_u32) ( (((axu << 16) / wt) * srcwidth) / (d2_u16)dstwidth );
    +
    +      result = d2_settexturemapping(
    +         handle,
    +         (d2_point)(dstx << 4),                 /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         (d2_point)((dsty + (d2_s16)y) << 4),   /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         (d2_s32)tlx + ((d2_s32)srcx << 16),    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         (d2_s32)tty + ((d2_s32)srcy << 16),    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +         (d2_s32)dxu,
    +         0, 0, 0
    +                                    );
    +      if(D2_OK != result)
    +      {
    +         return result;
    +      }
    +
    +      result = d2_renderbox( handle, (d2_point)(dstx << 4), (d2_point)((dsty + (d2_s16)y) << 4), (d2_width)(dstwidth << 4), 1 << 4 );  /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +      if(D2_OK != result)
    +      {
    +         return result;
    +      }
    +
    +      pu += ayu;
    +      pv += ayv;
    +      wt = (d2_u16)(wt + (d2_u16)aw);
    +   }
    +
    +   return D2_OK;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_utility_fbblitcopy
    + * Copy a rectangular part inside the current framebuffer.
    + *
    + * This is a wrapper function around <d2_blitcopy>, which copies a rectangular region inside a single buffer.
    + * Source and destination buffer are the current framebuffer, set via <d2_framebuffer>.
    + * This function handles the different cases of potentially overlapping source and destination areas and makes sure
    + * no read-after-write problems arise.
    + * Note that both source and destination rectangles need to lie fully inside the framebuffer for this function to work
    + * correctly.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   width, height - size of source/destination rectangle in pixels (integer)
    + *   srcx, srcy  - top/left coordinate of source rectangle (integer)
    + *   dstx, dsty - top/left coordinate of destination rectangle (integer)
    + *   flags - any combination of blit flag bits (see below), passed on to <d2_blitcopy>
    + *
    + * flags parameter bits (only one bit allowed):
    + *   d2_bf_no_blitctxbackup - for this blit don't backup context data for better performance; previous texture modes get lost and must be set again
    + *
    + * returns:
    + *   errorcode (D2_OK if successful) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_utility_fbblitcopy( d2_device *handle, d2_u16 width, d2_u16 height, d2_blitpos srcx, d2_blitpos srcy, d2_blitpos dstx, d2_blitpos dsty, d2_u32 flags)
    +{
    +   d2_s32 result = D2_OK;
    +   void *fb_ptr, *fb_ptr_blit;
    +   d2_s32 fb_pitch, fb_pitch_blit;
    +   d2_u16 fb_width, fb_height;
    +   d2_u8 fb_format, fb_bpp;
    +   d2_blitpos srcy_blit;
    +   d2_u8 flipped = 0;
    +   d2_s16 clip_ymin = 0, clip_ymax = 0;
    +
    +   D2_VALIDATEP( handle, D2_INVALIDDEVICE );                                                     /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( width>0, D2_INVALIDWIDTH );                                                      /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( height>0, D2_INVALIDHEIGHT );                                                    /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( width<=1024, D2_INVALIDWIDTH );                                                  /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_VALIDATE( height<=1024, D2_INVALIDHEIGHT );                                                /* PRQA S 4130, 3112 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* get current framebuffer parameters and set as blit source */
    +   fb_ptr    = D2_DEV(handle)->framebuffer;
    +   fb_format = (d2_u8)(D2_DEV(handle)->fbformat);
    +   fb_bpp    = (d2_u8)(D2_DEV(handle)->bpp);
    +   fb_pitch  = D2_DEV(handle)->pitch;
    +   fb_width  = (d2_u16)(D2_DEV(handle)->fbwidth);
    +   fb_height = (d2_u16)(D2_DEV(handle)->fbheight);
    +
    +   /* blit pitch has to be positive. flip vertical axis for blit source/texture if required */
    +   if (fb_pitch < 0)
    +   {
    +      d2_s32 fb_ptr_offset = (d2_s32)(fb_height-1)*fb_pitch*(d2_s32)fb_bpp;
    +      fb_ptr_blit   = (void*)( ((d2_char*)fb_ptr) + fb_ptr_offset );
    +      fb_pitch_blit = -fb_pitch;
    +      srcy_blit     = (d2_blitpos)(d2_s32)(fb_height-height-srcy);
    +      flags        ^= d2_bf_mirrorv;
    +   }
    +   else
    +   {
    +      fb_ptr_blit   = fb_ptr;
    +      fb_pitch_blit = fb_pitch;
    +      srcy_blit     = srcy;
    +   }
    +
    +   result = d2_setblitsrc(handle, fb_ptr_blit, fb_pitch_blit, (d2_s32)fb_width, (d2_s32)fb_height, (d2_u32)fb_format);
    +   if (D2_OK != result)
    +   {
    +      return result;
    +   }
    +
    +   /* since we now read the framebuffer as texture, we need to make sure everything has been flushed first */
    +   (void)d2_insertwaitfulldlist_intern(handle);
    +
    +   /* worst case: horizontal offset, destination region right of source region, overlap */
    +   if ((dsty == srcy) && (dstx > srcx) && (dstx < (srcx+width)))
    +   {
    +      /* calculate stripe size */
    +      d2_blitpos offset = (d2_blitpos)(dstx-srcx);
    +      d2_u16 strwidth   = offset;
    +      d2_blitpos strx   = (d2_blitpos)(srcx+width);  /* start on the right side */
    +      
    +      do
    +      {
    +         /* advance to next stripe: last columns need a slimmer stripe */
    +         if (((d2_s32)strx-(d2_s32)strwidth) < (d2_s32)srcx)
    +         {
    +            strwidth = (d2_u16)(strx-srcx);
    +         }
    +         strx = (d2_blitpos)(strx-strwidth);
    +         result = d2_blitcopy(handle, (d2_s32)strwidth,            (d2_s32)height,            strx,                           srcy_blit,
    +                                      (d2_width)D2_FIX4(strwidth), (d2_width)D2_FIX4(height), (d2_point)D2_FIX4(strx+offset), (d2_point)D2_FIX4(srcy), flags);
    +         if (D2_OK != result)
    +         {
    +            return result;
    +         }
    +      } while (strx > srcx);
    +      return result;
    +   }
    +
    +   /* vertical offset with destination region AFTER source region and overlap: vertical flip in source and destination */
    +   if ( (dsty > srcy)
    +        && (dsty < (srcy+height))
    +        && ((dstx+width) > srcx) && (dstx < (srcx+width)) )
    +   {
    +      /* go to start of last line */
    +      d2_s32 fb_ptr_offset = (d2_s32)(fb_height-1)*fb_pitch*(d2_s32)fb_bpp;
    +      D2_DEV(handle)->framebuffer = (void*)( ((d2_u8*)fb_ptr) + fb_ptr_offset );
    +      D2_DEV(handle)->pitch       = -fb_pitch;
    +      dsty = (d2_blitpos)(fb_height-height-dsty);
    +      clip_ymax = D2_DEV(handle)->clipymax; 
    +      clip_ymin = D2_DEV(handle)->clipymin;
    +      D2_DEV(handle)->clipymax = (d2_point) ((d2_s16)(D2_FIX4(fb_height-1)) - clip_ymin);  // MHO: once the framebuffer is mirrored temporarily, any coordinates 
    +      D2_DEV(handle)->clipymin = (d2_point) ((d2_s16)(D2_FIX4(fb_height-1)) - clip_ymax);  // MHO: ..of significance in that time, need to be mirrored internally, too
    +      flags ^= d2_bf_mirrorv;
    +      flipped = 1;
    +   }
    +
    +   result = d2_blitcopy(handle, (d2_s32)width,            (d2_s32)height,            srcx,                    srcy_blit,
    +                                (d2_width)D2_FIX4(width), (d2_width)D2_FIX4(height), (d2_point)D2_FIX4(dstx), (d2_point)D2_FIX4(dsty), flags);
    +
    +   if (1 == flipped)
    +   {
    +      /* restore framebuffer settings */
    +      D2_DEV(handle)->framebuffer = fb_ptr;
    +      D2_DEV(handle)->pitch       = fb_pitch;
    +      D2_DEV(handle)->clipymax = clip_ymax;   // MHO: undo the mirroring of the clip rect
    +      D2_DEV(handle)->clipymin = clip_ymin;  
    +   }
    +
    +   return result;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_rendercircle_no_hilimiterprecision
    + * Enable or disable the high limiter precision feature of the latest 
    + * D/AVE 2D renderer for drawing blurred circles with higher image quality. 
    + * Note: This function can be used to de-activate the feature for 
    + * compatibility reasons (clear D2FB_HILIMITERPRECISION bit in HW revision)!
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   flag - 0 will activate the high limiter precision if possible,
    + *          1 will deactivate the feature even on newer version of D/AVE 2D.
    + *
    + * */
    +void d2_rendercircle_no_hilimiterprecision( d2_device *handle, d2_u32 flag )
    +{
    +   if(0 == flag)
    +   {
    +      /* set the hilimiterprecision bit if possible to support this feature from now on */
    +      if(0 != D2_DEV(handle)->hilimiterprecision_supported)
    +      {
    +         D2_DEV(handle)->hwrevision |= D2FB_HILIMITERPRECISION;
    +      }
    +   }
    +   else
    +   {
    +      /* clear the hilimiterprecision bit to not support this feature from now on */
    +      D2_DEV(handle)->hwrevision &= ~D2FB_HILIMITERPRECISION;
    +   }
    +}
    diff --git a/src/drivers/dave2d/src/dave_viewport.c b/src/drivers/dave2d/src/dave_viewport.c
    new file mode 100644
    index 000000000..33e97de4e
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_viewport.c
    @@ -0,0 +1,372 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_viewport.c (%version: 21 %)
    + *          created Wed Jan 12 16:11:17 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Fri Jan 12 14:15:14 2007 %  (%derived_by:  hh04046 %)
    + *
    + * Changes:
    + *  2007-08-31 ASc  removed tabs, changed C++ to C comments, added
    + *                   descriptions for d2_getcliprect and d2_getframebuffer
    + *  2008-07-17 MRe  added RGBA formats
    + *  2009-10-29 CSe  Allow cliprect of width or height 1.
    + *  2011-09-05 MRe  removed check of fb format change; check now done at render start
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * Title: Viewport Functions
    + * Framebuffer and view specific functions.
    + *
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_viewport.h"
    +#include "dave_dlist.h"
    +
    +/*--------------------------------------------------------------------------
    + * Group: Clipping
    + * */
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_cliprect
    + * Specify the clipping rectangle.
    + *
    + * No pixels outside the clipping rectangle are touched (rendered or read).
    + * The clipping borders are specified as integer positions (in contrast to
    + * rendering where subpixel positions are supported).
    + *
    + * The driver checks whether the specified rectangle fits within the framebuffer
    + * memory (by checking the dimensions given with <d2_framebuffer>).
    + * Cliprects will be automatically adjusted to fit inside the framebuffer region.
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   xmin - integer pixel position of left border (inclusive)
    + *   ymin - integer pixel position of top border (inclusive)
    + *   xmax - integer pixel position of right border (inclusive)
    + *   ymax - integer pixel position of bottom border (inclusive)
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_cliprect( d2_device *handle, d2_border xmin, d2_border ymin, d2_border xmax, d2_border ymax )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );        /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( xmax >= xmin, D2_INVALIDWIDTH );   /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ymax >= ymin, D2_INVALIDHEIGHT );  /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* restrict cliprect to framebuffer */
    +   if(xmin < 0)
    +   {
    +      xmin = 0;
    +   }
    +
    +   if(ymin < 0)
    +   {
    +      ymin = 0;
    +   }
    +
    +   if(xmax >= (d2_border)D2_DEV(handle)->fbwidth)
    +   {
    +      xmax = (d2_border) ( D2_DEV(handle)->fbwidth - 1 );
    +   }
    +
    +   if(ymax >= (d2_border)D2_DEV(handle)->fbheight)
    +   {
    +      ymax = (d2_border) ( D2_DEV(handle)->fbheight - 1 );
    +   }
    +
    +   if(xmax < 0)
    +   {
    +      xmax = 0;
    +   }
    +
    +   if(ymax < 0)
    +   {
    +      ymax = 0;
    +   }
    +
    +   if(xmin >= (d2_border)D2_DEV(handle)->fbwidth)
    +   {
    +      xmin = (d2_border) ( D2_DEV(handle)->fbwidth - 1 );
    +   }
    +
    +   if(ymin >= (d2_border)D2_DEV(handle)->fbheight)
    +   {
    +      ymin = (d2_border) ( D2_DEV(handle)->fbheight - 1 );
    +   }
    +
    +   /* store boundary */
    +   D2_DEV(handle)->clipxmin = (d2_point) D2_FIX4( xmin );    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   D2_DEV(handle)->clipymin = (d2_point) D2_FIX4( ymin );    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   D2_DEV(handle)->clipxmax = (d2_point) D2_FIX4( xmax );    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +   D2_DEV(handle)->clipymax = (d2_point) D2_FIX4( ymax );    /* PRQA S 4131 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_LEFT $*/
    +
    +   D2_RETOK(handle);
    +}
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getcliprect
    + * Get the clipping rectangle.
    + *
    + * No pixels outside the clipping rectangle are touched (rendered or read).
    + * The clipping borders are specified as integer positions (in contrast to
    + * rendering where subpixel positions are supported).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   xmin - pointer to an integer that receives pixel position of left border
    + *   ymin - pointer to an integer that receives pixel position of top border
    + *   xmax - pointer to an integer that receives pixel position of right border
    + *   ymax - pointer to an integer that receives pixel position of bottom border
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_getcliprect( d2_device *handle, d2_border *xmin, d2_border *ymin, d2_border *xmax, d2_border *ymax )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(0 != xmin)
    +   {
    +      *xmin = D2_INT4( D2_DEV(handle)->clipxmin );    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   if(0 != ymin)
    +   {
    +      *ymin = D2_INT4( D2_DEV(handle)->clipymin );    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   if(0 != xmax)
    +   {
    +      *xmax = D2_INT4( D2_DEV(handle)->clipxmax );    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   if(0 != ymax)
    +   {
    +      *ymax = D2_INT4( D2_DEV(handle)->clipymax );    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   }
    +
    +   D2_RETOK( handle );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * Group: Framebuffer management
    + * */
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_framebuffer
    + * Specify the rendering target.
    + *
    + * Use this function to define the framebuffer's memory area and layout.
    + * All subsequent <Rendering Functions> will work on the given buffer.
    + *
    + * Setting a new framebuffer will automatically adjust the cliprect to
    + * the maximum range [0 .. width-1] and [0 .. height-1]
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ptr    - address of the top left pixel (coordinate 0,0)
    + *   pitch  - number of pixels (*not bytes*) per scanline
    + *   width  - width of framebuffer in pixels (equal or less than pitch)
    + *   height - height of framebuffer in pixels
    + *   format - pixel encoding type (framebuffer format)
    + *
    + * framebuffer formats:
    + *
    + *  d2_mode_alpha8   - monochrome 8bit per pixel
    + *  d2_mode_rgb565   - colored 16bit per pixel
    + *  d2_mode_argb8888 - colored 32bit per pixel
    + *  d2_mode_argb4444 - colored 16bit per pixel
    + *  d2_mode_rgba8888 - colored 32bit per pixel
    + *  d2_mode_rgba4444 - colored 16bit per pixel
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + *
    + * note:
    + *   this function has no effect on what memory area is currently visible
    + * */
    +d2_s32 d2_framebuffer( d2_device *handle, void *ptr, d2_s32 pitch, d2_u32 width, d2_u32 height, d2_s32 format )
    +{
    +   d2_contextdata *ctx;
    +
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );       /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( ptr, D2_NOVIDEOMEM );             /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( width  > 1, D2_VALUETOOSMALL );   /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +   D2_CHECKERR( height > 1, D2_VALUETOOSMALL );   /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   /* use new parameters */
    +   D2_DEV(handle)->framebuffer = ptr;
    +   D2_DEV(handle)->fbformat    = format;
    +   D2_DEV(handle)->pitch       = pitch;
    +   D2_DEV(handle)->fbwidth     = width;
    +   D2_DEV(handle)->fbheight    = height;
    +
    +   /* calc bpp and mask */
    +   switch (format)
    +   {
    +      case d2_mode_alpha8:
    +         D2_DEV(handle)->fbstylemask = 0;
    +         D2_DEV(handle)->bpp         = 1;
    +         break;
    +
    +      case d2_mode_rgb565:
    +         D2_DEV(handle)->fbstylemask = D2C_WRITEFORMAT1;
    +         D2_DEV(handle)->bpp         = 2;
    +         break;
    +
    +      case d2_mode_argb8888:
    +      case d2_mode_rgb888:
    +         D2_DEV(handle)->fbstylemask = D2C_WRITEFORMAT2;
    +         D2_DEV(handle)->bpp         = 4;
    +         break;
    +
    +      case d2_mode_rgba8888:
    +         D2_DEV(handle)->fbstylemask = D2C_WRITEFORMAT3 | D2C_WRITEFORMAT2;
    +         D2_DEV(handle)->bpp         = 4;
    +         break;
    +
    +      case d2_mode_argb4444:
    +      case d2_mode_rgb444:
    +         D2_DEV(handle)->fbstylemask = D2C_WRITEFORMAT2 | D2C_WRITEFORMAT1;
    +         D2_DEV(handle)->bpp         = 2;
    +         break;
    +
    +      case d2_mode_rgba4444:
    +         D2_DEV(handle)->fbstylemask = D2C_WRITEFORMAT3 | D2C_WRITEFORMAT2 | D2C_WRITEFORMAT1;
    +         D2_DEV(handle)->bpp         = 2;
    +         break;
    +
    +      default:
    +         break;
    +   }
    +
    +   /* update context modeflags */
    +   ctx = D2_DEV(handle)->ctxchain;
    +
    +   while(NULL != ctx)
    +   {
    +      ctx->cr2mask = 
    +         D2_DEV(handle)->fbstylemask | 
    +         ctx->blendmask              | 
    +         ctx->tbstylemask            | 
    +         ctx->alphablendmask         | 
    +         ctx->rlemask                | 
    +         ctx->clutmask               | 
    +         ctx->colkeymask             ;
    +
    +      ctx = ctx->next;
    +   }
    +
    +   /* reset cliprect */
    +   (void)d2_cliprect( handle, 0, 0, (d2_border) (width-1), (d2_border) (height-1) );
    +
    +   D2_RETOK(handle);
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * function: d2_getframebuffer
    + * Get information about the rendering target
    + *
    + * Use this function to get information about the framebuffer's
    + * memory area and layout (framebuffer pointer, pitch, size and format).
    + *
    + * parameters:
    + *   handle - device pointer (see: <d2_opendevice>)
    + *   ptr    - pointer to receive address of the top left pixel (coordinate 0,0)
    + *   pitch  - pointer to receive number of pixels (*not bytes*) per scanline
    + *   width  - pointer to receive width of framebuffer in pixels (equal or less than pitch)
    + *   height - pointer to receive height of framebuffer in pixels
    + *   format - pointer to receive pixel encoding type (framebuffer format)
    + *
    + * framebuffer formats:
    + *
    + *  d2_mode_alpha8   - monochrome 8bit per pixel
    + *  d2_mode_rgb565   - colored 16bit per pixel
    + *  d2_mode_argb8888 - colored 32bit per pixel
    + *  d2_mode_argb4444 - colored 16bit per pixel
    + *
    + * returns:
    + *   errorcode (D2_OK if successfull) see list of <Errorcodes> for details
    + * */
    +d2_s32 d2_getframebuffer( d2_device *handle, void** ptr, d2_s32 * pitch, d2_u32 * width, d2_u32 * height, d2_s32 * format )
    +{
    +   D2_VALIDATE( handle, D2_INVALIDDEVICE );   /* PRQA S 4130, 3112, 3453 */ /* $Misra: #DEBUG_MACRO $*/
    +
    +   if(NULL != ptr)
    +   {
    +      *ptr    = D2_DEV(handle)->framebuffer;
    +   }
    +
    +   if(0 != pitch)
    +   {
    +      *pitch  = D2_DEV(handle)->pitch;
    +   }
    +
    +   if(0 != width)
    +   {
    +      *width  = D2_DEV(handle)->fbwidth;
    +   }
    +
    +   if(0 != height)
    +   {
    +      *height = D2_DEV(handle)->fbheight;
    +   }
    +
    +   if(0 != format)
    +   {
    +      *format = D2_DEV(handle)->fbformat;
    +   }
    +
    +   D2_RETOK( handle );
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + * */
    +d2_s32 d2_clipbbox_intern( const d2_devicedata *handle, d2_bbox *box )
    +{
    +   /* trivial reject */
    +   if( (box->xmin > handle->clipxmax) ||
    +       (box->ymin > handle->clipymax) ||
    +       (box->xmax < handle->clipxmin) ||
    +       (box->ymax < handle->clipymin)
    +       )
    +   {
    +      return 0;
    +   } 
    +   else
    +   {
    +      /* box clipping */
    +      if(box->xmin < handle->clipxmin)
    +      {
    +         box->xmin = handle->clipxmin;
    +      }
    +
    +      if(box->ymin < handle->clipymin)
    +      {
    +         box->ymin = handle->clipymin;
    +      }
    +
    +      if(box->xmax > handle->clipxmax)
    +      {
    +         box->xmax = handle->clipxmax;
    +      }
    +
    +      if(box->ymax > handle->clipymax)
    +      {
    +         box->ymax = handle->clipymax;
    +      }
    +
    +      return 1;
    +   }
    +}
    +
    diff --git a/src/drivers/dave2d/src/dave_wedge.c b/src/drivers/dave2d/src/dave_wedge.c
    new file mode 100644
    index 000000000..c734e8ef1
    --- /dev/null
    +++ b/src/drivers/dave2d/src/dave_wedge.c
    @@ -0,0 +1,362 @@
    +/*--------------------------------------------------------------------------
    + * Project: D/AVE
    + * File:    dave_wedge.c (%version: 1 %)
    + *          created Mon Feb 14 14:46:39 2005 by hh04027
    + *
    + * Description:
    + *  %date_modified: Mon Feb 14 14:46:40 2005 %  (%derived_by:  hh04027 %)
    + *
    + * Changes:
    + *  2008-01-14 ASc  changed comments from C++ to C, removed tabs
    + *  2009-03-31 MRe  improved bbox for convex wedges (less enumeration; fix artefact for very small angles)
    + *  2010-09-22 MRe  don't render convex wedges with angle of 0
    + *  2012-09-25 BSp  MISRA cleanup
    + *-------------------------------------------------------------------------- */
    +
    +#include "dave_driver.h"
    +#include "dave_intern.h"
    +#include "dave_viewport.h"
    +#include "dave_render.h"
    +#include "dave_circle.h"
    +#include "dave_wedge.h"
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_u32 count_leading_zeroes16(d2_u16 v); /* MISRA */
    +static d2_s32 is_same_direction(d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2); /* MISRA */
    +static d2_s32 d2_renderwedge_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags ); /* MISRA */
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_u32 count_leading_zeroes16(d2_u16 v)
    +{
    +   d2_u32 c = 0;
    +
    +   if(0 == v)
    +   {
    +      c = 16;
    +   }
    +   else
    +   {
    +      if(0 == (v & 0xff00))
    +      {
    +         c = 8;
    +      }
    +      else
    +      {
    +         v >>= 8;
    +      }
    +        
    +      if(0 == (v & 0xf0u))
    +      {
    +         c += 4u;
    +      }
    +      else
    +      {
    +         v >>= 4;
    +      }
    +
    +      if(0 == (v & 0xcu))
    +      {
    +         c += 2u;
    +      }
    +      else
    +      {
    +         v >>= 2;
    +      }
    +
    +      c += (0 != (v & 0x2u)) ? 0u : 1u;
    +   }
    +
    +   return c;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_s32 is_same_direction(d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2)
    +{
    +   /* arguments are 16.16 fixedpoint */
    +   d2_u32 leading_zeroes;
    +   d2_s32 scalarprod;
    +
    +   /* check 180 deg */
    +   if(
    +      ((nx1 >= 0) && (nx2 >= 0)) || ((nx1 < 0) && (nx2 < 0)) || 
    +      ((ny1 >= 0) && (ny2 >= 0)) || ((ny1 < 0) && (ny2 < 0))
    +      )
    +   {
    +      return 0;
    +   }
    +
    +   /* reduce both vector components to less or equal 1 */
    +   leading_zeroes = count_leading_zeroes16((nx1 > 0) ? (d2_u16)(nx1 >> 16) : (d2_u16)((-nx1) >> 16));  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 3759 */ /* $Misra: #MISRA_BUG_IMPLICIT_CONVERSION_S32_TO_U16 $*/
    +   nx1 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   ny1 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   leading_zeroes = count_leading_zeroes16((ny1 > 0) ? (d2_u16)(ny1 >> 16) : (d2_u16)((-ny1) >> 16));  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 3759 */ /* $Misra: #MISRA_BUG_IMPLICIT_CONVERSION_S32_TO_U16 $*/
    +   nx1 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   ny1 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   leading_zeroes = count_leading_zeroes16((nx2 > 0) ? (d2_u16)(nx2 >> 16) : (d2_u16)((-nx2) >> 16));  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 3759 */ /* $Misra: #MISRA_BUG_IMPLICIT_CONVERSION_S32_TO_U16 $*/
    +   nx2 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   ny2 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   leading_zeroes = count_leading_zeroes16((ny2 > 0) ? (d2_u16)(ny2 >> 16) : (d2_u16)((-ny2) >> 16));  /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/ /* PRQA S 3759 */ /* $Misra: #MISRA_BUG_IMPLICIT_CONVERSION_S32_TO_U16 $*/
    +   nx2 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   ny2 >>= 16u - leading_zeroes;    /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +   /* if scalar product of v1 * (v2+90�) is zero then both vectors have same direction */
    +
    +   nx1 >>= 1; ny1 >>= 1; nx2 >>= 1; ny2 >>= 1;      /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +   scalarprod = (nx1 * ny2) + (ny1 * -nx2);
    +   scalarprod = (scalarprod < 0) ? -scalarprod : scalarprod;
    +
    +   if(scalarprod < D2_FIX16(1)) /* some epsilon */
    +   {
    +      return 1;
    +   }
    +   else
    +   {
    +      return 0;
    +   }
    +
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +static d2_s32 d2_renderwedge_intern( d2_devicedata *handle, d2_contextdata *ctx, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags )
    +{
    +   d2_contextdata *oldctx;
    +   d2_border xminori, yminori, xmaxori, ymaxori;
    +   d2_border bxmin, bymin, bxmax, bymax;
    +   d2_u32 flags1 = 0;
    +   d2_u32 flags2 = 0;
    +
    +   if(0 == (flags & d2_wf_concave))
    +   {
    +      if(0 != is_same_direction(nx1, ny1, nx2, ny2))
    +      {
    +         return 1;
    +      }
    +   }
    +
    +   /*DEBUG*/
    +   /* dummy code */
    +   oldctx = handle->ctxselected;
    +   handle->ctxselected = ctx;
    +   
    +   (void)d2_getcliprect(handle, &xminori, &yminori, &xmaxori, &ymaxori);
    +
    +   if(ny1 >= 0)
    +   {
    +      if(nx1 < 0)
    +         flags1 |= d2_grad_rightedge;
    +   }
    +   else
    +   {
    +      if(nx1 <= 0)
    +         flags1 |= d2_grad_rightedge;
    +   }
    +
    +   if(ny2 >= 0)
    +   {
    +      if(nx2 < 0)
    +         flags2 |= d2_grad_rightedge;
    +   }
    +   else
    +   {
    +      if(nx2 <= 0)
    +         flags2 |= d2_grad_rightedge;
    +   }
    +
    +   if(0 != (flags & d2_wf_concave))
    +   {
    +      /* For the concave case, we need a one pixel offset if the gradients'
    +       * gap angle <= 90 degrees. Otherwise, both clipgradients will only
    +       * partially cover some of the pixels in the wedge, which will lead to
    +       * a ripped wedge.
    +       */
    +
    +      /* calculate dot product but discard one bit precision for the sake of simplicity */
    +      d2_s32 dot = (((nx1>>1)*(nx2>>1))>>15) + (((ny1>>1)*(ny2>>1))>>15);
    +
    +      if((dot <= 0) && (0 == (flags & d2_edge0_shared)))
    +      {
    +         flags1 |= d2_grad_offset;
    +      }
    +
    +      if((dot <= 0) && (0 == (flags & d2_edge1_shared)))
    +      {
    +         flags2 |= d2_grad_offset;
    +      }
    +
    +      flags1 |= d2_grad_concave;
    +      flags2 |= d2_grad_concave;
    +   }
    +
    +   (void)d2_setclipgradient( handle, 0, x, y, nx1, ny1, 
    +                             ((0 != (flags & d2_edge0_shared)) ? d2_grad_threshold : 0) |
    +                             flags1                                                     );
    +
    +   (void)d2_setclipgradient( handle, 1, x, y, nx2, ny2,
    +                             ((0 != (flags & d2_edge1_shared)) ? d2_grad_threshold : 0) |
    +                             flags2                                                     );
    +
    +   /* remove quadrants from clipbox if possible: */
    +   if(0 == (flags & d2_wf_concave))
    +   { 
    +      (void)d2_getcliprect(handle, &bxmin, &bymin, &bxmax, &bymax);
    +
    +      if( ((nx1 + nx2) > 0) && 
    +          (
    +             ((ny2 >= 0) && (ny1 <= 0)) || 
    +             ((ny1 >= 0) && (ny2 <= 0))
    +           )
    +          ) /* right half */
    +      {
    +         d2_border val = (d2_border)(D2_INT4(x - (D2_FIX4(1) >> 1))); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +         if(bxmin < val)
    +         {
    +            bxmin = val;
    +         }
    +      }
    +
    +      if( ((nx1 + nx2) < 0 ) &&
    +          (
    +             ((ny2 >= 0) && (ny1 <= 0)) ||
    +             ((ny1 >= 0) && (ny2 <= 0)) 
    +           )
    +          ) /* left half */
    +      {
    +         d2_border val = (d2_border)(D2_INT4(x + (D2_FIX4(1) >> 1))); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +         if(bxmax > val)
    +         {
    +            bxmax = val;
    +         }
    +      }
    +
    +      if( ((ny1 + ny2) < 0) &&
    +          (
    +             (
    +                ((nx2 >= 0) && (nx1 <= 0)) ||
    +                ((nx1 >= 0) && (nx2 <= 0))
    +              )
    +           )
    +          ) /* upper half */
    +      {
    +         d2_border val = (d2_border)(D2_INT4(y + (D2_FIX4(1) >> 1))); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +         if(bymax > val)
    +         {
    +            bymax = val;
    +         }
    +      }
    +
    +      if( ((ny1 + ny2) > 0) &&
    +          (
    +             ((nx2 >= 0) && (nx1 <= 0)) ||
    +             ((nx1 >= 0) && (nx2 <= 0))
    +           )
    +          ) /* lower half */
    +      {
    +         d2_border val = (d2_border)(D2_INT4(y - (D2_FIX4(1) >> 1))); /* PRQA S 0502 */ /* $Misra: #PERF_ARITHMETIC_SHIFT_RIGHT $*/
    +
    +         if(bymin < val)
    +         {
    +            bymin = val;
    +         }
    +      }
    +          
    +      (void)d2_cliprect(handle, bxmin, bymin, bxmax, bymax);
    +   }
    +
    +   (void)d2_rendercircle_intern( handle, ctx, x, y, r, w );
    +
    +   /* restore */
    +   (void)d2_setclipgradient( handle, 0, x, y, 0, 0, 0 );
    +   (void)d2_setclipgradient( handle, 1, x, y, 0, 0, 0 );
    +   (void)d2_cliprect(handle, xminori, yminori, xmaxori, ymaxori);
    +   handle->ctxselected = oldctx;
    +
    +   return 1;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderwedge_solid( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags )
    +{
    +   (void)d2_renderwedge_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x, y, r, w, nx1,ny1, nx2,ny2, flags );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderwedge_outline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags )
    +{
    +   (void)d2_renderwedge_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x, y, r, (d2_width)(w + (D2_DEV(handle)->outlinewidth * 2)) , nx1, ny1, nx2, ny2, flags );
    +
    +/*   d2_renderline_intern_split( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x1,y1, x2,y2, w + D2_DEV(handle)->outlinewidth * 2, flags, edge_buffer, &edge_bbox, NULL ); */
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderwedge_shadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags )
    +{
    +   d2_point sx, sy;
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   (void)d2_renderwedge_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x + sx), (d2_point)(y + sy), r, w, nx1, ny1, nx2, ny2, flags );
    +
    +   return D2_OK;
    +}
    +
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderwedge_solidoutline( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags )
    +{
    +   /* render outline */
    +   (void)d2_renderwedge_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, x, y, r, (d2_width)(w + (D2_DEV(handle)->outlinewidth * 2)), nx1, ny1, nx2, ny2, flags );
    +
    +   /* render solid */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderwedge_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x, y, r, w, nx1, ny1, nx2, ny2, flags );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}
    +
    +/*--------------------------------------------------------------------------
    + *
    + * */
    +d2_s32 d2_renderwedge_solidshadow( d2_device *handle, d2_point x, d2_point y, d2_width r, d2_width w, d2_s32 nx1, d2_s32 ny1, d2_s32 nx2, d2_s32 ny2, d2_u32 flags )
    +{
    +   d2_point sx,sy;
    +   sx = D2_DEV(handle)->soffx;
    +   sy = D2_DEV(handle)->soffy;
    +
    +   /* render shadow */
    +   (void)d2_renderwedge_intern( D2_DEV(handle), D2_DEV(handle)->ctxoutline, (d2_point)(x + sx), (d2_point)(y + sy), r, w, nx1, ny1, nx2, ny2, flags );
    +
    +   /* render solid */
    +   d2_rendertolayer_intern( handle );
    +   (void)d2_renderwedge_intern( D2_DEV(handle), D2_DEV(handle)->ctxsolid, x, y, r, w, nx1, ny1, nx2, ny2, flags );
    +   d2_rendertobase_intern( handle );
    +
    +   return D2_OK;
    +}