[commit] r2355 - add generated B3D and Rome plugins

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[commit] r2355 - add generated B3D and Rome plugins

commits-3
 
Author: piumarta
Date: 2011-01-23 01:41:21 -0800 (Sun, 23 Jan 2011)
New Revision: 2355

Added:
   trunk/platforms/unix/src/plugins/RomePlugin/
   trunk/platforms/unix/src/plugins/RomePlugin/RomePlugin.c
   trunk/platforms/unix/src/plugins/Squeak3D/
   trunk/platforms/unix/src/plugins/Squeak3D/Squeak3D.c
Modified:
   trunk/platforms/unix/src/plugins.ext
   trunk/platforms/unix/src/plugins/B3DAcceleratorPlugin/B3DAcceleratorPlugin.c
   trunk/platforms/unix/src/vm/intplugins/ADPCMCodecPlugin/ADPCMCodecPlugin.c
   trunk/platforms/unix/src/vm/intplugins/SoundGenerationPlugin/SoundGenerationPlugin.c
   trunk/platforms/unix/src/vm/sqNamedPrims.h
Log:
add generated B3D and Rome plugins

Modified: trunk/platforms/unix/src/plugins/B3DAcceleratorPlugin/B3DAcceleratorPlugin.c
===================================================================
--- trunk/platforms/unix/src/plugins/B3DAcceleratorPlugin/B3DAcceleratorPlugin.c 2011-01-23 07:34:41 UTC (rev 2354)
+++ trunk/platforms/unix/src/plugins/B3DAcceleratorPlugin/B3DAcceleratorPlugin.c 2011-01-23 09:41:21 UTC (rev 2355)
@@ -1,4 +1,4 @@
-/* Automatically generated from Squeak on 23 January 2011 3:55:50 pm
+/* Automatically generated from Squeak on 23 January 2011 6:31:52 pm
    by VMMaker 4.4.7
  */
 
Added: trunk/platforms/unix/src/plugins/RomePlugin/RomePlugin.c
===================================================================
--- trunk/platforms/unix/src/plugins/RomePlugin/RomePlugin.c                        (rev 0)
+++ trunk/platforms/unix/src/plugins/RomePlugin/RomePlugin.c 2011-01-23 09:41:21 UTC (rev 2355)
@@ -0,0 +1,3601 @@
+/* Automatically generated from Squeak on 23 January 2011 6:31:55 pm
+   by VMMaker 4.4.7
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+/* Default EXPORT macro that does nothing (see comment in sq.h): */
+#define EXPORT(returnType) returnType
+
+/* Do not include the entire sq.h file but just those parts needed. */
+/*  The virtual machine proxy definition */
+#include "sqVirtualMachine.h"
+/* Configuration options */
+#include "sqConfig.h"
+/* Platform specific definitions */
+#include "sqPlatformSpecific.h"
+
+#define true 1
+#define false 0
+#define null 0  /* using 'null' because nil is predefined in Think C */
+#ifdef SQUEAK_BUILTIN_PLUGIN
+#undef EXPORT
+// was #undef EXPORT(returnType) but screws NorCroft cc
+#define EXPORT(returnType) static returnType
+#endif
+#include <cairo.h>
+#include <cairo-ft.h>
+#include <pango/pangocairo.h>
+#include "SurfacePlugin.h"
+#define NUM_OF(array) (sizeof (array) / sizeof *(array))
+#define lastIndex(array) (NUM_OF(array) - 1)
+#define degrees(a) (a * 3.141592653589793 / 180.0)
+
+#define log(msg) fprintf(stderr, "Squeak-Rome: " msg "\n")
+#define logwith(msg, a) fprintf(stderr, "Squeak-Rome: " msg "\n", a)
+#define logwithwith(msg, a, b) fprintf(stderr, "Squeak-Rome: " msg "\n", a, b)
+#define logwithwithwith(msg, a, b, c) fprintf(stderr, "Squeak-Rome: " msg "\n", a, b, c)
+#define logwithwithwithwith(msg, a, b, c, d) fprintf(stderr, "Squeak-Rome: " msg "\n", a, b, c, d)
+#define logwithwithwithwithwith(msg, a, b, c, d, e) fprintf(stderr, "Squeak-Rome: " msg "\n", a, b, c, d, e)
+
+#define primFail interpreterProxy->primitiveFail()
+#define fail(msg) log(msg "!"); primFail
+#define failwith(msg, a) logwith(msg "!", a); primFail
+#define failwithwith(msg, a, b) logwithwith(msg "!", a, b); primFail
+
+
+#include "sqMemoryAccess.h"
+
+
+/*** Constants ***/
+#define CairoExtendRepeat CAIRO_EXTEND_REPEAT
+#define CairoOperatorSource CAIRO_OPERATOR_SOURCE
+#define CanvasFlagFill 256
+#define CanvasFlagStroke 255
+#define CanvasFlagsIndex 2
+#define CanvasHandleIndex 0
+#define CanvasInstSize 8
+#define CanvasStrokeColorIndex 3
+#define CanvasTargetIndex 1
+#define FormBitsIndex 0
+#define FormDepthIndex 3
+#define FormHeightIndex 2
+#define FormInstSize 5
+#define FormWidthIndex 1
+#define PluginVersion 39
+#define TextLineBottomIndex 3
+#define TextLineEndIndex 5
+#define TextLineInternalSpaceIndex 6
+#define TextLineLeftIndex 0
+#define TextLinePaddingWidthIndex 7
+#define TextLineRightIndex 1
+#define TextLineStartIndex 4
+#define TextLineTopIndex 2
+
+/*** Function Prototypes ***/
+static sqInt addAlignmentinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList);
+static sqInt addColorinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList);
+static void addColorStopTooffsetrgbalpha(cairo_pattern_t*pattern, sqInt intOffset, sqInt rgb, sqInt alpha);
+static sqInt addDefaultInto(PangoAttrList *pangoAttrList);
+static sqInt addEmphasisinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList);
+static sqInt addFontinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList);
+static sqInt addLanguageinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList);
+static sqInt addSelectionAtpixelwith(PangoRectangle *rect, unsigned int c, cairo_t*context);
+static sqInt addSelectionFromtopixelinto(sqInt start, sqInt end, unsigned int c, PangoAttrList *pangoAttrList);
+static cairo_t* contextFrom(sqInt canvasOop);
+static sqInt createContextFor(sqInt canvasOop);
+static sqInt createSurfaceFor(sqInt formOop);
+static sqInt destroyContextFor(sqInt canvasOop);
+static sqInt destroySurface(sqInt surfaceID);
+static void fillOrStrokefrom(cairo_t*context, sqInt canvasOop);
+static cairo_surface_t* findSurface(sqInt surfaceID);
+static VirtualMachine * getInterpreter(void);
+#pragma export on
+EXPORT(const char*) getModuleName(void);
+#pragma export off
+static sqInt getSurfaceFormatgetWgetHgetDgetMsb(cairo_surface_t *surfaceHandle, int*wReturn, int*hReturn, int*dReturn, int*mReturn);
+static sqInt halt(void);
+#pragma export on
+EXPORT(sqInt) initialiseModule(void);
+#pragma export off
+static sqInt leadingCharOf(unsigned int value);
+static sqInt loadSurfacePlugin(void);
+static unsigned char* lockSurfacegetPitchxywh(cairo_surface_t*surfaceHandle, int*pitchReturn, sqInt x, sqInt y, sqInt w, sqInt h);
+#pragma export on
+EXPORT(sqInt) moduleUnloaded(char *aModuleName);
+#pragma export off
+static sqInt msg(char *s);
+static void polyPathfrom(cairo_t*context, sqInt pointsOop);
+#pragma export on
+EXPORT(sqInt) primitivePangoBlockAtIndex(void);
+EXPORT(sqInt) primitiveClear(void);
+EXPORT(sqInt) primitiveClipRectangleLeftRightTopBottom(void);
+EXPORT(sqInt) primitiveClose(void);
+EXPORT(sqInt) primitivePangoComposeString(void);
+EXPORT(sqInt) primitivePangoComposeString2(void);
+EXPORT(sqInt) primitiveCreateFormHandle(void);
+EXPORT(sqInt) primitiveDestroyFormHandle(void);
+EXPORT(sqInt) primitiveDrawArcRadiusXYFromTo(void);
+EXPORT(sqInt) primitiveDrawCurveFromXYviaXYandXYtoXY(void);
+EXPORT(sqInt) primitiveDrawCurveFromXYviaXYtoXY(void);
+EXPORT(sqInt) primitiveDrawGeneralBezierShape(void);
+EXPORT(sqInt) primitiveDrawImageSrcLRTBDestLRTB(void);
+EXPORT(sqInt) primitiveDrawLineFromXYtoXY(void);
+EXPORT(sqInt) primitiveDrawOvalLeftRightTopBottom(void);
+EXPORT(sqInt) primitiveDrawPolygon(void);
+EXPORT(sqInt) primitiveDrawPolyline(void);
+EXPORT(sqInt) primitiveDrawRectangleLeftRightTopBottom(void);
+EXPORT(sqInt) primitiveDrawRoundRectLeftRightTopBottomRadiusCorner(void);
+EXPORT(sqInt) primitiveDrawZeroTerminatedUtf8StringXY(void);
+EXPORT(sqInt) primitiveFillBitmapOriginXYdirectionXYnormalXYRepeatImage(void);
+EXPORT(sqInt) primitiveFillColorAlpha(void);
+EXPORT(sqInt) primitiveFillLinearOriginXYdirectionXYcolorStops(void);
+EXPORT(sqInt) primitiveFillRadialOriginXYdirectionXYnormalXYcolorStops(void);
+EXPORT(sqInt) primitiveFontFace(void);
+EXPORT(sqInt) primitiveFontSize(void);
+EXPORT(sqInt) primitiveGetLineWidth(void);
+EXPORT(sqInt) primitivePangoFontDescriptionIndex(void);
+EXPORT(sqInt) primitiveGetTransform(void);
+EXPORT(sqInt) primitivePangoIndexAtPoint(void);
+EXPORT(sqInt) primitiveLanguageAttributes(void);
+EXPORT(sqInt) primitiveOpen(void);
+EXPORT(sqInt) primitivePangoIsAvailable(void);
+EXPORT(sqInt) primitivePluginVersion(void);
+EXPORT(sqInt) primitiveRestoreState(void);
+EXPORT(sqInt) primitiveRotateBy(void);
+EXPORT(sqInt) primitiveSaveState(void);
+EXPORT(sqInt) primitiveScaleBy(void);
+EXPORT(sqInt) primitiveSetLineWidth(void);
+EXPORT(sqInt) primitiveSetTransform(void);
+EXPORT(sqInt) primitivePangoShowString(void);
+EXPORT(sqInt) primitiveShowZeroTerminatedUtf8StringXY(void);
+EXPORT(sqInt) primitiveStencilImageSrcLRTBDestLRTB(void);
+EXPORT(sqInt) primitiveTransformBy(void);
+EXPORT(sqInt) primitiveTranslateBy(void);
+EXPORT(sqInt) primitiveUTF8StringWith2Indexes(void);
+EXPORT(sqInt) primitiveUTF8StringWithIndex(void);
+#pragma export off
+static sqInt putCharintoat(sqInt c, unsigned char*utf8String, sqInt utf8Index);
+static sqInt registerSurface(cairo_surface_t*surfaceHandle);
+#pragma export on
+EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+#pragma export off
+static void setSourcergbalpha(cairo_t*context, sqInt rgb, sqInt alpha);
+static sqInt showSurfacexywh(cairo_surface_t *surfaceHandle, sqInt x, sqInt y, sqInt w, sqInt h);
+#pragma export on
+EXPORT(sqInt) shutdownModule(void);
+#pragma export off
+static sqInt sqAssert(sqInt aBool);
+static sqInt sqCharCountInfromto(unsigned char* aString, sqInt from, sqInt to);
+static void strokefrom(cairo_t*context, sqInt canvasOop);
+static cairo_surface_t* surfaceFrom(sqInt formOop);
+static sqInt translateSqAttrsToPangoAttrsinto(sqInt sqAttrsArrayOop, PangoAttrList *pangoAttrList);
+static sqInt unlockSurfacexywh(cairo_surface_t*surfaceHandle, sqInt x, sqInt y, sqInt w, sqInt h);
+static sqInt unregisterSurface(sqInt surfaceID);
+static sqInt utf8CountFor(unsigned int value);
+/*** Variables ***/
+static cairo_t* contexts[64];
+static PangoFontDescription *defaultFontDescription;
+static fn_ioFindSurface findSurfaceFn;
+static PangoFontDescription *fontDescriptions[256];
+static int formatToDepth[] = {
+32, 32, 8, 1, 16};
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+extern
+#endif
+struct VirtualMachine* interpreterProxy;
+static sqInt maxSurfaceID;
+static const char *moduleName =
+#ifdef SQUEAK_BUILTIN_PLUGIN
+ "RomePlugin Aeneas.39 23 January 2011 (i)"
+#else
+ "RomePlugin Aeneas.39 23 January 2011 (e)"
+#endif
+;
+static fn_ioRegisterSurface registerSurfaceFn;
+static sqSurfaceDispatch surfaceDispatch = {
+  1,
+  0,
+  (fn_getSurfaceFormat) getSurfaceFormatgetWgetHgetDgetMsb,
+  (fn_lockSurface) lockSurfacegetPitchxywh,
+  (fn_unlockSurface) unlockSurfacexywh,
+  (fn_showSurface) showSurfacexywh
+};
+static fn_ioUnregisterSurface unregisterSurfaceFn;
+static int utf8Headers[] = {
+0, 192, 224, 240, 248, 252, 254, 255};
+
+
+static sqInt addAlignmentinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList) {
+ sqInt start;
+ sqInt alignment;
+ int pangoAlignment;
+ sqInt end;
+ sqInt *attrArray;
+
+ attrArray = interpreterProxy->firstIndexableField(attrArrayOop);
+ start = ((attrArray[1]) >> 1);
+ end = ((attrArray[2]) >> 1);
+ alignment = ((attrArray[3]) >> 1);
+ if (alignment == 0) {
+ pangoAlignment = PANGO_ALIGN_LEFT;
+ }
+ if (alignment == 1) {
+ pangoAlignment = PANGO_ALIGN_RIGHT;
+ }
+ if (alignment == 2) {
+ pangoAlignment = PANGO_ALIGN_CENTER;
+ }
+ if (alignment == 3) {
+ null;
+ }
+}
+
+static sqInt addColorinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList) {
+ sqInt start;
+ sqInt r;
+ sqInt b;
+ PangoAttribute *pangoAttr;
+ sqInt end;
+ sqInt g;
+ sqInt alpha;
+ sqInt *attrArray;
+ unsigned int c;
+
+ attrArray = interpreterProxy->firstIndexableField(attrArrayOop);
+ start = ((attrArray[1]) >> 1);
+ end = ((attrArray[2]) >> 1);
+
+ /* self log: 'color: %u' with: c. */
+
+ c = interpreterProxy->positive32BitValueOf(attrArray[3]);
+ alpha = ((usqInt) (c && 4278190080U)) >> 24;
+ r = ((usqInt) (c & 16711680)) >> 16;
+ g = ((usqInt) (c & 65280)) >> 8;
+ b = c & 255;
+ if (!(r == 0)) {
+ r = r * 257;
+ }
+ if (!(g == 0)) {
+ g = g * 257;
+ }
+ if (!(b == 0)) {
+ b = b * 257;
+ }
+ pangoAttr = pango_attr_foreground_new(r, g, b);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+}
+
+static void addColorStopTooffsetrgbalpha(cairo_pattern_t*pattern, sqInt intOffset, sqInt rgb, sqInt alpha) {
+ sqInt b;
+ sqInt r;
+ sqInt g;
+
+ r = (((usqInt) rgb) >> 20) & 1023;
+ g = (((usqInt) rgb) >> 10) & 1023;
+ b = (((usqInt) rgb) >> 0) & 1023;
+ if (alpha == 255) {
+ cairo_pattern_add_color_stop_rgb(pattern, intOffset / 65536.0, r / 1023.0, g / 1023.0, b / 1023.0);
+ } else {
+ cairo_pattern_add_color_stop_rgba(pattern, intOffset / 65536.0, r / 1023.0, g / 1023.0, b / 1023.0, alpha / 255.0);
+ }
+}
+
+static sqInt addDefaultInto(PangoAttrList *pangoAttrList) {
+ PangoAttribute *pangoAttr;
+ PangoLanguage *lang;
+
+ pangoAttr = pango_attr_foreground_new(0, 0, 1);
+ pangoAttr->start_index = 0;
+ pangoAttr->end_index = 0x7fffffff;
+ pango_attr_list_insert(pangoAttrList, pangoAttr);
+ pangoAttr = pango_attr_font_desc_new(defaultFontDescription);
+ pangoAttr->start_index = 0;
+ pangoAttr->end_index = 0x7fffffff;
+ pango_attr_list_insert(pangoAttrList, pangoAttr);
+ lang = pango_language_from_string("en-US");
+ pangoAttr = pango_attr_language_new(lang);
+ pangoAttr->start_index = 0;
+ pangoAttr->end_index = 0x7fffffff;
+ pango_attr_list_insert(pangoAttrList, pangoAttr);
+}
+
+static sqInt addEmphasisinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList) {
+ sqInt start;
+ PangoAttribute *pangoAttr;
+ sqInt end;
+ sqInt *attrArray;
+ sqInt c;
+
+ attrArray = interpreterProxy->firstIndexableField(attrArrayOop);
+ start = ((attrArray[1]) >> 1);
+ end = ((attrArray[2]) >> 1);
+ c = ((attrArray[3]) >> 1);
+ if (c & 1) {
+ pangoAttr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+ }
+ if (c & 2) {
+ pangoAttr = pango_attr_style_new(PANGO_STYLE_OBLIQUE);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+ }
+ if (c & 4) {
+ pangoAttr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+ }
+ if (c & 8) {
+ pangoAttr = pango_attr_stretch_new(PANGO_STRETCH_CONDENSED);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+ }
+ if (c & 16) {
+ pangoAttr = pango_attr_strikethrough_new(1);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+ }
+}
+
+static sqInt addFontinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList) {
+ sqInt start;
+ PangoFontDescription *desc;
+ sqInt fontDescIndex;
+ PangoAttribute *pangoAttr;
+ sqInt end;
+ sqInt *attrArray;
+
+ attrArray = interpreterProxy->firstIndexableField(attrArrayOop);
+ start = ((attrArray[1]) >> 1);
+ end = ((attrArray[2]) >> 1);
+ fontDescIndex = interpreterProxy->fetchIntegerofObject(5, attrArray[4]);
+ if (fontDescIndex < 0) {
+ return null;
+ }
+ if (fontDescIndex > 255) {
+ return null;
+ }
+ desc = fontDescriptions[fontDescIndex];
+ if (desc == null) {
+ return null;
+ }
+ pangoAttr = pango_attr_font_desc_new(desc);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+}
+
+static sqInt addLanguageinto(sqInt attrArrayOop, PangoAttrList *pangoAttrList) {
+ sqInt start;
+ PangoAttribute *pangoAttr;
+ sqInt end;
+ sqInt lang;
+ char *cLang;
+ sqInt *attrArray;
+ PangoLanguage *pangoLang;
+
+ attrArray = interpreterProxy->firstIndexableField(attrArrayOop);
+ start = ((attrArray[1]) >> 1);
+ end = ((attrArray[2]) >> 1);
+ lang = ((attrArray[3]) >> 1);
+ if (lang == 0) {
+ cLang = "en-US";
+ }
+ if (lang == 5) {
+ cLang = "ja-JP";
+ }
+ if (lang == 6) {
+ cLang = "zh-CN";
+ }
+ if (lang == 7) {
+ cLang = "ko-KR";
+ }
+ if (lang == 9) {
+ cLang = "zh-TW";
+ }
+ if (lang == 13) {
+ cLang = "el-EL";
+ }
+ if (lang == 15) {
+ cLang = "ne-NP";
+ }
+ pangoLang = pango_language_from_string(cLang);
+ pangoAttr = pango_attr_language_new(pangoLang);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+}
+
+static sqInt addSelectionAtpixelwith(PangoRectangle *rect, unsigned int c, cairo_t*context) {
+ sqInt a;
+ sqInt r;
+ sqInt b;
+ sqInt g;
+
+ a = ((usqInt) (c & 4278190080U)) >> 24;
+ if (a == 0) {
+ return null;
+ }
+ r = ((usqInt) (c & 16711680)) >> 16;
+ g = ((usqInt) (c & 65280)) >> 8;
+ b = c & 255;
+ cairo_save(context);
+ cairo_set_source_rgba(context, r / 255.0, g / 255.0, b / 255.0, a / 255.0);
+ cairo_new_path(context);
+ cairo_move_to(context, PANGO_PIXELS(rect->x) + 1, PANGO_PIXELS(rect->y));
+ cairo_line_to(context, PANGO_PIXELS(rect->x) + 1, PANGO_PIXELS(rect->y+rect->height));
+ cairo_stroke(context);
+ cairo_restore(context);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+}
+
+static sqInt addSelectionFromtopixelinto(sqInt start, sqInt end, unsigned int c, PangoAttrList *pangoAttrList) {
+ sqInt r;
+ sqInt b;
+ PangoAttribute *pangoAttr;
+ sqInt g;
+ sqInt alpha;
+
+ alpha = ((usqInt) (c && 4278190080U)) >> 24;
+ r = ((usqInt) (c & 16711680)) >> 16;
+ g = ((usqInt) (c & 65280)) >> 8;
+ b = c & 255;
+ if ((alpha == 0) && ((r == 0) && ((g == 0) && (b == 0)))) {
+ return null;
+ }
+ if (!(r == 0)) {
+ r = r * 257;
+ }
+ if (!(g == 0)) {
+ g = g * 257;
+ }
+ if (!(b == 0)) {
+ b = b * 257;
+ }
+ pangoAttr = pango_attr_background_new(r, g, b);
+ pangoAttr->start_index = start;
+ pangoAttr->end_index = end;
+ pango_attr_list_change(pangoAttrList, pangoAttr);
+}
+
+
+/* Get contexts[canvasOop's handle] */
+
+static cairo_t* contextFrom(sqInt canvasOop) {
+ cairo_t*context;
+ sqInt contextIndex;
+ sqInt targetOop;
+
+ if ((interpreterProxy->slotSizeOf(canvasOop)) < CanvasInstSize) {
+ fail("canvas oop invalid");
+ return null;
+ }
+ contextIndex = interpreterProxy->fetchIntegerofObject(CanvasHandleIndex, canvasOop);
+ if (interpreterProxy->failed()) {
+ contextIndex = interpreterProxy->fetchPointerofObject(CanvasHandleIndex, canvasOop);
+ if (!(contextIndex == (interpreterProxy->nilObject()))) {
+ fail("canvas handle not an integer");
+ }
+ return null;
+ }
+ if ((contextIndex < 0) || (contextIndex > (lastIndex(contexts)))) {
+ failwith("canvas handle %i out of bounds", contextIndex);
+ return null;
+ }
+ context = contexts[contextIndex];
+ if (context == null) {
+ failwith("canvas handle %i invalid", contextIndex);
+ return null;
+ }
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ targetOop = interpreterProxy->fetchPointerofObject(CanvasTargetIndex, canvasOop);
+ if (!((surfaceFrom(targetOop)) == (cairo_get_target(context)))) {
+ failwith("canvas handle %i does not match target", contextIndex);
+ return null;
+ }
+ return context;
+}
+
+static sqInt createContextFor(sqInt canvasOop) {
+ sqInt i;
+ cairo_surface_t*targetSurface;
+ cairo_t*context;
+ sqInt targetID;
+ sqInt contextIndex;
+ sqInt targetOop;
+
+ if ((interpreterProxy->slotSizeOf(canvasOop)) < CanvasInstSize) {
+ fail("canvas oop invalid");
+ return null;
+ }
+ targetOop = interpreterProxy->fetchPointerofObject(CanvasTargetIndex, canvasOop);
+ if ((interpreterProxy->slotSizeOf(targetOop)) <= FormBitsIndex) {
+ fail("target oop invalid");
+ return null;
+ }
+ targetID = interpreterProxy->fetchIntegerofObject(FormBitsIndex, targetOop);
+ if (interpreterProxy->failed()) {
+ fail("target handle not an integer");
+ return null;
+ }
+ targetSurface = findSurface(targetID);
+ if (!((targetSurface != null) && ((cairo_surface_status(targetSurface)) == 0))) {
+ fail("target surface invalid");
+ return null;
+ }
+ contextIndex = -1;
+ i = 0;
+ while (i <= (lastIndex(contexts))) {
+ if ((contexts[i]) == null) {
+ contextIndex = i;
+ i = lastIndex(contexts);
+ }
+ i += 1;
+ }
+ if (contextIndex < 0) {
+ fail("too many canvases");
+ return null;
+ }
+ context = cairo_create(targetSurface);
+ contexts[contextIndex] = context;
+ /* missing DebugCode */;
+ return contextIndex;
+}
+
+
+/* create a surface, register it in SurfacePlugin and answer its surface plugin ID */
+
+static sqInt createSurfaceFor(sqInt formOop) {
+ cairo_format_t format;
+ sqInt bits;
+ sqInt width;
+ sqInt status;
+ cairo_surface_t*surface;
+ sqInt height;
+ sqInt depth;
+
+ if ((interpreterProxy->slotSizeOf(formOop)) < FormInstSize) {
+ fail("form oop invalid");
+ return -1;
+ }
+ width = interpreterProxy->fetchIntegerofObject(FormWidthIndex, formOop);
+ height = interpreterProxy->fetchIntegerofObject(FormHeightIndex, formOop);
+ depth = interpreterProxy->fetchIntegerofObject(FormDepthIndex, formOop);
+ if (interpreterProxy->failed()) {
+ fail("form fields are not integers");
+ return -1;
+ }
+ switch(depth) {
+ case 32: format = CAIRO_FORMAT_ARGB32; break;
+ case 24: format = CAIRO_FORMAT_RGB24; break;
+ case 16: format = CAIRO_FORMAT_RGB16_565; break;
+ case  8: format = CAIRO_FORMAT_A8; break;
+ case  1: format = CAIRO_FORMAT_A1; break;
+ default: format = -1;
+ }
+ if ((width <= 0) || ((height <= 0) || (format < 0))) {
+ fail("form fields out of range");
+ return -1;
+ }
+ bits = interpreterProxy->fetchPointerofObject(FormBitsIndex, formOop);
+ if (!(bits == (interpreterProxy->nilObject()))) {
+ fail("form handle not nil");
+ return -1;
+ }
+ surface = cairo_image_surface_create(format, width, height);
+ status = cairo_surface_status(surface);
+ if (!(status == 0)) {
+ failwith("failed to create surface - %s", cairo_status_to_string(status));
+ cairo_surface_destroy(surface);
+ return -1;
+ }
+ return registerSurface(surface);
+}
+
+static sqInt destroyContextFor(sqInt canvasOop) {
+ cairo_t*context;
+ sqInt contextIndex;
+
+ if ((interpreterProxy->slotSizeOf(canvasOop)) < CanvasInstSize) {
+ fail("canvas oop invalid");
+ return null;
+ }
+ contextIndex = interpreterProxy->fetchIntegerofObject(CanvasHandleIndex, canvasOop);
+ if (interpreterProxy->failed()) {
+ fail("canvas handle not an integer");
+ return null;
+ }
+ if ((contextIndex < 0) || (contextIndex > (lastIndex(contexts)))) {
+ failwith("canvas handle %i out of bounds", contextIndex);
+ return null;
+ }
+ context = contexts[contextIndex];
+ if (context == null) {
+ failwith("canvas handle %i invalid", contextIndex);
+ return null;
+ }
+ /* missing DebugCode */;
+ cairo_destroy(context);
+ contexts[contextIndex] = null;
+ return null;
+}
+
+
+/* fetch surface from surfaceID, destroy it and unregister from SurfacePlugin */
+
+static sqInt destroySurface(sqInt surfaceID) {
+ cairo_surface_t*surface;
+
+ surface = findSurface(surfaceID);
+ if (surface == null) {
+ failwith("could not find surface %i", surfaceID);
+ return null;
+ }
+ cairo_surface_destroy(surface);
+ unregisterSurface(surfaceID);
+ return null;
+}
+
+
+/* fill or stroke depending on canvasOop's flags */
+
+static void fillOrStrokefrom(cairo_t*context, sqInt canvasOop) {
+ sqInt stroke;
+ sqInt canvasFlags;
+ sqInt fill;
+ sqInt rgb;
+
+ canvasFlags = interpreterProxy->fetchIntegerofObject(CanvasFlagsIndex, canvasOop);
+ if (interpreterProxy->failed()) {
+ fail("canvas flags not an integer");
+ } else {
+ fill = canvasFlags & CanvasFlagFill;
+ stroke = canvasFlags & CanvasFlagStroke;
+ if (fill != 0) {
+ if (stroke != 0) {
+ cairo_fill_preserve(context);
+ } else {
+ cairo_fill(context);
+ }
+ }
+ if (stroke != 0) {
+ rgb = interpreterProxy->fetchIntegerofObject(CanvasStrokeColorIndex, canvasOop);
+ cairo_save(context);
+ setSourcergbalpha(context, rgb, stroke);
+ cairo_stroke(context);
+ cairo_restore(context);
+ }
+ }
+}
+
+
+/* Answer surface handle for surfaceID */
+
+static cairo_surface_t* findSurface(sqInt surfaceID) {
+ sqInt surfaceHandle;
+
+ if (findSurfaceFn == null) {
+ if (!(loadSurfacePlugin())) {
+ return null;
+ }
+ }
+ if (!((*findSurfaceFn)(surfaceID, &surfaceDispatch, &surfaceHandle))) {
+ return null;
+ }
+ return ((cairo_surface_t*) surfaceHandle);
+}
+
+
+/* Note: This is coded so that plugins can be run from Squeak. */
+
+static VirtualMachine * getInterpreter(void) {
+ return interpreterProxy;
+}
+
+
+/* Note: This is hardcoded so it can be run from Squeak.
+ The module name is used for validating a module *after*
+ it is loaded to check if it does really contain the module
+ we're thinking it contains. This is important! */
+
+EXPORT(const char*) getModuleName(void) {
+ return moduleName;
+}
+
+static sqInt getSurfaceFormatgetWgetHgetDgetMsb(cairo_surface_t *surfaceHandle, int*wReturn, int*hReturn, int*dReturn, int*mReturn) {
+ sqInt msb;
+ sqInt width;
+ sqInt depth;
+ sqInt height;
+
+ /* missing DebugCode */;
+ width = cairo_image_surface_get_width(surfaceHandle);
+ height = cairo_image_surface_get_height(surfaceHandle);
+ depth = formatToDepth[cairo_image_surface_get_format(surfaceHandle)];
+ msb = 1;
+ *wReturn = width;
+ *hReturn = height;
+ *dReturn = depth;
+ *mReturn = msb;
+ return 1;
+}
+
+static sqInt halt(void) {
+ ;
+}
+
+EXPORT(sqInt) initialiseModule(void) {
+ sqInt i;
+
+ for (i = 0; i <= (lastIndex(contexts)); i += 1) {
+ contexts[i] = null;
+ }
+ for (i = 0; i <= (lastIndex(fontDescriptions)); i += 1) {
+ fontDescriptions[i] = null;
+ }
+ defaultFontDescription = pango_font_description_from_string("Times New Roman 10");
+ registerSurfaceFn = null;
+ unregisterSurfaceFn = null;
+ findSurfaceFn = null;
+ return 1;
+}
+
+static sqInt leadingCharOf(unsigned int value) {
+ return ((usqInt) (value & 1069547520) >> 22);
+}
+
+
+/* Load the surface support plugin */
+
+static sqInt loadSurfacePlugin(void) {
+ sqInt found;
+
+ registerSurfaceFn = ((fn_ioRegisterSurface) (interpreterProxy->ioLoadFunctionFrom("ioRegisterSurface", "SurfacePlugin")));
+ unregisterSurfaceFn = ((fn_ioUnregisterSurface) (interpreterProxy->ioLoadFunctionFrom("ioUnregisterSurface", "SurfacePlugin")));
+ findSurfaceFn = ((fn_ioFindSurface) (interpreterProxy->ioLoadFunctionFrom("ioFindSurface", "SurfacePlugin")));
+ found = (registerSurfaceFn != null) && ((unregisterSurfaceFn != null) && (findSurfaceFn != null));
+ if (!(found)) {
+ fail("could not load SurfacePlugin");
+ }
+ maxSurfaceID = -1;
+ return found;
+}
+
+static unsigned char* lockSurfacegetPitchxywh(cairo_surface_t*surfaceHandle, int*pitchReturn, sqInt x, sqInt y, sqInt w, sqInt h) {
+ sqInt pitch;
+ unsigned char*data;
+
+ /* missing DebugCode */;
+ cairo_surface_flush(surfaceHandle);
+ data = cairo_image_surface_get_data(surfaceHandle);
+ pitch = cairo_image_surface_get_stride(surfaceHandle);
+ *pitchReturn = pitch;
+ return data;
+}
+
+
+/* The module with the given name was just unloaded.
+ Make sure we have no dangling references. */
+
+EXPORT(sqInt) moduleUnloaded(char *aModuleName) {
+ if ((strcmp(aModuleName, "SurfacePlugin")) == 0) {
+ registerSurfaceFn = null;
+ unregisterSurfaceFn = null;
+ findSurfaceFn = null;
+ }
+ return 1;
+}
+
+static sqInt msg(char *s) {
+ fprintf(stderr, "\n%s: %s", moduleName, s);
+}
+
+static void polyPathfrom(cairo_t*context, sqInt pointsOop) {
+ float*points;
+ sqInt i;
+ sqInt pointsCount;
+
+ points = interpreterProxy->arrayValueOf(pointsOop);
+ pointsCount = interpreterProxy->slotSizeOf(pointsOop);
+ if (!(interpreterProxy->failed())) {
+ if (pointsCount >= 2) {
+ cairo_move_to(context, points[0], points[1]);
+ for (i = 2; i <= (pointsCount - 1); i += 2) {
+ cairo_line_to(context, points[i], points[i + 1]);
+ }
+ }
+ }
+}
+
+EXPORT(sqInt) primitivePangoBlockAtIndex(void) {
+ sqInt index;
+ cairo_t*context;
+ sqInt origin;
+ unsigned char*aString;
+ sqInt trailing;
+ sqInt aStringOop;
+ sqInt stringLength;
+ PangoAttrList*attrList;
+ sqInt atEnd;
+ PangoLayout*layout;
+ sqInt canvasOop;
+ sqInt corner;
+ sqInt charData;
+ PangoRectangle pos;
+ sqInt inStringOop;
+ sqInt utf8Index;
+ sqInt x;
+ sqInt y;
+ sqInt sqAttrArray;
+ sqInt w;
+ sqInt h;
+ sqInt withWrap;
+ sqInt cData;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(8), "Object"));
+ inStringOop = interpreterProxy->stackValue(8);
+ utf8Index = interpreterProxy->stackIntegerValue(7);
+ x = interpreterProxy->stackIntegerValue(6);
+ y = interpreterProxy->stackIntegerValue(5);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(4), "Object"));
+ sqAttrArray = interpreterProxy->stackValue(4);
+ w = interpreterProxy->stackIntegerValue(3);
+ h = interpreterProxy->stackIntegerValue(2);
+ withWrap = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(1));
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Object"));
+ cData = interpreterProxy->stackValue(0);
+ ;
+ canvasOop = interpreterProxy->stackValue(9);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ aStringOop = inStringOop;
+ aString = interpreterProxy->firstIndexableField(aStringOop);
+ layout = pango_cairo_create_layout(context);
+ attrList = pango_attr_list_new();
+ translateSqAttrsToPangoAttrsinto(sqAttrArray, attrList);
+ pango_layout_set_text(layout, aString, strlen(aString));
+ pango_layout_set_attributes(layout, attrList);
+ pango_layout_set_width(layout, w * (PANGO_SCALE));
+ if (withWrap) {
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ }
+ cairo_translate(context, x, y);
+ pango_cairo_update_layout(context, layout);
+ stringLength = strlen(aString);
+ if (utf8Index == (stringLength + 1)) {
+ atEnd = 1;
+ pango_layout_index_to_pos(layout, ((((((utf8Index - 1) < 0) ? 0 : (utf8Index - 1))) < stringLength) ? ((((utf8Index - 1) < 0) ? 0 : (utf8Index - 1))) : stringLength), &pos);
+ pos.x = pos.x + pos.width;
+ } else {
+ atEnd = 0;
+ pango_layout_index_to_pos(layout, (((((utf8Index < 0) ? 0 : utf8Index)) < stringLength) ? (((utf8Index < 0) ? 0 : utf8Index)) : stringLength), &pos);
+ }
+ pango_attr_list_unref(attrList);
+ g_object_unref(layout);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ interpreterProxy->pushRemappableOop(aStringOop);
+ interpreterProxy->pushRemappableOop(cData);
+ origin = interpreterProxy->makePointwithxValueyValue((PANGO_PIXELS(pos.x)) + x, (PANGO_PIXELS(pos.y)) + y);
+ interpreterProxy->pushRemappableOop(origin);
+ corner = interpreterProxy->makePointwithxValueyValue((PANGO_PIXELS(pos.x+pos.width)) + x, (PANGO_PIXELS(pos.y+pos.height)) + y);
+ origin = interpreterProxy->popRemappableOop();
+ charData = interpreterProxy->popRemappableOop();
+ aStringOop = interpreterProxy->popRemappableOop();
+ aString = interpreterProxy->firstIndexableField(aStringOop);
+ interpreterProxy->storePointerofObjectwithValue(0, charData, origin);
+ interpreterProxy->storePointerofObjectwithValue(1, charData, corner);
+ index = sqCharCountInfromto(aString, 0, utf8Index);
+ if (!(atEnd)) {
+ index += 1;
+ }
+ interpreterProxy->storePointerofObjectwithValue(2, charData, ((index << 1) | 1));
+ _return_value = interpreterProxy->integerObjectOf(index);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(10, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitiveClear(void) {
+ sqInt op;
+ sqInt canvasFlags;
+ sqInt fill;
+ cairo_t*context;
+ sqInt canvasOop;
+
+ canvasOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ canvasFlags = interpreterProxy->fetchIntegerofObject(CanvasFlagsIndex, canvasOop);
+ if (interpreterProxy->failed()) {
+ fail("canvas flags not an integer");
+ return null;
+ }
+ fill = canvasFlags & CanvasFlagFill;
+ if (!(fill)) {
+ cairo_set_source_rgba(context, 0.0, 0.0, 0.0, 0.0);
+ }
+ op = cairo_get_operator(context);
+ cairo_set_operator(context, CairoOperatorSource);
+ cairo_paint(context);
+ cairo_set_operator(context, op);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt) primitiveClipRectangleLeftRightTopBottom(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double left;
+ double right;
+ double top;
+ double bottom;
+
+ left = interpreterProxy->stackFloatValue(3);
+ right = interpreterProxy->stackFloatValue(2);
+ top = interpreterProxy->stackFloatValue(1);
+ bottom = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(4);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ cairo_rectangle(context, left, top, right - left, bottom - top);
+ cairo_clip(context);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(4);
+ return null;
+}
+
+EXPORT(sqInt) primitiveClose(void) {
+ sqInt canvasOop;
+
+ canvasOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ destroyContextFor(canvasOop);
+ if (!(interpreterProxy->failed())) {
+ interpreterProxy->storePointerofObjectwithValue(CanvasHandleIndex, canvasOop, interpreterProxy->nilObject());
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt) primitivePangoComposeString(void) {
+ cairo_t*context;
+ sqInt linesSize;
+ sqInt newW;
+ sqInt sqStart;
+ sqInt lineCount;
+ PangoRectangle ink;
+ sqInt start;
+ sqInt lineIndex;
+ PangoAttrList*attrList;
+ sqInt sqEnd;
+ sqInt baseline;
+ PangoLayoutLine*line;
+ PangoRectangle logical;
+ sqInt totalY;
+ sqInt prevBaseline;
+ PangoLayout*layout;
+ sqInt lastLine;
+ sqInt canvasOop;
+ sqInt addition;
+ PangoLayoutIter*lineIter;
+ sqInt next;
+ char *aString;
+ sqInt x;
+ sqInt y;
+ sqInt sqAttrArray;
+ sqInt w;
+ sqInt h;
+ sqInt withWrap;
+ sqInt lines;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(7)));
+ aString = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(7))));
+ x = interpreterProxy->stackIntegerValue(6);
+ y = interpreterProxy->stackIntegerValue(5);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(4), "Object"));
+ sqAttrArray = interpreterProxy->stackValue(4);
+ w = interpreterProxy->stackIntegerValue(3);
+ h = interpreterProxy->stackIntegerValue(2);
+ withWrap = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(1));
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Object"));
+ lines = interpreterProxy->stackValue(0);
+ ;
+ canvasOop = interpreterProxy->stackValue(8);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ layout = pango_cairo_create_layout(context);
+ attrList = pango_attr_list_new();
+ translateSqAttrsToPangoAttrsinto(sqAttrArray, attrList);
+ pango_layout_set_text(layout, aString, strlen(aString));
+ pango_layout_set_attributes(layout, attrList);
+ pango_layout_set_width(layout, w * (PANGO_SCALE));
+ if (withWrap) {
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ }
+ cairo_translate(context, x, y);
+ pango_cairo_update_layout(context, layout);
+ lineCount = pango_layout_get_line_count(layout);
+ lineIter = pango_layout_get_iter(layout);
+ baseline = pango_layout_iter_get_baseline(lineIter);
+ prevBaseline = 0;
+ cairo_translate(context, 0, PANGO_PIXELS(baseline));
+ sqEnd = 0;
+ totalY = 0;
+ linesSize = interpreterProxy->stSizeOf(lines);
+ lastLine = (((lineCount < linesSize) ? lineCount : linesSize)) - 1;
+ for (lineIndex = 0; lineIndex <= lastLine; lineIndex += 1) {
+ line = pango_layout_iter_get_line_readonly(lineIter);
+ pango_layout_line_get_extents(line, &ink, &logical);
+ sqStart = sqEnd + 1;
+ start = line->start_index;
+
+ /* self log: 'sqStart, sqEnd: %d %d' with: sqStart with: sqEnd. */
+
+ sqEnd = (sqStart + (sqCharCountInfromto(aString, start, start + (line->length)))) - 1;
+ if (((start + (line->length)) < (interpreterProxy->stSizeOf(((int) aString)))) && ((aString[start + (line->length)]) == 13)) {
+ sqEnd += 1;
+ }
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineStartIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), sqStart);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineEndIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), sqEnd);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineLeftIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), (PANGO_PIXELS(logical.x)) + x);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineRightIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), (PANGO_PIXELS(logical.x+logical.width)) + x);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineTopIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), totalY + y);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineInternalSpaceIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), ((0 << 1) | 1));
+ interpreterProxy->storeIntegerofObjectwithValue(TextLinePaddingWidthIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), ((0 << 1) | 1));
+ next = pango_layout_iter_next_line(lineIter);
+ if (next) {
+ addition = (logical.height) + (pango_layout_get_spacing(layout));
+ } else {
+ addition = logical.height;
+ }
+ totalY += PANGO_PIXELS(addition);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineBottomIndex, interpreterProxy->fetchPointerofObject(lineIndex, lines), totalY + y);
+ }
+ pango_layout_get_extents(layout, &ink, &logical);
+ newW = PANGO_PIXELS(logical.width);
+ pango_layout_iter_free(lineIter);
+ pango_attr_list_unref(attrList);
+ g_object_unref(layout);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ _return_value = interpreterProxy->integerObjectOf(newW);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(9, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitivePangoComposeString2(void) {
+ cairo_t*context;
+ sqInt newW;
+ sqInt sqStart;
+ sqInt lineCount;
+ PangoRectangle ink;
+ unsigned char*aString;
+ unsigned char*inString;
+ sqInt start;
+ sqInt lineIndex;
+ PangoAttrList*attrList;
+ sqInt sqEnd;
+ sqInt baseline;
+ PangoLayoutLine*line;
+ PangoRectangle logical;
+ sqInt totalY;
+ sqInt prevBaseline;
+ sqInt arrayOop;
+ sqInt retArrayOop;
+ sqInt textLine;
+ sqInt i;
+ PangoLayout*layout;
+ sqInt lastLine;
+ sqInt canvasOop;
+ sqInt addition;
+ sqInt textLineClass;
+ sqInt inStringSize;
+ PangoLayoutIter*lineIter;
+ sqInt next;
+ sqInt inStringOop;
+ sqInt x;
+ sqInt y;
+ sqInt sqAttrArray;
+ sqInt w;
+ sqInt h;
+ sqInt withWrap;
+ sqInt inTextLineClass;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(7), "Object"));
+ inStringOop = interpreterProxy->stackValue(7);
+ x = interpreterProxy->stackIntegerValue(6);
+ y = interpreterProxy->stackIntegerValue(5);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(4), "Object"));
+ sqAttrArray = interpreterProxy->stackValue(4);
+ w = interpreterProxy->stackIntegerValue(3);
+ h = interpreterProxy->stackIntegerValue(2);
+ withWrap = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(1));
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Object"));
+ inTextLineClass = interpreterProxy->stackValue(0);
+ ;
+ canvasOop = interpreterProxy->stackValue(8);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ inStringSize = interpreterProxy->stSizeOf(inStringOop);
+ if (inStringSize == 0) {
+ primitiveFail();
+ return null;
+ }
+ aString = alloca(inStringSize);
+ inString = interpreterProxy->firstIndexableField(inStringOop);
+ strncpy(aString, inString, inStringSize);
+ textLineClass = inTextLineClass;
+ layout = pango_cairo_create_layout(context);
+ attrList = pango_attr_list_new();
+ translateSqAttrsToPangoAttrsinto(sqAttrArray, attrList);
+ pango_layout_set_text(layout, aString, strlen(aString));
+ pango_layout_set_attributes(layout, attrList);
+ pango_layout_set_width(layout, w * (PANGO_SCALE));
+ if (withWrap) {
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ }
+ cairo_translate(context, x, y);
+ pango_cairo_update_layout(context, layout);
+ lineCount = pango_layout_get_line_count(layout);
+ lineIter = pango_layout_get_iter(layout);
+ baseline = pango_layout_iter_get_baseline(lineIter);
+ prevBaseline = 0;
+ cairo_translate(context, 0, PANGO_PIXELS(baseline));
+ sqEnd = 0;
+ totalY = 0;
+ interpreterProxy->pushRemappableOop(textLineClass);
+ arrayOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), lineCount);
+ textLineClass = interpreterProxy->popRemappableOop();
+ for (i = 0; i <= (lineCount - 1); i += 1) {
+ interpreterProxy->pushRemappableOop(textLineClass);
+ interpreterProxy->pushRemappableOop(arrayOop);
+ textLine = interpreterProxy->instantiateClassindexableSize(textLineClass, 0);
+ arrayOop = interpreterProxy->popRemappableOop();
+ textLineClass = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(i, arrayOop, textLine);
+ }
+ lastLine = lineCount - 1;
+ for (lineIndex = 0; lineIndex <= lastLine; lineIndex += 1) {
+ line = pango_layout_iter_get_line_readonly(lineIter);
+ pango_layout_line_get_extents(line, &ink, &logical);
+ sqStart = sqEnd + 1;
+ start = line->start_index;
+
+ /* self log: 'sqStart, sqEnd: %d %d' with: sqStart with: sqEnd. */
+
+ sqEnd = (sqStart + (sqCharCountInfromto(aString, start, start + (line->length)))) - 1;
+ if (((start + (line->length)) < (interpreterProxy->stSizeOf(((int) aString)))) && ((aString[start + (line->length)]) == 13)) {
+ sqEnd += 1;
+ }
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineStartIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), sqStart);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineEndIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), sqEnd);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineLeftIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), (PANGO_PIXELS(logical.x)) + x);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineRightIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), (PANGO_PIXELS(logical.x+logical.width)) + x);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineTopIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), totalY + y);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineInternalSpaceIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), ((0 << 1) | 1));
+ interpreterProxy->storeIntegerofObjectwithValue(TextLinePaddingWidthIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), ((0 << 1) | 1));
+ next = pango_layout_iter_next_line(lineIter);
+ if (next) {
+ addition = (logical.height) + (pango_layout_get_spacing(layout));
+ } else {
+ addition = logical.height;
+ }
+ totalY += PANGO_PIXELS(addition);
+ interpreterProxy->storeIntegerofObjectwithValue(TextLineBottomIndex, interpreterProxy->fetchPointerofObject(lineIndex, arrayOop), totalY + y);
+ }
+ pango_layout_get_extents(layout, &ink, &logical);
+ newW = PANGO_PIXELS(logical.width);
+ pango_layout_iter_free(lineIter);
+ pango_attr_list_unref(attrList);
+ g_object_unref(layout);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ interpreterProxy->pushRemappableOop(arrayOop);
+ retArrayOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 2);
+ arrayOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storeIntegerofObjectwithValue(0, retArrayOop, newW);
+ interpreterProxy->storePointerofObjectwithValue(1, retArrayOop, arrayOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(9, retArrayOop);
+ return null;
+}
+
+EXPORT(sqInt) primitiveCreateFormHandle(void) {
+ sqInt formOop;
+ sqInt surfaceID;
+ sqInt _return_value;
+
+ formOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ surfaceID = createSurfaceFor(formOop);
+ if (surfaceID < 0) {
+ interpreterProxy->primitiveFail();
+ }
+ if (!(interpreterProxy->failed())) {
+ _return_value = interpreterProxy->integerObjectOf(surfaceID);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt) primitiveDestroyFormHandle(void) {
+ sqInt surfaceID;
+
+ surfaceID = interpreterProxy->stackIntegerValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!(interpreterProxy->failed())) {
+ destroySurface(surfaceID);
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawArcRadiusXYFromTo(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double radius;
+ double x;
+ double y;
+ double angle1;
+ double angle2;
+
+ radius = interpreterProxy->stackFloatValue(4);
+ x = interpreterProxy->stackFloatValue(3);
+ y = interpreterProxy->stackFloatValue(2);
+ angle1 = interpreterProxy->stackFloatValue(1);
+ angle2 = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(5);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ if (radius > 0.0) {
+ cairo_arc(context, x, y, radius, angle1, angle2);
+ } else {
+ cairo_arc_negative(context, x, y, -1.0 * radius, angle1, angle2);
+ }
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(5);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawCurveFromXYviaXYandXYtoXY(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double x0;
+ double y0;
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+ double x3;
+ double y3;
+
+ x0 = interpreterProxy->stackFloatValue(7);
+ y0 = interpreterProxy->stackFloatValue(6);
+ x1 = interpreterProxy->stackFloatValue(5);
+ y1 = interpreterProxy->stackFloatValue(4);
+ x2 = interpreterProxy->stackFloatValue(3);
+ y2 = interpreterProxy->stackFloatValue(2);
+ x3 = interpreterProxy->stackFloatValue(1);
+ y3 = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(8);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ cairo_move_to(context, x0, y0);
+ cairo_curve_to(context, x1, y1, x2, y2, x3, y3);
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(8);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawCurveFromXYviaXYtoXY(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double x0;
+ double y0;
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+
+ x0 = interpreterProxy->stackFloatValue(5);
+ y0 = interpreterProxy->stackFloatValue(4);
+ x1 = interpreterProxy->stackFloatValue(3);
+ y1 = interpreterProxy->stackFloatValue(2);
+ x2 = interpreterProxy->stackFloatValue(1);
+ y2 = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(6);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ cairo_move_to(context, x0, y0);
+ cairo_curve_to(context, ((2.0 * x1) + x0) / 3.0, ((2.0 * y1) + y0) / 3.0, ((2.0 * x1) + x2) / 3.0, ((2.0 * y1) + y2) / 3.0, x2, y2);
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(6);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawGeneralBezierShape(void) {
+ cairo_t*context;
+ sqInt shapeCount;
+ sqInt segmentCount;
+ short*seg;
+ sqInt j;
+ sqInt yVia;
+ sqInt i;
+ sqInt xFrom;
+ sqInt contourOop;
+ sqInt canvasOop;
+ sqInt xTo;
+ sqInt yTo;
+ sqInt xVia;
+ sqInt yFrom;
+ sqInt shapeOop;
+
+ shapeOop = interpreterProxy->stackValue(0);
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ shapeCount = interpreterProxy->slotSizeOf(shapeOop);
+ cairo_new_path(context);
+ for (i = 0; i <= (shapeCount - 1); i += 1) {
+ contourOop = interpreterProxy->fetchPointerofObject(i, shapeOop);
+ if (!(interpreterProxy->isMemberOf(contourOop, "ShortPointArray"))) {
+ failwith("bezier contour %i is no ShortPointArray", i + 1);
+ return null;
+ }
+ segmentCount = (interpreterProxy->slotSizeOf(contourOop)) / 3;
+ seg = interpreterProxy->arrayValueOf(contourOop);
+ for (j = 0; j <= (segmentCount - 1); j += 1) {
+ xFrom = seg[0];
+ yFrom = seg[1];
+ xVia = seg[2];
+ yVia = seg[3];
+ xTo = seg[4];
+ yTo = seg[5];
+ if (j == 0) {
+ cairo_move_to(context, xFrom, yFrom);
+ }
+ if ((xFrom == xVia) && (yFrom == yVia)) {
+ cairo_line_to(context, xTo, yTo);
+ } else {
+ cairo_curve_to(context, (xFrom + (2.0 * xVia)) / 3.0, (yFrom + (2.0 * yVia)) / 3.0, ((2.0 * xVia) + xTo) / 3.0, ((2.0 * yVia) + yTo) / 3.0, xTo, yTo);
+ }
+ seg += 6;
+ }
+ cairo_close_path(context);
+ }
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawImageSrcLRTBDestLRTB(void) {
+ cairo_surface_t*srcSurface;
+ cairo_t*context;
+ sqInt canvasOop;
+ sqInt formOop;
+ double dstL;
+ double dstR;
+ double dstT;
+ double dstB;
+ double srcL;
+ double srcR;
+ double srcT;
+ double srcB;
+
+ formOop = interpreterProxy->stackValue(8);
+ dstL = interpreterProxy->stackFloatValue(7);
+ dstR = interpreterProxy->stackFloatValue(6);
+ dstT = interpreterProxy->stackFloatValue(5);
+ dstB = interpreterProxy->stackFloatValue(4);
+ srcL = interpreterProxy->stackFloatValue(3);
+ srcR = interpreterProxy->stackFloatValue(2);
+ srcT = interpreterProxy->stackFloatValue(1);
+ srcB = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(9);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ srcSurface = surfaceFrom(formOop);
+ if (!((srcSurface != null) && ((cairo_surface_status(srcSurface)) == 0))) {
+ fail("source surface invalid");
+ return null;
+ }
+ if ((srcR != srcL) && (srcT != srcB)) {
+ cairo_save(context);
+ cairo_translate(context, dstL, dstT);
+ cairo_scale(context, (dstR - dstL) / (srcR - srcL), (dstB - dstT) / (srcB - srcT));
+ cairo_new_path(context);
+ cairo_rectangle(context, 0.0, 0.0, srcR - srcL, srcB - srcT);
+ cairo_set_source_surface(context, srcSurface, 0.0 - srcL, 0.0 - srcT);
+ cairo_fill(context);
+ cairo_restore(context);
+ }
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(9);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawLineFromXYtoXY(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double fromX;
+ double fromY;
+ double toX;
+ double toY;
+
+ fromX = interpreterProxy->stackFloatValue(3);
+ fromY = interpreterProxy->stackFloatValue(2);
+ toX = interpreterProxy->stackFloatValue(1);
+ toY = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(4);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ cairo_move_to(context, fromX, fromY);
+ cairo_line_to(context, toX, toY);
+ strokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(4);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawOvalLeftRightTopBottom(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double left;
+ double right;
+ double top;
+ double bottom;
+
+ left = interpreterProxy->stackFloatValue(3);
+ right = interpreterProxy->stackFloatValue(2);
+ top = interpreterProxy->stackFloatValue(1);
+ bottom = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(4);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if ((right != left) && (top != bottom)) {
+ cairo_save(context);
+ cairo_new_path(context);
+ cairo_translate(context, (left + right) / 2.0, (top + bottom) / 2.0);
+ cairo_scale(context, (right - left) / 2.0, (bottom - top) / 2.0);
+ cairo_arc(context, 0.0, 0.0, 1.0, 0.0, degrees(360.0));
+ cairo_restore(context);
+ fillOrStrokefrom(context, canvasOop);
+ }
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(4);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawPolygon(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ sqInt pointsOop;
+
+ pointsOop = interpreterProxy->stackValue(0);
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ polyPathfrom(context, pointsOop);
+ cairo_close_path(context);
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawPolyline(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ sqInt pointsOop;
+
+ pointsOop = interpreterProxy->stackValue(0);
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ polyPathfrom(context, pointsOop);
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveDrawRectangleLeftRightTopBottom(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double left;
+ double right;
+ double top;
+ double bottom;
+
+ left = interpreterProxy->stackFloatValue(3);
+ right = interpreterProxy->stackFloatValue(2);
+ top = interpreterProxy->stackFloatValue(1);
+ bottom = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(4);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_new_path(context);
+ cairo_rectangle(context, left, top, right - left, bottom - top);
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(4);
+ return null;
+}
+
+
+/* x1 x2 x3 x4
+ y1 + / - \ +
+ y2 / . . \
+ | |
+ y3 \ . . /
+ y4 + \ - / + */
+
+EXPORT(sqInt) primitiveDrawRoundRectLeftRightTopBottomRadiusCorner(void) {
+ cairo_t*context;
+ double y3;
+ double y2;
+ double x3;
+ double x2;
+ sqInt canvasOop;
+ double ry;
+ double rx;
+ double r;
+ double x1;
+ double x4;
+ double y1;
+ double y4;
+ double radius;
+ sqInt cornerFlags;
+
+ x1 = interpreterProxy->stackFloatValue(5);
+ x4 = interpreterProxy->stackFloatValue(4);
+ y1 = interpreterProxy->stackFloatValue(3);
+ y4 = interpreterProxy->stackFloatValue(2);
+ radius = interpreterProxy->stackFloatValue(1);
+ cornerFlags = interpreterProxy->stackIntegerValue(0);
+ canvasOop = interpreterProxy->stackValue(6);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ rx = (x4 - x1) / 2.0;
+ ry = (y4 - y1) / 2.0;
+ r = (((((radius < rx) ? radius : rx)) < ry) ? (((radius < rx) ? radius : rx)) : ry);
+ x2 = x1 + r;
+ x3 = x4 - r;
+ y2 = y1 + r;
+ y3 = y4 - r;
+ cairo_new_path(context);
+ if (cornerFlags & 1) {
+ cairo_arc(context, x2, y2, r, degrees(180), degrees(270));
+ } else {
+ cairo_move_to(context, x1, y1);
+ }
+ if (cornerFlags & 8) {
+ cairo_arc(context, x3, y2, r, degrees(270), degrees(360));
+ } else {
+ cairo_line_to(context, x4, y1);
+ }
+ if (cornerFlags & 4) {
+ cairo_arc(context, x3, y3, r, degrees(0), degrees(90));
+ } else {
+ cairo_line_to(context, x4, y4);
+ }
+ if (cornerFlags & 2) {
+ cairo_arc(context, x2, y3, r, degrees(90), degrees(180));
+ } else {
+ cairo_line_to(context, x1, y4);
+ }
+ cairo_close_path(context);
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(6);
+ return null;
+}
+
+
+/* draw a string including its outline if selected */
+
+EXPORT(sqInt) primitiveDrawZeroTerminatedUtf8StringXY(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ char *aString;
+ double x;
+ double y;
+
+ interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(2)));
+ aString = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(2))));
+ x = interpreterProxy->stackFloatValue(1);
+ y = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(3);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_move_to(context, x, y);
+ cairo_text_path(context, aString);
+ fillOrStrokefrom(context, canvasOop);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(3);
+ return null;
+}
+
+EXPORT(sqInt) primitiveFillBitmapOriginXYdirectionXYnormalXYRepeatImage(void) {
+ cairo_pattern_t*pattern;
+ cairo_t*context;
+ sqInt canvasOop;
+ cairo_matrix_t*m;
+ cairo_matrix_t mdata;
+ cairo_surface_t*surface;
+ double ox;
+ double oy;
+ double dx;
+ double dy;
+ double nx;
+ double ny;
+ sqInt aBoolean;
+ sqInt formOop;
+
+ ox = interpreterProxy->stackFloatValue(7);
+ oy = interpreterProxy->stackFloatValue(6);
+ dx = interpreterProxy->stackFloatValue(5);
+ dy = interpreterProxy->stackFloatValue(4);
+ nx = interpreterProxy->stackFloatValue(3);
+ ny = interpreterProxy->stackFloatValue(2);
+ aBoolean = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(1));
+ formOop = interpreterProxy->stackValue(0);
+ m = &mdata;
+ canvasOop = interpreterProxy->stackValue(8);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ surface = surfaceFrom(formOop);
+ if (!((surface != null) && ((cairo_surface_status(surface)) == 0))) {
+ fail("surface invalid");
+ return null;
+ }
+ pattern = cairo_pattern_create_for_surface(surface);
+ cairo_matrix_init(m, dx, dy, nx, ny, ox, oy);
+ cairo_matrix_invert(m);
+ cairo_pattern_set_matrix(pattern, m);
+ if (aBoolean) {
+ cairo_pattern_set_extend(pattern, CairoExtendRepeat);
+ }
+ if (cairo_pattern_status(pattern)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_pattern_status(pattern)));
+ return null;
+ }
+ cairo_set_source(context, pattern);
+ cairo_pattern_destroy(pattern);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(8);
+ return null;
+}
+
+EXPORT(sqInt) primitiveFillColorAlpha(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ sqInt rgb;
+ sqInt alpha;
+
+ rgb = interpreterProxy->stackIntegerValue(1);
+ alpha = interpreterProxy->stackIntegerValue(0);
+ canvasOop = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ setSourcergbalpha(context, rgb, alpha);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+EXPORT(sqInt) primitiveFillLinearOriginXYdirectionXYcolorStops(void) {
+ cairo_pattern_t*pattern;
+ int*colorStops;
+ sqInt i;
+ sqInt colorStopsCount;
+ cairo_t*context;
+ sqInt canvasOop;
+ double ox;
+ double oy;
+ double dx;
+ double dy;
+ sqInt colorStopsOop;
+
+ ox = interpreterProxy->stackFloatValue(4);
+ oy = interpreterProxy->stackFloatValue(3);
+ dx = interpreterProxy->stackFloatValue(2);
+ dy = interpreterProxy->stackFloatValue(1);
+ colorStopsOop = interpreterProxy->stackValue(0);
+ canvasOop = interpreterProxy->stackValue(5);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ colorStops = interpreterProxy->arrayValueOf(colorStopsOop);
+ colorStopsCount = interpreterProxy->slotSizeOf(colorStopsOop);
+ if (interpreterProxy->failed()) {
+ fail("bad colorStops array");
+ return null;
+ }
+ pattern = cairo_pattern_create_linear(ox, oy, ox + dx, oy + dy);
+ if (cairo_pattern_status(pattern)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_pattern_status(pattern)));
+ return null;
+ }
+ for (i = 0; i <= (colorStopsCount - 1); i += 3) {
+ addColorStopTooffsetrgbalpha(pattern, colorStops[i], colorStops[i + 1], colorStops[i + 2]);
+ }
+ cairo_set_source(context, pattern);
+ cairo_pattern_destroy(pattern);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(5);
+ return null;
+}
+
+EXPORT(sqInt) primitiveFillRadialOriginXYdirectionXYnormalXYcolorStops(void) {
+ int*colorStops;
+ cairo_t*context;
+ sqInt colorStopsCount;
+ cairo_matrix_t*m;
+ cairo_matrix_t mdata;
+ sqInt i;
+ sqInt canvasOop;
+ cairo_pattern_t*pattern;
+ double ox;
+ double oy;
+ double dx;
+ double dy;
+ double nx;
+ double ny;
+ sqInt colorStopsOop;
+
+ ox = interpreterProxy->stackFloatValue(6);
+ oy = interpreterProxy->stackFloatValue(5);
+ dx = interpreterProxy->stackFloatValue(4);
+ dy = interpreterProxy->stackFloatValue(3);
+ nx = interpreterProxy->stackFloatValue(2);
+ ny = interpreterProxy->stackFloatValue(1);
+ colorStopsOop = interpreterProxy->stackValue(0);
+ m = &mdata;
+ canvasOop = interpreterProxy->stackValue(7);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ colorStops = interpreterProxy->arrayValueOf(colorStopsOop);
+ colorStopsCount = interpreterProxy->slotSizeOf(colorStopsOop);
+ if (interpreterProxy->failed()) {
+ fail("bad colorStops array");
+ return null;
+ }
+ pattern = cairo_pattern_create_radial(0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
+ cairo_matrix_init(m, dx, dy, nx, ny, ox, oy);
+ cairo_matrix_invert(m);
+ cairo_pattern_set_matrix(pattern, m);
+ if (cairo_pattern_status(pattern)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_pattern_status(pattern)));
+ return null;
+ }
+ for (i = 0; i <= (colorStopsCount - 1); i += 3) {
+ addColorStopTooffsetrgbalpha(pattern, colorStops[i], colorStops[i + 1], colorStops[i + 2]);
+ }
+ cairo_set_source(context, pattern);
+ cairo_pattern_destroy(pattern);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(7);
+ return null;
+}
+
+EXPORT(sqInt) primitiveFontFace(void) {
+ cairo_font_face_t*crFace;
+ FT_Face ftFace;
+ cairo_t*context;
+ sqInt canvasOop;
+ char *faceHandle;
+
+ interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(0)));
+ faceHandle = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(0))));
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ ftFace = *(void**)faceHandle;
+ crFace = cairo_ft_font_face_create_for_ft_face(ftFace, FT_LOAD_NO_HINTING);
+ cairo_set_font_face(context, crFace);
+ cairo_font_face_destroy(crFace);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveFontSize(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double size;
+
+ size = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_set_font_size(context, size);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveGetLineWidth(void) {
+ double width;
+ cairo_t*context;
+ sqInt canvasOop;
+ sqInt _return_value;
+
+ canvasOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ width = cairo_get_line_width(context);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ _return_value = interpreterProxy->floatObjectOf(width);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitivePangoFontDescriptionIndex(void) {
+ sqInt familyNameSize;
+ sqInt newInd;
+ PangoFontDescription *desc;
+ sqInt i;
+ sqInt ind;
+ char cFamilyName[128];
+ sqInt size;
+ sqInt pangoStyle;
+ char *familyName;
+ sqInt isAbsolute;
+ sqInt familyNameOop;
+ sqInt ptSize;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "Object"));
+ familyNameOop = interpreterProxy->stackValue(1);
+ ptSize = interpreterProxy->stackIntegerValue(0);
+ ;
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ familyNameSize = interpreterProxy->stSizeOf(familyNameOop);
+ if (familyNameSize > 127) {
+ return null;
+ }
+ if ((ptSize < 0) || (ptSize > 1000000)) {
+ _return_value = ((-1 << 1) | 1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(3, _return_value);
+ return null;
+ }
+ familyName = interpreterProxy->firstIndexableField(familyNameOop);
+ for (i = 0; i <= (familyNameSize - 1); i += 1) {
+ cFamilyName[i] = (familyName[i]);
+ }
+ cFamilyName[familyNameSize] = 0;
+ newInd = -1;
+ ind = 0;
+ desc = null;
+ while (newInd == -1) {
+ desc = fontDescriptions[ind];
+ if (desc == null) {
+ newInd = ind;
+ } else {
+ isAbsolute = pango_font_description_get_size_is_absolute(desc);
+ size = pango_font_description_get_size(desc);
+ if (isAbsolute) {
+ size = size;
+ }
+ if (((strcmp(cFamilyName, pango_font_description_get_family(desc))) == 0) && (size == (ptSize * (PANGO_SCALE)))) {
+ newInd = ind;
+ }
+ }
+ ind += 1;
+ if (ind > 255) {
+ newInd = 256;
+ }
+ }
+ if (newInd == 256) {
+ _return_value = ((-1 << 1) | 1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(3, _return_value);
+ return null;
+ }
+ if (desc == null) {
+ null;
+ } else {
+ _return_value = ((newInd << 1) | 1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(3, _return_value);
+ return null;
+ }
+ desc = pango_font_description_new();
+ pango_font_description_set_family(desc, cFamilyName);
+ pangoStyle = PANGO_STYLE_NORMAL;
+ pango_font_description_set_style(desc, pangoStyle);
+ pango_font_description_set_size(desc, ptSize * (PANGO_SCALE));
+ fontDescriptions[newInd] = desc;
+ _return_value = ((newInd << 1) | 1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(3, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitiveGetTransform(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ cairo_matrix_t m;
+ float *aTransform;
+
+ aTransform = ((float *) (interpreterProxy->arrayValueOf(interpreterProxy->stackValue(0))));
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_get_matrix(context, &m);
+ aTransform[0] = (m.xx);
+ aTransform[1] = (m.xy);
+ aTransform[2] = (m.x0);
+ aTransform[3] = (m.yx);
+ aTransform[4] = (m.yy);
+ aTransform[5] = (m.y0);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitivePangoIndexAtPoint(void) {
+ sqInt index;
+ cairo_t*context;
+ sqInt origin;
+ unsigned char*aString;
+ sqInt trailing;
+ sqInt aStringOop;
+ sqInt lineIndex;
+ sqInt inside;
+ PangoAttrList*attrList;
+ PangoLayoutLine*line;
+ sqInt xPos;
+ PangoLayout*layout;
+ sqInt canvasOop;
+ sqInt corner;
+ sqInt charData;
+ PangoRectangle pos;
+ sqInt inStringOop;
+ sqInt x;
+ sqInt y;
+ sqInt sqAttrArray;
+ sqInt w;
+ sqInt h;
+ sqInt withWrap;
+ sqInt cData;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(7), "Object"));
+ inStringOop = interpreterProxy->stackValue(7);
+ x = interpreterProxy->stackIntegerValue(6);
+ y = interpreterProxy->stackIntegerValue(5);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(4), "Object"));
+ sqAttrArray = interpreterProxy->stackValue(4);
+ w = interpreterProxy->stackIntegerValue(3);
+ h = interpreterProxy->stackIntegerValue(2);
+ withWrap = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(1));
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Object"));
+ cData = interpreterProxy->stackValue(0);
+ ;
+ canvasOop = interpreterProxy->stackValue(8);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ aStringOop = inStringOop;
+ aString = interpreterProxy->firstIndexableField(aStringOop);
+ layout = pango_cairo_create_layout(context);
+ attrList = pango_attr_list_new();
+ translateSqAttrsToPangoAttrsinto(sqAttrArray, attrList);
+ pango_layout_set_text(layout, aString, strlen(aString));
+ pango_layout_set_attributes(layout, attrList);
+ pango_layout_set_width(layout, w * (PANGO_SCALE));
+ if (withWrap) {
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ }
+ cairo_translate(context, x, y);
+ pango_cairo_update_layout(context, layout);
+ inside = pango_layout_xy_to_index(layout, x * (PANGO_SCALE), y * (PANGO_SCALE), &index, &trailing);
+ pango_layout_index_to_pos(layout, index, &pos);
+ line = null;
+ if (!(inside)) {
+ pango_layout_index_to_line_x(layout, index, trailing, &lineIndex, &xPos);
+
+ /* self log: 'lineIndex %x' with: line. */
+
+ line = pango_layout_get_line_readonly(layout, ((lineIndex < 0) ? 0 : lineIndex));
+ if (line == null) {
+ index = strlen(aString);
+ } else {
+ pango_layout_line_ref(line);
+
+ /* self log: 'line->length %d' with: (self cCode: 'line->length'). */
+
+ index = line->start_index;
+ index += line->length;
+ if (trailing > 0) {
+ trailing = 1;
+ }
+ }
+ }
+ pango_attr_list_unref(attrList);
+ g_object_unref(layout);
+ if (!(line == null)) {
+ pango_layout_line_unref(line);
+ }
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ interpreterProxy->pushRemappableOop(aStringOop);
+ interpreterProxy->pushRemappableOop(cData);
+ origin = interpreterProxy->makePointwithxValueyValue(PANGO_PIXELS(pos.x), PANGO_PIXELS(pos.y));
+ interpreterProxy->pushRemappableOop(origin);
+ corner = interpreterProxy->makePointwithxValueyValue(PANGO_PIXELS(pos.x+pos.width), PANGO_PIXELS(pos.y+pos.height));
+ origin = interpreterProxy->popRemappableOop();
+ charData = interpreterProxy->popRemappableOop();
+ aStringOop = interpreterProxy->popRemappableOop();
+ aString = interpreterProxy->firstIndexableField(aStringOop);
+ interpreterProxy->storePointerofObjectwithValue(0, charData, origin);
+ interpreterProxy->storePointerofObjectwithValue(1, charData, corner);
+ index = sqCharCountInfromto(aString, 0, (((index + trailing) < (1 + (strlen(aString)))) ? (index + trailing) : (1 + (strlen(aString)))));
+ if (inside || (xPos <= 0)) {
+ index += 1;
+ }
+ interpreterProxy->storePointerofObjectwithValue(2, charData, ((index << 1) | 1));
+ _return_value = interpreterProxy->integerObjectOf(index);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(9, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitiveLanguageAttributes(void) {
+ sqInt arraySize;
+ sqInt array4Oop;
+ sqInt lOop;
+ sqInt currentStart;
+ sqInt ws;
+ sqInt stringOop;
+ int *array;
+ int *array4;
+ unsigned int *string;
+ sqInt currentTag;
+ sqInt leadingChar;
+ sqInt arrayOop;
+ sqInt i;
+ sqInt arrayIndex;
+ sqInt stringSize;
+ sqInt currentEnd;
+ sqInt oStringOop;
+ sqInt oLOop;
+ sqInt oArrayOop;
+ sqInt _return_value;
+ sqInt v;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(2), "Object"));
+ oStringOop = interpreterProxy->stackValue(2);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "Object"));
+ oLOop = interpreterProxy->stackValue(1);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Object"));
+ oArrayOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ lOop = oLOop;
+ arrayOop = oArrayOop;
+ stringOop = oStringOop;
+ if (interpreterProxy->isBytes(stringOop)) {
+ _return_value = interpreterProxy->integerObjectOf(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(4, _return_value);
+ return null;
+ }
+ if (!(interpreterProxy->isWords(stringOop))) {
+ primitiveFail();
+ return null;
+ }
+ arraySize = interpreterProxy->stSizeOf(arrayOop);
+ if (arraySize <= 0) {
+ primitiveFail();
+ return null;
+ }
+ stringSize = interpreterProxy->stSizeOf(stringOop);
+ if (stringSize == 0) {
+ _return_value = interpreterProxy->integerObjectOf(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(4, _return_value);
+ return null;
+ }
+ string = interpreterProxy->firstIndexableField(stringOop);
+ array = interpreterProxy->firstIndexableField(arrayOop);
+ ws = string[0];
+ currentTag = ((usqInt) (ws & 1069547520) >> 22);
+ leadingChar = -1;
+ currentStart = 0;
+ /* begin utf8CountFor: */
+ v = ws & 2097151;
+ if ((0 <= v) && (v <= 127)) {
+ currentEnd = 1;
+ goto l1;
+ }
+ if ((128 <= v) && (v <= 2047)) {
+ currentEnd = 2;
+ goto l1;
+ }
+ if ((2048 <= v) && (v <= 55295)) {
+ currentEnd = 3;
+ goto l1;
+ }
+ if ((57344 <= v) && (v <= 65535)) {
+ currentEnd = 3;
+ goto l1;
+ }
+ if ((65536 <= v) && (v <= 1114111)) {
+ currentEnd = 4;
+ goto l1;
+ }
+ currentEnd = 0;
+l1: /* end utf8CountFor: */;
+ arrayIndex = 0;
+ for (i = 1; i <= (stringSize - 1); i += 1) {
+ ws = string[i];
+ leadingChar = ((usqInt) (ws & 1069547520) >> 22);
+ if (leadingChar != currentTag) {
+ interpreterProxy->pushRemappableOop(stringOop);
+ interpreterProxy->pushRemappableOop(arrayOop);
+ interpreterProxy->pushRemappableOop(lOop);
+ array4Oop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 4);
+ lOop = interpreterProxy->popRemappableOop();
+ arrayOop = interpreterProxy->popRemappableOop();
+ stringOop = interpreterProxy->popRemappableOop();
+ array = interpreterProxy->firstIndexableField(arrayOop);
+ string = interpreterProxy->firstIndexableField(stringOop);
+ array4 = interpreterProxy->firstIndexableField(array4Oop);
+ array4[0] = lOop;
+ array4[1] = (((currentStart << 1) | 1));
+ array4[2] = (((currentEnd << 1) | 1));
+ array4[3] = (((currentTag << 1) | 1));
+ array[arrayIndex] = array4Oop;
+ arrayIndex += 1;
+ if (arrayIndex >= arraySize) {
+ primitiveFail();
+ return null;
+ }
+ currentTag = leadingChar;
+ currentStart = currentEnd;
+ }
+ currentEnd += utf8CountFor(ws);
+ }
+ interpreterProxy->pushRemappableOop(stringOop);
+ interpreterProxy->pushRemappableOop(arrayOop);
+ interpreterProxy->pushRemappableOop(lOop);
+ array4Oop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classArray(), 4);
+ lOop = interpreterProxy->popRemappableOop();
+ arrayOop = interpreterProxy->popRemappableOop();
+ stringOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, array4Oop, lOop);
+ interpreterProxy->storeIntegerofObjectwithValue(1, array4Oop, currentStart);
+ interpreterProxy->storeIntegerofObjectwithValue(2, array4Oop, currentEnd);
+ interpreterProxy->storeIntegerofObjectwithValue(3, array4Oop, currentTag);
+ interpreterProxy->storePointerofObjectwithValue(arrayIndex, arrayOop, array4Oop);
+ arrayIndex += 1;
+ _return_value = interpreterProxy->integerObjectOf(arrayIndex);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(4, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitiveOpen(void) {
+ sqInt handleOop;
+ sqInt contextIndex;
+ sqInt canvasOop;
+
+ canvasOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ contextIndex = createContextFor(canvasOop);
+ if (!(interpreterProxy->failed())) {
+ handleOop = interpreterProxy->integerObjectOf(contextIndex);
+ interpreterProxy->storePointerofObjectwithValue(CanvasHandleIndex, canvasOop, handleOop);
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt) primitivePangoIsAvailable(void) {
+ PangoLayout*layout;
+ cairo_t*context;
+ sqInt canvasOop;
+ sqInt _return_value;
+
+ canvasOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ layout = pango_cairo_create_layout(context);
+ if (layout == null) {
+ _return_value = interpreterProxy->integerObjectOf(2);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+ }
+ g_object_unref(layout);
+ _return_value = (1? interpreterProxy->trueObject(): interpreterProxy->falseObject());
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitivePluginVersion(void) {
+ sqInt _return_value;
+
+ _return_value = interpreterProxy->integerObjectOf(PluginVersion);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(1, _return_value);
+ return null;
+}
+
+EXPORT(sqInt) primitiveRestoreState(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+
+ canvasOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_restore(context);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt) primitiveRotateBy(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double angle;
+
+ angle = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_rotate(context, angle);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveSaveState(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+
+ canvasOop = interpreterProxy->stackValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_save(context);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ return null;
+}
+
+EXPORT(sqInt) primitiveScaleBy(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double x;
+ double y;
+
+ x = interpreterProxy->stackFloatValue(1);
+ y = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_scale(context, x, y);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+EXPORT(sqInt) primitiveSetLineWidth(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double width;
+
+ width = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_set_line_width(context, width);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveSetTransform(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ cairo_matrix_t m;
+ float *aTransform;
+
+ aTransform = ((float *) (interpreterProxy->arrayValueOf(interpreterProxy->stackValue(0))));
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_matrix_init(&m, aTransform[0], aTransform[3], aTransform[1], aTransform[4], aTransform[2], aTransform[5]);
+ cairo_set_matrix(context, &m);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitivePangoShowString(void) {
+ cairo_t*context;
+ sqInt newW;
+ sqInt lineCount;
+ PangoRectangle ink;
+ unsigned int cursorColor;
+ PangoAttrList*attrList;
+ PangoLayoutLine*line;
+ PangoRectangle logical;
+ sqInt prevBaseline;
+ PangoLayout*layout;
+ PangoRectangle startRect;
+ sqInt canvasOop;
+ PangoLayoutIter*lineIter;
+ sqInt indexToX;
+ char *aString;
+ sqInt x;
+ sqInt y;
+ sqInt sqAttrArray;
+ sqInt w;
+ sqInt h;
+ sqInt withWrap;
+ sqInt selStart;
+ sqInt selEnd;
+ sqInt cPixel;
+ sqInt _return_value;
+
+ interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(9)));
+ aString = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(9))));
+ x = interpreterProxy->stackIntegerValue(8);
+ y = interpreterProxy->stackIntegerValue(7);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(6), "Object"));
+ sqAttrArray = interpreterProxy->stackValue(6);
+ w = interpreterProxy->stackIntegerValue(5);
+ h = interpreterProxy->stackIntegerValue(4);
+ withWrap = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(3));
+ selStart = interpreterProxy->stackIntegerValue(2);
+ selEnd = interpreterProxy->stackIntegerValue(1);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(0), "Object"));
+ cPixel = interpreterProxy->stackValue(0);
+ ;
+ canvasOop = interpreterProxy->stackValue(10);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ cursorColor = interpreterProxy->positive32BitValueOf(cPixel);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ layout = pango_cairo_create_layout(context);
+ attrList = pango_attr_list_new();
+ translateSqAttrsToPangoAttrsinto(sqAttrArray, attrList);
+ if (!(selStart == selEnd)) {
+ if ((selStart >= 0) && (selEnd >= 0)) {
+ addSelectionFromtopixelinto(selStart, selEnd, cursorColor, attrList);
+ }
+ }
+ pango_layout_set_text(layout, aString, strlen(aString));
+ pango_layout_set_attributes(layout, attrList);
+ pango_layout_set_width(layout, w * (PANGO_SCALE));
+ if (withWrap) {
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ }
+ cairo_translate(context, x, y);
+ pango_cairo_update_layout(context, layout);
+
+ /* lineIter := self pangoLayoutGetIter: layout.
+ baseline := self pangoLayoutIterGetBaseline: lineIter.
+ prevBaseline := 0.
+ */
+
+ lineCount = pango_layout_get_line_count(layout);
+ if (1) {
+ pango_cairo_show_layout(context, layout);
+ } else {
+ null;
+ }
+ if (selStart == selEnd) {
+ if ((selStart >= 0) && (selEnd >= 0)) {
+ pango_layout_index_to_pos(layout, selStart, &startRect);
+ addSelectionAtpixelwith(&startRect, cursorColor, context);
+ }
+ }
+ pango_layout_get_extents(layout, &ink, &logical);
+
+ /* self pangoLayoutIterFree: lineIter. */
+
+ newW = PANGO_PIXELS(logical.width);
+ pango_attr_list_unref(attrList);
+ g_object_unref(layout);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ _return_value = interpreterProxy->integerObjectOf(newW);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(11, _return_value);
+ return null;
+}
+
+
+/* Show a string - ignores outline (use drawString primitive for outlines) */
+
+EXPORT(sqInt) primitiveShowZeroTerminatedUtf8StringXY(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ char *aString;
+ double x;
+ double y;
+
+ interpreterProxy->success(interpreterProxy->isBytes(interpreterProxy->stackValue(2)));
+ aString = ((char *) (interpreterProxy->firstIndexableField(interpreterProxy->stackValue(2))));
+ x = interpreterProxy->stackFloatValue(1);
+ y = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(3);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_move_to(context, x, y);
+ cairo_show_text(context, aString);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(3);
+ return null;
+}
+
+EXPORT(sqInt) primitiveStencilImageSrcLRTBDestLRTB(void) {
+ cairo_surface_t*srcSurface;
+ cairo_t*context;
+ sqInt canvasOop;
+ sqInt formOop;
+ double dstL;
+ double dstR;
+ double dstT;
+ double dstB;
+ double srcL;
+ double srcR;
+ double srcT;
+ double srcB;
+
+ formOop = interpreterProxy->stackValue(8);
+ dstL = interpreterProxy->stackFloatValue(7);
+ dstR = interpreterProxy->stackFloatValue(6);
+ dstT = interpreterProxy->stackFloatValue(5);
+ dstB = interpreterProxy->stackFloatValue(4);
+ srcL = interpreterProxy->stackFloatValue(3);
+ srcR = interpreterProxy->stackFloatValue(2);
+ srcT = interpreterProxy->stackFloatValue(1);
+ srcB = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(9);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ srcSurface = surfaceFrom(formOop);
+ if (!((srcSurface != null) && ((cairo_surface_status(srcSurface)) == 0))) {
+ fail("source surface invalid");
+ return null;
+ }
+ if ((srcR != srcL) && (srcT != srcB)) {
+ cairo_save(context);
+ cairo_translate(context, dstL, dstT);
+ cairo_scale(context, (dstR - dstL) / (srcR - srcL), (dstB - dstT) / (srcB - srcT));
+ cairo_new_path(context);
+ cairo_rectangle(context, 0.0, 0.0, srcR - srcL, srcB - srcT);
+ cairo_clip(context);
+ cairo_mask_surface(context, srcSurface, 0.0 - srcL, 0.0 - srcT);
+ cairo_restore(context);
+ }
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(9);
+ return null;
+}
+
+EXPORT(sqInt) primitiveTransformBy(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ cairo_matrix_t m;
+ float *aTransform;
+
+ aTransform = ((float *) (interpreterProxy->arrayValueOf(interpreterProxy->stackValue(0))));
+ canvasOop = interpreterProxy->stackValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_matrix_init(&m, aTransform[0], aTransform[3], aTransform[1], aTransform[4], aTransform[2], aTransform[5]);
+ cairo_transform(context, &m);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(1);
+ return null;
+}
+
+EXPORT(sqInt) primitiveTranslateBy(void) {
+ cairo_t*context;
+ sqInt canvasOop;
+ double x;
+ double y;
+
+ x = interpreterProxy->stackFloatValue(1);
+ y = interpreterProxy->stackFloatValue(0);
+ canvasOop = interpreterProxy->stackValue(2);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ context = contextFrom(canvasOop);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ cairo_translate(context, x, y);
+ if (cairo_status(context)) {
+ failwith("cairo error: %s", cairo_status_to_string(cairo_status(context)));
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->pop(2);
+ return null;
+}
+
+EXPORT(sqInt) primitiveUTF8StringWith2Indexes(void) {
+ sqInt utf8StringOop;
+ sqInt size;
+ sqInt bytes;
+ sqInt mult;
+ unsigned char *byteString;
+ sqInt stringOop;
+ sqInt utf8Index;
+ sqInt arrayOop;
+ sqInt i;
+ sqInt newIndex2;
+ sqInt realutf8StringOop;
+ sqInt newIndex1;
+ unsigned int *wideString;
+ unsigned char *realutf8String;
+ sqInt val;
+ unsigned int c;
+ unsigned char *utf8String;
+ sqInt oStringOop;
+ sqInt sqIndex1;
+ sqInt sqIndex2;
+ sqInt oArrayOop;
+ sqInt nullFlag;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(4), "Object"));
+ oStringOop = interpreterProxy->stackValue(4);
+ sqIndex1 = interpreterProxy->stackIntegerValue(3);
+ sqIndex2 = interpreterProxy->stackIntegerValue(2);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "Object"));
+ oArrayOop = interpreterProxy->stackValue(1);
+ nullFlag = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(0));
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ arrayOop = oArrayOop;
+ stringOop = oStringOop;
+ if (interpreterProxy->isPointers(stringOop)) {
+ primitiveFail();
+ return null;
+ }
+ bytes = interpreterProxy->isBytes(stringOop);
+ size = interpreterProxy->stSizeOf(stringOop);
+ if (bytes) {
+ mult = 2;
+ } else {
+ mult = 4;
+ }
+ interpreterProxy->pushRemappableOop(stringOop);
+ interpreterProxy->pushRemappableOop(arrayOop);
+ utf8StringOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), (size * mult) + 1);
+ arrayOop = interpreterProxy->popRemappableOop();
+ stringOop = interpreterProxy->popRemappableOop();
+ if (bytes) {
+ byteString = interpreterProxy->firstIndexableField(stringOop);
+ } else {
+ wideString = interpreterProxy->firstIndexableField(stringOop);
+ }
+ utf8Index = 0;
+ newIndex1 = -1;
+ newIndex2 = -1;
+ utf8String = interpreterProxy->firstIndexableField(utf8StringOop);
+ if (bytes) {
+ for (i = 0; i <= (size - 1); i += 1) {
+ c = byteString[i];
+ if ((i + 1) == sqIndex1) {
+ newIndex1 = utf8Index;
+ }
+ if ((i + 1) == sqIndex2) {
+ newIndex2 = utf8Index;
+ }
+ utf8Index = putCharintoat(c, utf8String, utf8Index);
+ }
+ } else {
+ for (i = 0; i <= (size - 1); i += 1) {
+ c = wideString[i];
+ if ((i + 1) == sqIndex1) {
+ newIndex1 = utf8Index;
+ }
+ if ((i + 1) == sqIndex2) {
+ newIndex2 = utf8Index;
+ }
+ utf8Index = putCharintoat(c, utf8String, utf8Index);
+ }
+ }
+ if (nullFlag) {
+ utf8String[utf8Index] = 0;
+ utf8Index += 1;
+ }
+ interpreterProxy->pushRemappableOop(utf8StringOop);
+ interpreterProxy->pushRemappableOop(arrayOop);
+ realutf8StringOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), utf8Index);
+ arrayOop = interpreterProxy->popRemappableOop();
+ utf8StringOop = interpreterProxy->popRemappableOop();
+ utf8String = interpreterProxy->firstIndexableField(utf8StringOop);
+ realutf8String = interpreterProxy->firstIndexableField(realutf8StringOop);
+ memcpy(realutf8String, utf8String, utf8Index);
+ interpreterProxy->storePointerofObjectwithValue(0, arrayOop, realutf8StringOop);
+ if (newIndex1 == -1) {
+ if (sqIndex1 == -1) {
+ val = -1;
+ } else {
+ val = utf8Index;
+ }
+ } else {
+ val = newIndex1;
+ }
+ interpreterProxy->storeIntegerofObjectwithValue(1, arrayOop, val);
+ if (newIndex2 == -1) {
+ if (sqIndex2 == -1) {
+ val = -1;
+ } else {
+ val = utf8Index;
+ }
+ } else {
+ val = newIndex2;
+ }
+ interpreterProxy->storeIntegerofObjectwithValue(2, arrayOop, val);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(6, arrayOop);
+ return null;
+}
+
+EXPORT(sqInt) primitiveUTF8StringWithIndex(void) {
+ sqInt utf8StringOop;
+ sqInt size;
+ sqInt bytes;
+ sqInt mult;
+ unsigned char *byteString;
+ sqInt stringOop;
+ sqInt utf8Index;
+ sqInt arrayOop;
+ sqInt i;
+ sqInt realutf8StringOop;
+ unsigned int *wideString;
+ unsigned char *realutf8String;
+ sqInt val;
+ unsigned int c;
+ sqInt newIndex;
+ unsigned char *utf8String;
+ sqInt oStringOop;
+ sqInt sqIndex;
+ sqInt oArrayOop;
+ sqInt nullFlag;
+
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(3), "Object"));
+ oStringOop = interpreterProxy->stackValue(3);
+ sqIndex = interpreterProxy->stackIntegerValue(2);
+ interpreterProxy->success(interpreterProxy->isKindOf(interpreterProxy->stackValue(1), "Object"));
+ oArrayOop = interpreterProxy->stackValue(1);
+ nullFlag = interpreterProxy->booleanValueOf(interpreterProxy->stackValue(0));
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ arrayOop = oArrayOop;
+ stringOop = oStringOop;
+ if (interpreterProxy->isPointers(stringOop)) {
+ primitiveFail();
+ return null;
+ }
+ bytes = interpreterProxy->isBytes(stringOop);
+ size = interpreterProxy->stSizeOf(stringOop);
+ if (bytes) {
+ mult = 2;
+ } else {
+ mult = 4;
+ }
+ interpreterProxy->pushRemappableOop(stringOop);
+ interpreterProxy->pushRemappableOop(arrayOop);
+ utf8StringOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), (size * mult) + 1);
+ arrayOop = interpreterProxy->popRemappableOop();
+ stringOop = interpreterProxy->popRemappableOop();
+ if (bytes) {
+ byteString = interpreterProxy->firstIndexableField(stringOop);
+ } else {
+ wideString = interpreterProxy->firstIndexableField(stringOop);
+ }
+ utf8Index = 0;
+ newIndex = -1;
+ utf8String = interpreterProxy->firstIndexableField(utf8StringOop);
+ if (bytes) {
+ for (i = 0; i <= (size - 1); i += 1) {
+ c = byteString[i];
+ if ((i + 1) == sqIndex) {
+ newIndex = utf8Index;
+ }
+ utf8Index = putCharintoat(c, utf8String, utf8Index);
+ }
+ } else {
+ for (i = 0; i <= (size - 1); i += 1) {
+ c = wideString[i];
+ if ((i + 1) == sqIndex) {
+ newIndex = utf8Index;
+ }
+ utf8Index = putCharintoat(c, utf8String, utf8Index);
+ }
+ }
+ if (nullFlag) {
+ utf8String[utf8Index] = 0;
+ utf8Index += 1;
+ }
+ interpreterProxy->pushRemappableOop(utf8StringOop);
+ interpreterProxy->pushRemappableOop(arrayOop);
+ realutf8StringOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), utf8Index);
+ arrayOop = interpreterProxy->popRemappableOop();
+ utf8StringOop = interpreterProxy->popRemappableOop();
+ utf8String = interpreterProxy->firstIndexableField(utf8StringOop);
+ realutf8String = interpreterProxy->firstIndexableField(realutf8StringOop);
+ memcpy(realutf8String, utf8String, utf8Index);
+ interpreterProxy->storePointerofObjectwithValue(0, arrayOop, realutf8StringOop);
+ if (newIndex == -1) {
+ if (sqIndex == -1) {
+ val = -1;
+ } else {
+ val = utf8Index;
+ }
+ } else {
+ val = newIndex;
+ }
+ interpreterProxy->storeIntegerofObjectwithValue(1, arrayOop, val);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ interpreterProxy->popthenPush(5, arrayOop);
+ return null;
+}
+
+static sqInt putCharintoat(sqInt c, unsigned char*utf8String, sqInt utf8Index) {
+ unsigned int val;
+ sqInt nBytes;
+ sqInt mask;
+ sqInt i;
+ sqInt index;
+ sqInt shift;
+ sqInt v;
+
+ val = c & 2097151;
+ index = utf8Index;
+ if ((0 <= val) && (val <= 127)) {
+ utf8String[index] = val;
+ return utf8Index + 1;
+ }
+ /* begin utf8CountFor: */
+ v = c & 2097151;
+ if ((0 <= v) && (v <= 127)) {
+ nBytes = 1;
+ goto l1;
+ }
+ if ((128 <= v) && (v <= 2047)) {
+ nBytes = 2;
+ goto l1;
+ }
+ if ((2048 <= v) && (v <= 55295)) {
+ nBytes = 3;
+ goto l1;
+ }
+ if ((57344 <= v) && (v <= 65535)) {
+ nBytes = 3;
+ goto l1;
+ }
+ if ((65536 <= v) && (v <= 1114111)) {
+ nBytes = 4;
+ goto l1;
+ }
+ nBytes = 0;
+l1: /* end utf8CountFor: */;
+ mask = utf8Headers[nBytes - 1];
+ shift = (nBytes - 1) * -6;
+ utf8String[index] = ((((shift < 0) ? ((usqInt) val >> -shift) : ((usqInt) val << shift))) | mask);
+ index += 1;
+ for (i = 2; i <= nBytes; i += 1) {
+ shift += 6;
+ utf8String[index] = (((((shift < 0) ? ((usqInt) val >> -shift) : ((usqInt) val << shift))) & 63) + 128);
+ index += 1;
+ }
+ return utf8Index + nBytes;
+}
+
+
+/* Register the given surface, answer an ID or -1 on failure */
+
+static sqInt registerSurface(cairo_surface_t*surfaceHandle) {
+ sqInt surfaceID;
+
+ if (registerSurfaceFn == null) {
+ if (!(loadSurfacePlugin())) {
+ return -1;
+ }
+ }
+ if (!((*registerSurfaceFn)((int)surfaceHandle, &surfaceDispatch, &surfaceID))) {
+ fail("could not register surface");
+ return -1;
+ }
+ /* missing DebugCode */;
+ if (surfaceID > maxSurfaceID) {
+ maxSurfaceID = surfaceID;
+ }
+ return surfaceID;
+}
+
+
+/* Note: This is coded so that is can be run from Squeak. */
+
+EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter) {
+ sqInt ok;
+
+ interpreterProxy = anInterpreter;
+ ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR;
+ if (ok == 0) {
+ return 0;
+ }
+ ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR;
+ return ok;
+}
+
+static void setSourcergbalpha(cairo_t*context, sqInt rgb, sqInt alpha) {
+ sqInt b;
+ sqInt r;
+ sqInt g;
+
+ r = (((usqInt) rgb) >> 20) & 1023;
+ g = (((usqInt) rgb) >> 10) & 1023;
+ b = (((usqInt) rgb) >> 0) & 1023;
+ if (alpha == 255) {
+ cairo_set_source_rgb(context, r / 1023.0, g / 1023.0, b / 1023.0);
+ } else {
+ cairo_set_source_rgba(context, r / 1023.0, g / 1023.0, b / 1023.0, alpha / 255.0);
+ }
+}
+
+static sqInt showSurfacexywh(cairo_surface_t *surfaceHandle, sqInt x, sqInt y, sqInt w, sqInt h) {
+ return 0;
+}
+
+EXPORT(sqInt) shutdownModule(void) {
+ PangoFontDescription*desc;
+ sqInt i;
+ sqInt id;
+ cairo_surface_t*surface;
+
+ for (i = 0; i <= (lastIndex(contexts)); i += 1) {
+ if (!((contexts[i]) == null)) {
+ logwith("context %i still active when unloading module!", i);
+ cairo_destroy(contexts[i]);
+ contexts[i] = null;
+ }
+ }
+ for (id = 0; id <= maxSurfaceID; id += 1) {
+ surface = findSurface(id);
+ if (surface != null) {
+ logwith("surface %i still active when unloading module!", id);
+ destroySurface(id);
+ }
+ }
+ for (i = 0; i <= 255; i += 1) {
+ desc = fontDescriptions[i];
+ if (desc != null) {
+ pango_font_description_free(desc);
+ fontDescriptions[i] = null;
+ }
+ }
+ if (defaultFontDescription != null) {
+ pango_font_description_free(defaultFontDescription);
+ defaultFontDescription = null;
+ }
+ return 1;
+}
+
+static sqInt sqAssert(sqInt aBool) {
+ /* missing DebugCode */;
+}
+
+static sqInt sqCharCountInfromto(unsigned char* aString, sqInt from, sqInt to) {
+ sqInt sqCount;
+ sqInt aChar;
+ sqInt index;
+
+ index = from;
+ sqCount = 0;
+ while (index < to) {
+ aChar = aString[index];
+ if (aChar < 128) {
+ index += 1;
+ } else {
+ if (aChar < 224) {
+ index += 2;
+ } else {
+ if (aChar < 240) {
+ index += 3;
+ } else {
+ if (aChar < 248) {
+ index += 4;
+ } else {
+ if (aChar < 252) {
+ index += 5;
+ } else {
+ if (aChar >= 252) {
+ index += 6;
+ }
+ }
+ }
+ }
+ }
+ }
+ sqCount += 1;
+ }
+ return sqCount;
+}
+
+
+/* stroke depending on canvasOop's stroke flag */
+
+static void strokefrom(cairo_t*context, sqInt canvasOop) {
+ sqInt stroke;
+ sqInt canvasFlags;
+ sqInt rgb;
+
+ canvasFlags = interpreterProxy->fetchIntegerofObject(CanvasFlagsIndex, canvasOop);
+ if (interpreterProxy->failed()) {
+ fail("canvas flags not an integer");
+ } else {
+ stroke = canvasFlags & CanvasFlagStroke;
+ if (stroke != 0) {
+ rgb = interpreterProxy->fetchIntegerofObject(CanvasStrokeColorIndex, canvasOop);
+ cairo_save(context);
+ setSourcergbalpha(context, rgb, stroke);
+ cairo_stroke(context);
+ cairo_restore(context);
+ }
+ }
+}
+
+
+/* answer a surface by looking up its surface plugin ID stored as bits in formOop */
+
+static cairo_surface_t* surfaceFrom(sqInt formOop) {
+ sqInt surfaceID;
+
+ if ((interpreterProxy->slotSizeOf(formOop)) < FormInstSize) {
+ fail("form oop invalid");
+ return null;
+ }
+ surfaceID = interpreterProxy->fetchIntegerofObject(FormBitsIndex, formOop);
+ if (interpreterProxy->failed()) {
+ fail("form handle not an integer");
+ return null;
+ }
+ return findSurface(surfaceID);
+}
+
+static sqInt translateSqAttrsToPangoAttrsinto(sqInt sqAttrsArrayOop, PangoAttrList *pangoAttrList) {
+ sqInt ind;
+ sqInt symbolOop;
+ sqInt *sqAttrsArray;
+ char *symbol;
+ sqInt sqAttrsSize;
+ sqInt attrArray;
+
+ sqAttrsSize = interpreterProxy->stSizeOf(sqAttrsArrayOop);
+ sqAttrsArray = interpreterProxy->firstIndexableField(sqAttrsArrayOop);
+ addDefaultInto(pangoAttrList);
+ for (ind = 0; ind <= (sqAttrsSize - 1); ind += 1) {
+ attrArray = sqAttrsArray[ind];
+ symbolOop = interpreterProxy->fetchPointerofObject(0, attrArray);
+ symbol = interpreterProxy->firstIndexableField(symbolOop);
+ if ((symbol[0]) == 65) {
+ addAlignmentinto(attrArray, pangoAttrList);
+ }
+ if ((symbol[0]) == 67) {
+ addColorinto(attrArray, pangoAttrList);
+ }
+ if ((symbol[0]) == 69) {
+ addEmphasisinto(attrArray, pangoAttrList);
+ }
+ if ((symbol[0]) == 70) {
+ addFontinto(attrArray, pangoAttrList);
+ }
+ if ((symbol[0]) == 76) {
+ addLanguageinto(attrArray, pangoAttrList);
+ }
+ }
+ return 1;
+}
+
+static sqInt unlockSurfacexywh(cairo_surface_t*surfaceHandle, sqInt x, sqInt y, sqInt w, sqInt h) {
+ /* missing DebugCode */;
+ if ((w > 0) && (h > 0)) {
+ cairo_surface_mark_dirty_rectangle(surfaceHandle, x, y, w, h);
+ }
+ return 1;
+}
+
+
+/* Unregister the surface, answer true if successful */
+
+static sqInt unregisterSurface(sqInt surfaceID) {
+ if (unregisterSurfaceFn == null) {
+ if (!(loadSurfacePlugin())) {
+ return 0;
+ }
+ }
+ /* missing DebugCode */;
+ if (!((*unregisterSurfaceFn)(surfaceID))) {
+ failwith("could not unregister surface %i", surfaceID);
+ return 0;
+ }
+ return 1;
+}
+
+static sqInt utf8CountFor(unsigned int value) {
+ sqInt v;
+
+ v = value & 2097151;
+ if ((0 <= v) && (v <= 127)) {
+ return 1;
+ }
+ if ((128 <= v) && (v <= 2047)) {
+ return 2;
+ }
+ if ((2048 <= v) && (v <= 55295)) {
+ return 3;
+ }
+ if ((57344 <= v) && (v <= 65535)) {
+ return 3;
+ }
+ if ((65536 <= v) && (v <= 1114111)) {
+ return 4;
+ }
+ return 0;
+}
+
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+
+
+void* RomePlugin_exports[][3] = {
+ {"RomePlugin", "primitivePangoBlockAtIndex", (void*)primitivePangoBlockAtIndex},
+ {"RomePlugin", "primitiveDrawImageSrcLRTBDestLRTB", (void*)primitiveDrawImageSrcLRTBDestLRTB},
+ {"RomePlugin", "primitiveDrawGeneralBezierShape", (void*)primitiveDrawGeneralBezierShape},
+ {"RomePlugin", "initialiseModule", (void*)initialiseModule},
+ {"RomePlugin", "primitiveFillRadialOriginXYdirectionXYnormalXYcolorStops", (void*)primitiveFillRadialOriginXYdirectionXYnormalXYcolorStops},
+ {"RomePlugin", "primitiveFillColorAlpha", (void*)primitiveFillColorAlpha},
+ {"RomePlugin", "primitiveFillLinearOriginXYdirectionXYcolorStops", (void*)primitiveFillLinearOriginXYdirectionXYcolorStops},
+ {"RomePlugin", "primitiveDestroyFormHandle", (void*)primitiveDestroyFormHandle},
+ {"RomePlugin", "primitiveClear", (void*)primitiveClear},
+ {"RomePlugin", "primitiveTransformBy", (void*)primitiveTransformBy},
+ {"RomePlugin", "primitiveDrawOvalLeftRightTopBottom", (void*)primitiveDrawOvalLeftRightTopBottom},
+ {"RomePlugin", "primitiveDrawPolygon", (void*)primitiveDrawPolygon},
+ {"RomePlugin", "primitivePluginVersion", (void*)primitivePluginVersion},
+ {"RomePlugin", "primitiveShowZeroTerminatedUtf8StringXY", (void*)primitiveShowZeroTerminatedUtf8StringXY},
+ {"RomePlugin", "primitiveFontFace", (void*)primitiveFontFace},
+ {"RomePlugin", "primitiveClipRectangleLeftRightTopBottom", (void*)primitiveClipRectangleLeftRightTopBottom},
+ {"RomePlugin", "getModuleName", (void*)getModuleName},
+ {"RomePlugin", "primitiveFontSize", (void*)primitiveFontSize},
+ {"RomePlugin", "primitivePangoIndexAtPoint", (void*)primitivePangoIndexAtPoint},
+ {"RomePlugin", "primitiveDrawPolyline", (void*)primitiveDrawPolyline},
+ {"RomePlugin", "primitiveDrawCurveFromXYviaXYandXYtoXY", (void*)primitiveDrawCurveFromXYviaXYandXYtoXY},
+ {"RomePlugin", "primitiveRotateBy", (void*)primitiveRotateBy},
+ {"RomePlugin", "primitiveDrawRoundRectLeftRightTopBottomRadiusCorner", (void*)primitiveDrawRoundRectLeftRightTopBottomRadiusCorner},
+ {"RomePlugin", "moduleUnloaded", (void*)moduleUnloaded},
+ {"RomePlugin", "primitiveDrawLineFromXYtoXY", (void*)primitiveDrawLineFromXYtoXY},
+ {"RomePlugin", "primitivePangoShowString", (void*)primitivePangoShowString},
+ {"RomePlugin", "primitiveDrawArcRadiusXYFromTo", (void*)primitiveDrawArcRadiusXYFromTo},
+ {"RomePlugin", "primitiveDrawZeroTerminatedUtf8StringXY", (void*)primitiveDrawZeroTerminatedUtf8StringXY},
+ {"RomePlugin", "primitiveSetLineWidth", (void*)primitiveSetLineWidth},
+ {"RomePlugin", "primitivePangoComposeString", (void*)primitivePangoComposeString},
+ {"RomePlugin", "primitiveUTF8StringWithIndex", (void*)primitiveUTF8StringWithIndex},
+ {"RomePlugin", "primitiveStencilImageSrcLRTBDestLRTB", (void*)primitiveStencilImageSrcLRTBDestLRTB},
+ {"RomePlugin", "setInterpreter", (void*)setInterpreter},
+ {"RomePlugin", "primitiveRestoreState", (void*)primitiveRestoreState},
+ {"RomePlugin", "primitiveScaleBy", (void*)primitiveScaleBy},
+ {"RomePlugin", "primitivePangoComposeString2", (void*)primitivePangoComposeString2},
+ {"RomePlugin", "primitiveDrawRectangleLeftRightTopBottom", (void*)primitiveDrawRectangleLeftRightTopBottom},
+ {"RomePlugin", "primitiveFillBitmapOriginXYdirectionXYnormalXYRepeatImage", (void*)primitiveFillBitmapOriginXYdirectionXYnormalXYRepeatImage},
+ {"RomePlugin", "primitiveSetTransform", (void*)primitiveSetTransform},
+ {"RomePlugin", "primitiveSaveState", (void*)primitiveSaveState},
+ {"RomePlugin", "primitiveLanguageAttributes", (void*)primitiveLanguageAttributes},
+ {"RomePlugin", "primitiveGetTransform", (void*)primitiveGetTransform},
+ {"RomePlugin", "primitivePangoFontDescriptionIndex", (void*)primitivePangoFontDescriptionIndex},
+ {"RomePlugin", "primitiveUTF8StringWith2Indexes", (void*)primitiveUTF8StringWith2Indexes},
+ {"RomePlugin", "primitiveCreateFormHandle", (void*)primitiveCreateFormHandle},
+ {"RomePlugin", "primitivePangoIsAvailable", (void*)primitivePangoIsAvailable},
+ {"RomePlugin", "primitiveClose", (void*)primitiveClose},
+ {"RomePlugin", "primitiveOpen", (void*)primitiveOpen},
+ {"RomePlugin", "primitiveDrawCurveFromXYviaXYtoXY", (void*)primitiveDrawCurveFromXYviaXYtoXY},
+ {"RomePlugin", "primitiveGetLineWidth", (void*)primitiveGetLineWidth},
+ {"RomePlugin", "shutdownModule", (void*)shutdownModule},
+ {"RomePlugin", "primitiveTranslateBy", (void*)primitiveTranslateBy},
+ {NULL, NULL, NULL}
+};
+
+
+#endif /* ifdef SQ_BUILTIN_PLUGIN */
+
Added: trunk/platforms/unix/src/plugins/Squeak3D/Squeak3D.c
===================================================================
--- trunk/platforms/unix/src/plugins/Squeak3D/Squeak3D.c                        (rev 0)
+++ trunk/platforms/unix/src/plugins/Squeak3D/Squeak3D.c 2011-01-23 09:41:21 UTC (rev 2355)
@@ -0,0 +1,3087 @@
+/* Automatically generated from Squeak on 23 January 2011 6:34:03 pm
+   by VMMaker 4.4.7
+ */
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+/* Default EXPORT macro that does nothing (see comment in sq.h): */
+#define EXPORT(returnType) returnType
+
+/* Do not include the entire sq.h file but just those parts needed. */
+/*  The virtual machine proxy definition */
+#include "sqVirtualMachine.h"
+/* Configuration options */
+#include "sqConfig.h"
+/* Platform specific definitions */
+#include "sqPlatformSpecific.h"
+
+#define true 1
+#define false 0
+#define null 0  /* using 'null' because nil is predefined in Think C */
+#ifdef SQUEAK_BUILTIN_PLUGIN
+#undef EXPORT
+// was #undef EXPORT(returnType) but screws NorCroft cc
+#define EXPORT(returnType) static returnType
+#endif
+#include "b3d.h"
+#include "b3d.h"
+
+#include "sqMemoryAccess.h"
+
+
+/*** Constants ***/
+#define AmbientPart 0
+#define DiffusePart 4
+#define EmissionAlpha 15
+#define EmissionBlue 14
+#define EmissionGreen 13
+#define EmissionRed 12
+#define FlagAmbientPart 256
+#define FlagAttenuated 4
+#define FlagDiffusePart 512
+#define FlagDirectional 2
+#define FlagHasSpot 8
+#define FlagM44Identity 1
+#define FlagM44NoPerspective 2
+#define FlagM44NoTranslation 4
+#define FlagPositional 1
+#define FlagSpecularPart 1024
+#define InAllMask 1365
+#define InBackBit 1024
+#define InBottomBit 64
+#define InFrontBit 256
+#define InLeftBit 1
+#define InRightBit 4
+#define InTopBit 16
+#define MaterialShininess 16
+#define MaterialSize 17
+#define OutAllMask 2730
+#define OutBackBit 2048
+#define OutBottomBit 128
+#define OutFrontBit 512
+#define OutLeftBit 2
+#define OutRightBit 8
+#define OutTopBit 32
+#define PrimLightAttenuationConstant 18
+#define PrimLightAttenuationLinear 19
+#define PrimLightAttenuationSquared 20
+#define PrimLightDirection 15
+#define PrimLightDirectionX 15
+#define PrimLightDirectionY 16
+#define PrimLightDirectionZ 17
+#define PrimLightFlags 21
+#define PrimLightPositionX 12
+#define PrimLightPositionY 13
+#define PrimLightPositionZ 14
+#define PrimLightSize 32
+#define PrimTypeMax 6
+#define PrimVertexSize 16
+#define PrimVtxClipFlags 13
+#define PrimVtxColor32 12
+#define PrimVtxNormal 3
+#define PrimVtxNormalX 3
+#define PrimVtxNormalY 4
+#define PrimVtxNormalZ 5
+#define PrimVtxPosition 0
+#define PrimVtxPositionX 0
+#define PrimVtxPositionY 1
+#define PrimVtxPositionZ 2
+#define PrimVtxRasterPosW 11
+#define PrimVtxRasterPosX 8
+#define PrimVtxRasterPosY 9
+#define PrimVtxRasterPosZ 10
+#define PrimVtxTexCoordU 6
+#define PrimVtxTexCoordV 7
+#define PrimVtxTexCoords 6
+#define SpecularPart 8
+#define SpotLightDeltaCos 24
+#define SpotLightExponent 25
+#define SpotLightMinCos 22
+#define VBTrackAmbient 1
+#define VBTrackDiffuse 2
+#define VBTrackEmission 8
+#define VBTrackSpecular 4
+#define VBTwoSidedLighting 64
+#define VBUseLocalViewer 128
+#define VBVtxHasNormals 16
+
+/*** Function Prototypes ***/
+static sqInt addPartfromtrackFlagscale(float *lightPart, float *materialPart, sqInt vbTrackFlag, double scale);
+static sqInt analyzeMatrix3x3Length(float *m);
+static sqInt analyzeMatrix(float *m);
+#pragma export on
+EXPORT(sqInt) b3dClipPolygon(void);
+EXPORT(sqInt) b3dComputeMinIndexZ(void);
+EXPORT(sqInt) b3dComputeMinZ(void);
+EXPORT(sqInt) b3dDetermineClipFlags(void);
+EXPORT(sqInt) b3dInitPrimitiveObject(void);
+EXPORT(sqInt) b3dInitializeRasterizerState(void);
+EXPORT(sqInt) b3dInplaceHouseHolderInvert(void);
+EXPORT(sqInt) b3dLoadIndexArray(void);
+EXPORT(sqInt) b3dLoadVertexBuffer(void);
+EXPORT(sqInt) b3dMapVertexBuffer(void);
+EXPORT(sqInt) b3dOrthoNormInverseMatrix(void);
+EXPORT(sqInt) b3dPrimitiveNextClippedTriangle(void);
+EXPORT(sqInt) b3dPrimitiveObjectSize(void);
+EXPORT(sqInt) b3dPrimitiveTextureSize(void);
+EXPORT(sqInt) b3dRasterizerVersion(void);
+EXPORT(sqInt) b3dShadeVertexBuffer(void);
+EXPORT(sqInt) b3dShaderVersion(void);
+EXPORT(sqInt) b3dStartRasterizer(void);
+EXPORT(sqInt) b3dTransformDirection(void);
+EXPORT(sqInt) b3dTransformMatrixWithInto(void);
+EXPORT(sqInt) b3dTransformPoint(void);
+EXPORT(sqInt) b3dTransformPrimitiveNormal(void);
+EXPORT(sqInt) b3dTransformPrimitivePosition(void);
+EXPORT(sqInt) b3dTransformPrimitiveRasterPosition(void);
+EXPORT(sqInt) b3dTransformVertexBuffer(void);
+EXPORT(sqInt) b3dTransformerVersion(void);
+EXPORT(sqInt) b3dTransposeMatrix(void);
+#pragma export off
+static double backClipValueFromto(sqInt last, sqInt next);
+static double bottomClipValueFromto(sqInt last, sqInt next);
+static sqInt clipPolygoncountwithmask(int *vtxArray, sqInt vtxCount, int *tempVtxArray, sqInt outMask);
+static sqInt clipPolygonBackFromtocount(int *buf1, int *buf2, sqInt n);
+static sqInt clipPolygonBottomFromtocount(int *buf1, int *buf2, sqInt n);
+static sqInt clipPolygonFrontFromtocount(int *buf1, int *buf2, sqInt n);
+static sqInt clipPolygonLeftFromtocount(int *buf1, int *buf2, sqInt n);
+static sqInt clipPolygonRightFromtocount(int *buf1, int *buf2, sqInt n);
+static sqInt clipPolygonTopFromtocount(int *buf1, int *buf2, sqInt n);
+static sqInt computeAttenuation(void);
+static sqInt computeDirection(void);
+static sqInt computeSpecularDirection(void);
+static double computeSpotFactor(void);
+static sqInt determineClipFlagscount(void *vtxArray, sqInt count);
+static double dotProductOfFloatwithDouble(float * v1, double *v2);
+static void* fetchLightSourceofObject(sqInt index, sqInt anArray);
+static double frontClipValueFromto(sqInt last, sqInt next);
+static VirtualMachine * getInterpreter(void);
+#pragma export on
+EXPORT(const char*) getModuleName(void);
+#pragma export off
+static sqInt halt(void);
+#pragma export on
+EXPORT(sqInt) initialiseModule(void);
+#pragma export off
+static sqInt interpolateFromtoatinto(float *last, float *next, double t, float *out);
+static double inverseLengthOfDouble(double * aVector);
+static double inverseLengthOfFloat(float * aVector);
+static double leftClipValueFromto(sqInt last, sqInt next);
+static sqInt loadObjectsFrom(sqInt stackIndex);
+static sqInt loadPrimitiveLightSource(void);
+static sqInt loadPrimitiveVertex(void);
+static sqInt loadRasterizerState(sqInt stackIndex);
+static sqInt loadTextureinto(sqInt textureOop, B3DTexture *destPtr);
+static sqInt loadTexturesFrom(sqInt stackIndex);
+static sqInt loadViewportFrom(sqInt stackIndex);
+static sqInt mapVBofSizeinto(void *vtxArray, sqInt vtxCount, sqInt boxArray);
+#pragma export on
+EXPORT(sqInt) moduleUnloaded(char *aModuleName);
+#pragma export off
+static sqInt msg(char *s);
+#pragma export on
+EXPORT(sqInt) primitiveSetBitBltPlugin(void);
+#pragma export off
+static double processIndexedofSizeidxArrayidxSize(float *vtxArray, sqInt vtxSize, int *idxArray, sqInt idxSize);
+static sqInt processIndexedIDXofSizeidxArrayidxSize(float *vtxArray, sqInt vtxSize, int *idxArray, sqInt idxSize);
+static double processNonIndexedofSize(float *vtxArray, sqInt vtxSize);
+static sqInt processNonIndexedIDXofSize(float *vtxArray, sqInt vtxSize);
+static double rightClipValueFromto(sqInt last, sqInt next);
+#pragma export on
+EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+#pragma export off
+static sqInt shadeVertex(void);
+static sqInt stackLightArrayValue(sqInt stackIndex);
+static void * stackMaterialValue(sqInt stackIndex);
+static void* stackMatrix(sqInt index);
+static void* stackPrimitiveIndexArrayofSizevalidateforVertexSize(sqInt stackIndex, sqInt nItems, sqInt aBool, sqInt maxIndex);
+static void* stackPrimitiveVertex(sqInt index);
+static void* stackPrimitiveVertexArrayofSize(sqInt index, sqInt nItems);
+static sqInt storeObjectsInto(sqInt stackIndex);
+static sqInt storePrimitiveVertex(void);
+static double topClipValueFromto(sqInt last, sqInt next);
+static sqInt transformMatrixwithinto(float *src, float *arg, float *dst);
+static sqInt transformPrimitiveNormalbyrescale(float *pVertex, float *matrix, sqInt rescale);
+static sqInt transformPrimitivePositionby(float *pVertex, float *matrix);
+static sqInt transformPrimitivePositionFastby(float *pVertex, float *matrix);
+static sqInt transformPrimitivePositionFasterby(float *pVertex, float *matrix);
+static sqInt transformPrimitiveRasterPositionby(float *pVertex, float *matrix);
+static sqInt transformVBcountbyandflags(float *vtxArray, sqInt vtxCount, float *modelViewMatrix, float *projectionMatrix, sqInt flags);
+static void* vbLoadArraysize(sqInt oop, sqInt count);
+/*** Variables ***/
+static char bbPluginName[256] = "BitBltPlugin";
+static sqInt copyBitsFn;
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+extern
+#endif
+struct VirtualMachine* interpreterProxy;
+static double l2vDirection[3];
+static double l2vDistance;
+static double l2vSpecDir[3];
+static sqInt lightFlags;
+static double lightScale;
+static float* litVertex;
+static sqInt loadBBFn;
+static const char *moduleName =
+#ifdef SQUEAK_BUILTIN_PLUGIN
+ "Squeak3D 23 January 2011 (i)"
+#else
+ "Squeak3D 23 January 2011 (e)"
+#endif
+;
+static float* primLight;
+static float* primMaterial;
+static B3DRasterizerState state;
+static sqInt vbFlags;
+static B3DPrimitiveViewport viewport;
+static double vtxInColor[4];
+static double vtxOutColor[4];
+
+
+
+/* Add the given light part to the output color, scaled by the given scale factor.
+ If the given flag is set in vbFlags then load the part from the primitive vertex */
+
+static sqInt addPartfromtrackFlagscale(float *lightPart, float *materialPart, sqInt vbTrackFlag, double scale) {
+    double aPart;
+    double bPart;
+    double gPart;
+    double rPart;
+
+ if (vbFlags & vbTrackFlag) {
+ rPart = ((vtxInColor[0]) * (lightPart[0])) * scale;
+ gPart = ((vtxInColor[1]) * (lightPart[1])) * scale;
+ bPart = ((vtxInColor[2]) * (lightPart[2])) * scale;
+ aPart = ((vtxInColor[3]) * (lightPart[3])) * scale;
+ } else {
+
+ /* Note: This should be pre-computed. */
+
+ rPart = ((materialPart[0]) * (lightPart[0])) * scale;
+ gPart = ((materialPart[1]) * (lightPart[1])) * scale;
+ bPart = ((materialPart[2]) * (lightPart[2])) * scale;
+ aPart = ((materialPart[3]) * (lightPart[3])) * scale;
+ }
+ vtxOutColor[0] = ((vtxOutColor[0]) + rPart);
+ vtxOutColor[1] = ((vtxOutColor[1]) + gPart);
+ vtxOutColor[2] = ((vtxOutColor[2]) + bPart);
+ vtxOutColor[3] = ((vtxOutColor[3]) + aPart);
+}
+
+
+/* Check if the matrix scales normals to non-unit length. */
+
+static sqInt analyzeMatrix3x3Length(float *m) {
+    double det;
+
+ det = (((((((m[0]) * (m[5])) * (m[10])) - (((m[2]) * (m[5])) * (m[8]))) + (((m[4]) * (m[9])) * (m[2]))) - (((m[6]) * (m[9])) * (m[0]))) + (((m[8]) * (m[1])) * (m[6]))) - (((m[10]) * (m[1])) * (m[4]));
+ return (det < 0.99) || (det > 1.01);
+}
+
+
+/* Analyze the matrix and return the appropriate flags */
+
+static sqInt analyzeMatrix(float *m) {
+    sqInt flags;
+
+ flags = 0;
+ if (((m[12]) == 0.0) && (((m[13]) == 0.0) && (((m[14]) == 0.0) && ((m[15]) == 1.0)))) {
+
+ /* Check translation */
+
+ flags = flags | FlagM44NoPerspective;
+ if (((m[3]) == 0.0) && (((m[7]) == 0.0) && ((m[11]) == 0.0))) {
+
+ /* Check for identity */
+
+ flags = flags | FlagM44NoTranslation;
+ if (((m[0]) == 1.0) && (((m[5]) == 1.0) && (((m[10]) == 1.0) && (((m[1]) == 0.0) && (((m[2]) == 0.0) && (((m[4]) == 0.0) && (((m[6]) == 0.0) && (((m[8]) == 0.0) && ((m[9]) == 0.0))))))))) {
+ flags = flags | FlagM44Identity;
+ }
+ }
+ }
+ return flags;
+}
+
+
+/* Primitive. Clip the polygon given in the vertexArray using the temporary vertex array which is assumed to have sufficient size. */
+
+EXPORT(sqInt) b3dClipPolygon(void) {
+    sqInt count;
+    sqInt outMask;
+    int *tempVtxArray;
+    int *vtxArray;
+    sqInt vtxCount;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 4)) {
+ return interpreterProxy->primitiveFail();
+ }
+ outMask = interpreterProxy->stackIntegerValue(0);
+ vtxCount = interpreterProxy->stackIntegerValue(2);
+ vtxArray = stackPrimitiveVertexArrayofSize(3, vtxCount + 4);
+ tempVtxArray = stackPrimitiveVertexArrayofSize(1, vtxCount + 4);
+ if ((vtxArray == null) || ((tempVtxArray == null) || (interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ vtxArray -= PrimVertexSize;
+ tempVtxArray -= PrimVertexSize;
+ count = clipPolygoncountwithmask(vtxArray, vtxCount, tempVtxArray, outMask);
+ interpreterProxy->pop(5);
+ interpreterProxy->pushInteger(count);
+}
+
+
+/* Primitive. Compute and return the index for the minimal z value of all objects in the vertex buffer. */
+
+EXPORT(sqInt) b3dComputeMinIndexZ(void) {
+    int *idxArray;
+    sqInt idxSize;
+    sqInt minIndex;
+    sqInt primType;
+    float *vtxArray;
+    sqInt vtxSize;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 5)) {
+ return interpreterProxy->primitiveFail();
+ }
+ idxSize = interpreterProxy->stackIntegerValue(0);
+ vtxSize = interpreterProxy->stackIntegerValue(2);
+ primType = interpreterProxy->stackIntegerValue(4);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ vtxArray = stackPrimitiveVertexArrayofSize(3, vtxSize);
+ idxArray = stackPrimitiveIndexArrayofSizevalidateforVertexSize(1, idxSize, 1, vtxSize);
+ if ((vtxArray == null) || ((idxArray == null) || (interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if ((primType < 1) || (primType > 6)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (primType <= 3) {
+ minIndex = processNonIndexedIDXofSize(vtxArray, vtxSize);
+ } else {
+ minIndex = processIndexedIDXofSizeidxArrayidxSize(vtxArray, vtxSize, idxArray, idxSize);
+ }
+ if (!(interpreterProxy->failed())) {
+ interpreterProxy->pop(6);
+ interpreterProxy->pushInteger(minIndex);
+ }
+}
+
+
+/* Primitive. Compute and return the minimal z value of all objects in the vertex buffer. */
+
+EXPORT(sqInt) b3dComputeMinZ(void) {
+    int *idxArray;
+    sqInt idxSize;
+    double minZ;
+    sqInt primType;
+    float *vtxArray;
+    sqInt vtxSize;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 5)) {
+ return interpreterProxy->primitiveFail();
+ }
+ idxSize = interpreterProxy->stackIntegerValue(0);
+ vtxSize = interpreterProxy->stackIntegerValue(2);
+ primType = interpreterProxy->stackIntegerValue(4);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ vtxArray = stackPrimitiveVertexArrayofSize(3, vtxSize);
+ idxArray = stackPrimitiveIndexArrayofSizevalidateforVertexSize(1, idxSize, 1, vtxSize);
+ if ((vtxArray == null) || ((idxArray == null) || (interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if ((primType < 1) || (primType > 6)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (primType <= 3) {
+ minZ = processNonIndexedofSize(vtxArray, vtxSize);
+ } else {
+ minZ = processIndexedofSizeidxArrayidxSize(vtxArray, vtxSize, idxArray, idxSize);
+ }
+ if (!(interpreterProxy->failed())) {
+ interpreterProxy->pop(6);
+ interpreterProxy->pushFloat(minZ);
+ }
+}
+
+
+/* Primitive. Determine the clipping flags for all vertices. */
+
+EXPORT(sqInt) b3dDetermineClipFlags(void) {
+    sqInt result;
+    void *vtxArray;
+    sqInt vtxCount;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 2)) {
+ return interpreterProxy->primitiveFail();
+ }
+ vtxCount = interpreterProxy->stackIntegerValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ vtxArray = stackPrimitiveVertexArrayofSize(1, vtxCount);
+ if ((vtxArray == null) || (interpreterProxy->failed())) {
+ return interpreterProxy->primitiveFail();
+ }
+ result = determineClipFlagscount(vtxArray, vtxCount);
+ if (!(interpreterProxy->failed())) {
+ interpreterProxy->pop(3);
+ interpreterProxy->pushInteger(result);
+ }
+}
+
+EXPORT(sqInt) b3dInitPrimitiveObject(void) {
+    int *idxArray;
+    sqInt idxSize;
+    void *primObj;
+    sqInt primOop;
+    sqInt primSize;
+    sqInt primitive;
+    sqInt textureIndex;
+    int *vtxArray;
+    sqInt vtxSize;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 8)) {
+ return interpreterProxy->primitiveFail();
+ }
+ textureIndex = interpreterProxy->stackIntegerValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ loadViewportFrom(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ vtxSize = interpreterProxy->stackIntegerValue(4);
+ vtxArray = stackPrimitiveVertexArrayofSize(5, vtxSize);
+ if (vtxArray == null) {
+ return interpreterProxy->primitiveFail();
+ }
+ idxSize = interpreterProxy->stackIntegerValue(2);
+ idxArray = stackPrimitiveIndexArrayofSizevalidateforVertexSize(3, idxSize, 1, vtxSize);
+ if (idxArray == null) {
+ return interpreterProxy->primitiveFail();
+ }
+ primitive = interpreterProxy->stackIntegerValue(6);
+ if ((primitive < 1) || (primitive > PrimTypeMax)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (!((primitive == 3) || ((primitive == 5) || (primitive == 6)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ primOop = interpreterProxy->stackObjectValue(7);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!(interpreterProxy->isWords(primOop))) {
+ return interpreterProxy->primitiveFail();
+ }
+ primObj = interpreterProxy->firstIndexableField(primOop);
+
+ /* Do the work */
+
+ primSize = interpreterProxy->byteSizeOf(primOop);
+ if (primitive == 3) {
+ if (b3dAddPolygonObject((void*) primObj, primSize, B3D_FACE_RGB, textureIndex, (B3DPrimitiveVertex*) vtxArray, vtxSize, &viewport) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ if (primitive == 5) {
+ if (b3dAddIndexedTriangleObject((void*) primObj, primSize, B3D_FACE_RGB, textureIndex, (B3DPrimitiveVertex*) vtxArray, vtxSize, (B3DInputFace*) idxArray, idxSize / 3, &viewport) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ if (primitive == 6) {
+ if (b3dAddIndexedQuadObject((void*) primObj, primSize, B3D_FACE_RGB, textureIndex, (B3DPrimitiveVertex*) vtxArray, vtxSize, (B3DInputQuad*) idxArray, idxSize / 4, &viewport) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ interpreterProxy->pop(9);
+ interpreterProxy->push(primOop);
+}
+
+
+/* Primitive. Initialize the primitive level objects of the given rasterizer. */
+
+EXPORT(sqInt) b3dInitializeRasterizerState(void) {
+    void *obj;
+    sqInt objLen;
+    sqInt objOop;
+    sqInt stateOop;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 0)) {
+ return interpreterProxy->primitiveFail();
+ }
+ stateOop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!((interpreterProxy->isPointers(stateOop)) && ((interpreterProxy->slotSizeOf(stateOop)) >= 7))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objOop = interpreterProxy->fetchPointerofObject(0, stateOop);
+ if (((objOop & 1)) || (!(interpreterProxy->isWords(objOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objLen = interpreterProxy->byteSizeOf(objOop);
+ obj = interpreterProxy->firstIndexableField(objOop);
+ if (b3dInitializeFaceAllocator(obj, objLen) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ objOop = interpreterProxy->fetchPointerofObject(1, stateOop);
+ if (((objOop & 1)) || (!(interpreterProxy->isWords(objOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objLen = interpreterProxy->byteSizeOf(objOop);
+ obj = interpreterProxy->firstIndexableField(objOop);
+ if (b3dInitializeEdgeAllocator(obj, objLen) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ objOop = interpreterProxy->fetchPointerofObject(2, stateOop);
+ if (((objOop & 1)) || (!(interpreterProxy->isWords(objOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objLen = interpreterProxy->byteSizeOf(objOop);
+ obj = interpreterProxy->firstIndexableField(objOop);
+ if (b3dInitializeAttrAllocator(obj, objLen) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ objOop = interpreterProxy->fetchPointerofObject(3, stateOop);
+ if (((objOop & 1)) || (!(interpreterProxy->isWords(objOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objLen = interpreterProxy->byteSizeOf(objOop);
+ obj = interpreterProxy->firstIndexableField(objOop);
+ if (b3dInitializeAET(obj, objLen) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ objOop = interpreterProxy->fetchPointerofObject(4, stateOop);
+ if (((objOop & 1)) || (!(interpreterProxy->isWords(objOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objLen = interpreterProxy->byteSizeOf(objOop);
+ obj = interpreterProxy->firstIndexableField(objOop);
+ if (b3dInitializeEdgeList(obj, objLen) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+ objOop = interpreterProxy->fetchPointerofObject(5, stateOop);
+ if (((objOop & 1)) || (!(interpreterProxy->isWords(objOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objLen = interpreterProxy->byteSizeOf(objOop);
+ obj = interpreterProxy->firstIndexableField(objOop);
+ if (b3dInitializeFillList(obj, objLen) != B3D_NO_ERROR) {
+ return interpreterProxy->primitiveFail();
+ }
+}
+
+
+/* Primitive. Perform an inplace house holder matrix inversion */
+
+EXPORT(sqInt) b3dInplaceHouseHolderInvert(void) {
+    double beta;
+    double d[4][4];
+    sqInt i;
+    sqInt j;
+    sqInt k;
+    double m[4][4];
+    sqInt r;
+    float *rcvr;
+    double s;
+    double sigma;
+    double sum;
+    double x[4][4] = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1} };
+
+ ;
+ rcvr = stackMatrix(0);
+ for (i = 0; i <= 3; i += 1) {
+ for (j = 0; j <= 3; j += 1) {
+ (m[i])[j] = (rcvr[(i * 4) + j]);
+ }
+ }
+ for (j = 0; j <= 3; j += 1) {
+ sigma = 0.0;
+ for (i = j; i <= 3; i += 1) {
+ sigma += ((m[i])[j]) * ((m[i])[j]);
+ }
+ if (sigma < 1.0e-10) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (((m[j])[j]) < 0.0) {
+ s = sqrt(sigma);
+ } else {
+ s = 0.0 - (sqrt(sigma));
+ }
+ for (r = 0; r <= 3; r += 1) {
+ (d[j])[r] = s;
+ }
+ beta = 1.0 / ((s * ((m[j])[j])) - sigma);
+ (m[j])[j] = (((m[j])[j]) - s);
+ for (k = (j + 1); k <= 3; k += 1) {
+ sum = 0.0;
+ for (i = j; i <= 3; i += 1) {
+ sum += ((m[i])[j]) * ((m[i])[k]);
+ }
+ sum = sum * beta;
+ for (i = j; i <= 3; i += 1) {
+ (m[i])[k] = (((m[i])[k]) + (((m[i])[j]) * sum));
+ }
+ }
+ for (r = 0; r <= 3; r += 1) {
+ sum = 0.0;
+ for (i = j; i <= 3; i += 1) {
+ sum += ((x[i])[r]) * ((m[i])[j]);
+ }
+ sum = sum * beta;
+ for (i = j; i <= 3; i += 1) {
+ (x[i])[r] = (((x[i])[r]) + (sum * ((m[i])[j])));
+ }
+ }
+ }
+ for (r = 0; r <= 3; r += 1) {
+ for (i = 3; i >= 0; i += -1) {
+ for (j = (i + 1); j <= 3; j += 1) {
+ (x[i])[r] = (((x[i])[r]) - (((x[j])[r]) * ((m[i])[j])));
+ }
+ (x[i])[r] = (((x[i])[r]) / ((d[i])[r]));
+ }
+ }
+ for (i = 0; i <= 3; i += 1) {
+ for (j = 0; j <= 3; j += 1) {
+ rcvr[(i * 4) + j] = (((float) ((x[i])[j])));
+ }
+ }
+}
+
+
+/* Primitive. Load the given index array into the receiver.
+ NOTE: dstStart is a zero-based index. */
+
+EXPORT(sqInt) b3dLoadIndexArray(void) {
+    sqInt count;
+    sqInt dstArray;
+    int *dstPtr;
+    sqInt dstSize;
+    sqInt dstStart;
+    sqInt i;
+    sqInt idx;
+    sqInt maxValue;
+    sqInt srcArray;
+    int *srcPtr;
+    sqInt vtxOffset;
+
+ vtxOffset = interpreterProxy->stackIntegerValue(0);
+ maxValue = interpreterProxy->stackIntegerValue(1);
+ count = interpreterProxy->stackIntegerValue(2);
+ srcArray = interpreterProxy->stackObjectValue(3);
+ dstStart = interpreterProxy->stackIntegerValue(4);
+ dstArray = interpreterProxy->stackObjectValue(5);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!(interpreterProxy->isWords(srcArray))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if ((interpreterProxy->slotSizeOf(srcArray)) < count) {
+ return interpreterProxy->primitiveFail();
+ }
+
+ /* Check dstArray */
+
+ srcPtr = ((int*) (interpreterProxy->firstIndexableField(srcArray)));
+
+ /* Check if there is enough room left in dstArray */
+
+ dstSize = interpreterProxy->slotSizeOf(dstArray);
+ if ((dstStart + count) > dstSize) {
+ return interpreterProxy->primitiveFail();
+ }
+
+ /* Do the actual work */
+
+ dstPtr = ((int *) (interpreterProxy->firstIndexableField(dstArray)));
+ for (i = 0; i <= (count - 1); i += 1) {
+ idx = srcPtr[i];
+ if ((idx < 1) || (idx > maxValue)) {
+ return interpreterProxy->primitiveFail();
+ }
+ dstPtr[dstStart + i] = (idx + vtxOffset);
+ }
+ interpreterProxy->pop(7);
+ interpreterProxy->pushInteger(count);
+}
+
+
+/* Primitive. Load the data into the given vertex buffer.
+ NOTE: dstStart is a zero-based index. */
+
+EXPORT(sqInt) b3dLoadVertexBuffer(void) {
+    int *colorPtr;
+    sqInt count;
+    int *defaultColor;
+    int *defaultNormal;
+    int *defaultTexCoords;
+    int *defaultVtx;
+    int *dstPtr;
+    sqInt dstStart;
+    sqInt i;
+    int *normalPtr;
+    int *pVtx;
+    int *texPtr;
+    int *vtxPtr;
+
+ defaultVtx = stackPrimitiveVertex(0);
+ count = interpreterProxy->stackIntegerValue(1);
+ texPtr = vbLoadArraysize(interpreterProxy->stackObjectValue(2), 2 * count);
+ colorPtr = vbLoadArraysize(interpreterProxy->stackObjectValue(3), count);
+ normalPtr = vbLoadArraysize(interpreterProxy->stackObjectValue(4), 3 * count);
+ vtxPtr = vbLoadArraysize(interpreterProxy->stackObjectValue(5), 3 * count);
+ dstStart = interpreterProxy->stackIntegerValue(6);
+
+ /* Check for all problems above */
+
+ dstPtr = stackPrimitiveVertexArrayofSize(7, dstStart + count);
+ if ((dstPtr == null) || ((defaultVtx == null) || (interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (normalPtr == null) {
+ defaultNormal = defaultVtx + PrimVtxNormal;
+ } else {
+ defaultNormal = normalPtr;
+ }
+ if (texPtr == null) {
+ defaultTexCoords = defaultVtx + PrimVtxTexCoords;
+ } else {
+ defaultTexCoords = texPtr;
+ }
+ if (colorPtr == null) {
+ defaultColor = defaultVtx + PrimVtxColor32;
+ } else {
+ defaultColor = colorPtr;
+ }
+ pVtx = dstPtr + (dstStart * PrimVertexSize);
+ for (i = 0; i <= (count - 1); i += 1) {
+ pVtx[PrimVtxPositionX] = (vtxPtr[0]);
+ pVtx[PrimVtxPositionY] = (vtxPtr[1]);
+ pVtx[PrimVtxPositionZ] = (vtxPtr[2]);
+ pVtx[PrimVtxNormalX] = (defaultNormal[0]);
+ pVtx[PrimVtxNormalY] = (defaultNormal[1]);
+ pVtx[PrimVtxNormalZ] = (defaultNormal[2]);
+ pVtx[PrimVtxColor32] = (defaultColor[0]);
+ pVtx[PrimVtxTexCoordU] = (defaultTexCoords[0]);
+ pVtx[PrimVtxTexCoordV] = (defaultTexCoords[1]);
+ pVtx += PrimVertexSize;
+ vtxPtr += 3;
+ if (!(normalPtr == null)) {
+ defaultNormal += 3;
+ }
+ if (!(colorPtr == null)) {
+ defaultColor += 1;
+ }
+ if (!(texPtr == null)) {
+ defaultTexCoords += 2;
+ }
+ }
+ interpreterProxy->pop(9);
+ interpreterProxy->pushInteger(count);
+}
+
+
+/* Primitive. Determine the bounds for all vertices in the vertex buffer. */
+
+EXPORT(sqInt) b3dMapVertexBuffer(void) {
+    sqInt boxArray;
+    void *vtxArray;
+    sqInt vtxCount;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 3)) {
+ return interpreterProxy->primitiveFail();
+ }
+ boxArray = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!(((interpreterProxy->fetchClassOf(boxArray)) == (interpreterProxy->classArray())) && ((interpreterProxy->slotSizeOf(boxArray)) == 4))) {
+ return interpreterProxy->primitiveFail();
+ }
+ vtxCount = interpreterProxy->stackIntegerValue(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ vtxArray = stackPrimitiveVertexArrayofSize(2, vtxCount);
+ if ((vtxArray == null) || (interpreterProxy->failed())) {
+ return interpreterProxy->primitiveFail();
+ }
+ mapVBofSizeinto(vtxArray, vtxCount, boxArray);
+ if (!(interpreterProxy->failed())) {
+ interpreterProxy->pop(3);
+ }
+}
+
+EXPORT(sqInt) b3dOrthoNormInverseMatrix(void) {
+    float *dst;
+    sqInt dstOop;
+    double rx;
+    double ry;
+    double rz;
+    float *src;
+    sqInt srcOop;
+    double x;
+    double y;
+    double z;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 0)) {
+ return interpreterProxy->primitiveFail();
+ }
+ srcOop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!((interpreterProxy->isWords(srcOop)) && ((interpreterProxy->slotSizeOf(srcOop)) == 16))) {
+ return interpreterProxy->primitiveFail();
+ }
+
+ /* reload srcOop in case of GC */
+
+ dstOop = interpreterProxy->clone(srcOop);
+ srcOop = interpreterProxy->stackObjectValue(0);
+ src = interpreterProxy->firstIndexableField(srcOop);
+
+ /* Transpose upper 3x3 matrix */
+ /* dst at: 0 put: (src at: 0). */
+
+ dst = interpreterProxy->firstIndexableField(dstOop);
+ dst[1] = (src[4]);
+ dst[2] = (src[8]);
+ dst[4] = (src[1]);
+ dst[6] = (src[9]);
+ dst[8] = (src[2]);
+ dst[9] = (src[6]);
+ x = src[3];
+ y = src[7];
+ z = src[11];
+ rx = ((x * (dst[0])) + (y * (dst[1]))) + (z * (dst[2]));
+ ry = ((x * (dst[4])) + (y * (dst[5]))) + (z * (dst[6]));
+ rz = ((x * (dst[8])) + (y * (dst[9]))) + (z * (dst[10]));
+ dst[3] = (((float) (0.0 - rx)));
+ dst[7] = (((float) (0.0 - ry)));
+ dst[11] = (((float) (0.0 - rz)));
+ interpreterProxy->pop(1);
+ interpreterProxy->push(dstOop);
+}
+
+
+/* Primitive. Return the next clipped triangle from the vertex buffer and return its index. */
+
+EXPORT(sqInt) b3dPrimitiveNextClippedTriangle(void) {
+    sqInt firstIndex;
+    sqInt i;
+    sqInt idx1;
+    sqInt idx2;
+    sqInt idx3;
+    int *idxArray;
+    sqInt idxCount;
+    sqInt triMask;
+    int *vtxArray;
+    sqInt vtxCount;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 5)) {
+ return interpreterProxy->primitiveFail();
+ }
+ idxCount = interpreterProxy->stackIntegerValue(0);
+ vtxCount = interpreterProxy->stackIntegerValue(2);
+ firstIndex = interpreterProxy->stackIntegerValue(4);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ vtxArray = stackPrimitiveVertexArrayofSize(3, vtxCount);
+ idxArray = stackPrimitiveIndexArrayofSizevalidateforVertexSize(1, idxCount, 1, vtxCount);
+ if ((vtxArray == null) || ((idxArray == null) || (interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ idxArray -= 1;
+ vtxArray -= PrimVertexSize;
+ for (i = firstIndex; i <= idxCount; i += 3) {
+ idx1 = idxArray[i];
+ idx2 = idxArray[i + 1];
+ idx3 = idxArray[i + 2];
+ if (!((idx1 == 0) || ((idx2 == 0) || (idx3 == 0)))) {
+
+ /* Check if tri is completely inside */
+
+ triMask = (vtxArray[(idx1 * PrimVertexSize) + PrimVtxClipFlags]) & ((vtxArray[(idx2 * PrimVertexSize) + PrimVtxClipFlags]) & (vtxArray[(idx3 * PrimVertexSize) + PrimVtxClipFlags]));
+ if (!((InAllMask & triMask) == InAllMask)) {
+ if (triMask & OutAllMask) {
+ idxArray[i] = 0;
+ idxArray[i + 1] = 0;
+ idxArray[i + 2] = 0;
+ } else {
+ interpreterProxy->pop(6);
+ interpreterProxy->pushInteger(i);
+ return null;
+ }
+ }
+ }
+ }
+ interpreterProxy->pop(6);
+ interpreterProxy->pushInteger(0);
+}
+
+
+/* Primitive. Return the minimal number of words needed for a primitive object. */
+
+EXPORT(sqInt) b3dPrimitiveObjectSize(void) {
+    sqInt objSize;
+
+ objSize = (((sqInt) (sizeof(B3DPrimitiveObject) + sizeof(B3DPrimitiveVertex)) >> 2)) + 1;
+ interpreterProxy->pop(1);
+ interpreterProxy->pushInteger(objSize);
+}
+
+
+/* Primitive. Return the minimal number of words needed for a primitive object. */
+
+EXPORT(sqInt) b3dPrimitiveTextureSize(void) {
+    sqInt objSize;
+
+ objSize = (((sqInt) (sizeof(B3DTexture)) >> 2)) + 1;
+ interpreterProxy->pop(1);
+ interpreterProxy->pushInteger(objSize);
+}
+
+
+/* Primitive. Return the version of the rasterizer. */
+
+EXPORT(sqInt) b3dRasterizerVersion(void) {
+ interpreterProxy->pop(1);
+ interpreterProxy->pushInteger(1);
+}
+
+
+/* Primitive. Shade all the vertices in the vertex buffer using the given array of primitive light sources. Return true on success. */
+
+EXPORT(sqInt) b3dShadeVertexBuffer(void) {
+    sqInt i;
+    sqInt j;
+    sqInt lightArray;
+    sqInt lightCount;
+    float *vtxArray;
+    sqInt vtxCount;
+    sqInt lightOop;
+    sqInt rgba;
+    sqInt a;
+    sqInt b;
+    sqInt g;
+    sqInt r;
+
+ vbFlags = interpreterProxy->stackIntegerValue(0);
+ primMaterial = stackMaterialValue(1);
+ lightArray = stackLightArrayValue(2);
+ vtxCount = interpreterProxy->stackIntegerValue(3);
+ vtxArray = stackPrimitiveVertexArrayofSize(4, vtxCount);
+ if ((vtxArray == null) || ((primMaterial == null) || (interpreterProxy->failed()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ litVertex = vtxArray;
+
+ /* Go over all vertices */
+
+ lightCount = interpreterProxy->slotSizeOf(lightArray);
+ for (i = 1; i <= vtxCount; i += 1) {
+ /* begin loadPrimitiveVertex */
+ rgba = (((int*) litVertex))[PrimVtxColor32];
+ vtxInColor[2] = ((rgba & 255) * (1.0 / 255.0));
+ rgba = ((usqInt) rgba) >> 8;
+ vtxInColor[1] = ((rgba & 255) * (1.0 / 255.0));
+ rgba = ((usqInt) rgba) >> 8;
+ vtxInColor[0] = ((rgba & 255) * (1.0 / 255.0));
+ rgba = ((usqInt) rgba) >> 8;
+ vtxInColor[3] = ((rgba & 255) * (1.0 / 255.0));
+ if (vbFlags & VBTrackEmission) {
+ vtxOutColor[0] = ((vtxInColor[0]) + (primMaterial[EmissionRed]));
+ vtxOutColor[1] = ((vtxInColor[1]) + (primMaterial[EmissionGreen]));
+ vtxOutColor[2] = ((vtxInColor[2]) + (primMaterial[EmissionBlue]));
+ vtxOutColor[3] = ((vtxInColor[3]) + (primMaterial[EmissionAlpha]));
+ } else {
+ vtxOutColor[0] = (primMaterial[EmissionRed]);
+ vtxOutColor[1] = (primMaterial[EmissionGreen]);
+ vtxOutColor[2] = (primMaterial[EmissionBlue]);
+ vtxOutColor[3] = (primMaterial[EmissionAlpha]);
+ }
+ for (j = 0; j <= (lightCount - 1); j += 1) {
+ /* begin fetchLightSource:ofObject: */
+ lightOop = interpreterProxy->fetchPointerofObject(j, lightArray);
+ primLight = interpreterProxy->firstIndexableField(lightOop);
+ /* begin loadPrimitiveLightSource */
+ lightFlags = (((int*) primLight))[PrimLightFlags];
+ shadeVertex();
+ }
+ /* begin storePrimitiveVertex */
+ r = ((sqInt)((vtxOutColor[0]) * 255));
+ r = (((((r < 255) ? r : 255)) < 0) ? 0 : (((r < 255) ? r : 255)));
+ g = ((sqInt)((vtxOutColor[1]) * 255));
+ g = (((((g < 255) ? g : 255)) < 0) ? 0 : (((g < 255) ? g : 255)));
+ b = ((sqInt)((vtxOutColor[2]) * 255));
+ b = (((((b < 255) ? b : 255)) < 0) ? 0 : (((b < 255) ? b : 255)));
+ a = ((sqInt)((vtxOutColor[3]) * 255));
+ a = (((((a < 255) ? a : 255)) < 0) ? 0 : (((a < 255) ? a : 255)));
+ (((int*) litVertex))[PrimVtxColor32] = (b + ((g + ((r + (a << 8)) << 8)) << 8));
+ litVertex += PrimVertexSize;
+ }
+ interpreterProxy->pop(6);
+ interpreterProxy->pushBool(1);
+}
+
+
+/* Return the current shader version. */
+
+EXPORT(sqInt) b3dShaderVersion(void) {
+ interpreterProxy->pop(1);
+ interpreterProxy->pushInteger(1);
+}
+
+
+/* Primitive. Start the rasterizer. */
+
+EXPORT(sqInt) b3dStartRasterizer(void) {
+    sqInt errCode;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 3)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (!(loadRasterizerState(2))) {
+ return interpreterProxy->primitiveFail();
+ }
+ loadTexturesFrom(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ loadObjectsFrom(1);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ errCode = b3dMainLoop(&state, B3D_NO_ERROR);
+ storeObjectsInto(1);
+ interpreterProxy->pop(4);
+ interpreterProxy->pushInteger(errCode);
+}
+
+EXPORT(sqInt) b3dTransformDirection(void) {
+    float *matrix;
+    double rx;
+    double ry;
+    double rz;
+    sqInt v3Oop;
+    float *vertex;
+    double x;
+    double y;
+    double z;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 1)) {
+ return interpreterProxy->primitiveFail();
+ }
+ v3Oop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!((interpreterProxy->isWords(v3Oop)) && ((interpreterProxy->slotSizeOf(v3Oop)) == 3))) {
+ return interpreterProxy->primitiveFail();
+ }
+ vertex = interpreterProxy->firstIndexableField(v3Oop);
+ matrix = stackMatrix(1);
+ if (matrix == null) {
+ return interpreterProxy->primitiveFail();
+ }
+ x = vertex[0];
+ y = vertex[1];
+ z = vertex[2];
+ rx = ((x * (matrix[0])) + (y * (matrix[1]))) + (z * (matrix[2]));
+ ry = ((x * (matrix[4])) + (y * (matrix[5]))) + (z * (matrix[6]));
+ rz = ((x * (matrix[8])) + (y * (matrix[9]))) + (z * (matrix[10]));
+ v3Oop = interpreterProxy->clone(v3Oop);
+ vertex = interpreterProxy->firstIndexableField(v3Oop);
+ vertex[0] = (((float) rx));
+ vertex[1] = (((float) ry));
+ vertex[2] = (((float) rz));
+ interpreterProxy->pop(2);
+ interpreterProxy->push(v3Oop);
+}
+
+
+/* Transform two matrices into the third */
+
+EXPORT(sqInt) b3dTransformMatrixWithInto(void) {
+    float *m1;
+    float *m2;
+    float *m3;
+
+ m3 = stackMatrix(0);
+ m2 = stackMatrix(1);
+ m1 = stackMatrix(2);
+ if (((m1 == null) || (m2 == null)) || (m3 == null)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (m2 == m3) {
+ return interpreterProxy->primitiveFail();
+ }
+ transformMatrixwithinto(m1, m2, m3);
+ interpreterProxy->pop(3);
+}
+
+EXPORT(sqInt) b3dTransformPoint(void) {
+    float *matrix;
+    double rw;
+    double rx;
+    double ry;
+    double rz;
+    sqInt v3Oop;
+    float *vertex;
+    double x;
+    double y;
+    double z;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 1)) {
+ return interpreterProxy->primitiveFail();
+ }
+ v3Oop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!((interpreterProxy->isWords(v3Oop)) && ((interpreterProxy->slotSizeOf(v3Oop)) == 3))) {
+ return interpreterProxy->primitiveFail();
+ }
+ vertex = interpreterProxy->firstIndexableField(v3Oop);
+ matrix = stackMatrix(1);
+ if (matrix == null) {
+ return interpreterProxy->primitiveFail();
+ }
+ x = vertex[0];
+ y = vertex[1];
+ z = vertex[2];
+ rx = (((x * (matrix[0])) + (y * (matrix[1]))) + (z * (matrix[2]))) + (matrix[3]);
+ ry = (((x * (matrix[4])) + (y * (matrix[5]))) + (z * (matrix[6]))) + (matrix[7]);
+ rz = (((x * (matrix[8])) + (y * (matrix[9]))) + (z * (matrix[10]))) + (matrix[11]);
+ rw = (((x * (matrix[12])) + (y * (matrix[13]))) + (z * (matrix[14]))) + (matrix[15]);
+ v3Oop = interpreterProxy->clone(v3Oop);
+ vertex = interpreterProxy->firstIndexableField(v3Oop);
+ if (rw == 1.0) {
+ vertex[0] = (((float) rx));
+ vertex[1] = (((float) ry));
+ vertex[2] = (((float) rz));
+ } else {
+ if (rw == 0.0) {
+ rw = 0.0;
+ } else {
+ rw = 1.0 / rw;
+ }
+ vertex[0] = (((float) (rx * rw)));
+ vertex[1] = (((float) (ry * rw)));
+ vertex[2] = (((float) (rz * rw)));
+ }
+ interpreterProxy->pop(2);
+ interpreterProxy->push(v3Oop);
+}
+
+
+/* Transform the normal of the given primitive vertex using the argument matrix and rescale the normal if necessary. */
+
+EXPORT(sqInt) b3dTransformPrimitiveNormal(void) {
+    float *matrix;
+    float *pVertex;
+    sqInt rescale;
+
+ rescale = interpreterProxy->stackValue(0);
+ if (!(rescale == (interpreterProxy->nilObject()))) {
+ rescale = interpreterProxy->booleanValueOf(rescale);
+ }
+ matrix = stackMatrix(1);
+ pVertex = stackPrimitiveVertex(2);
+ if ((matrix == null) || (pVertex == null)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if ((rescale != 1) && (rescale != 0)) {
+ rescale = analyzeMatrix3x3Length(matrix);
+ }
+ transformPrimitiveNormalbyrescale(pVertex, matrix, rescale);
+ interpreterProxy->pop(3);
+}
+
+
+/* Transform the position of the given primitive vertex the given matrix
+ and store the result back inplace. */
+
+EXPORT(sqInt) b3dTransformPrimitivePosition(void) {
+    float *matrix;
+    float *pVertex;
+
+ matrix = stackMatrix(0);
+ pVertex = stackPrimitiveVertex(1);
+ if ((matrix == null) || (pVertex == null)) {
+ return interpreterProxy->primitiveFail();
+ }
+ transformPrimitivePositionby(pVertex, matrix);
+ interpreterProxy->pop(2);
+}
+
+
+/* Transform the position of the given primitive vertex the given matrix
+ and store the result in homogenous coordinates at rasterPos. */
+
+EXPORT(sqInt) b3dTransformPrimitiveRasterPosition(void) {
+    float *matrix;
+    float *pVertex;
+
+ matrix = stackMatrix(0);
+ pVertex = stackPrimitiveVertex(1);
+ if ((matrix == null) || (pVertex == null)) {
+ return interpreterProxy->primitiveFail();
+ }
+ transformPrimitiveRasterPositionby(pVertex, matrix);
+ interpreterProxy->pop(2);
+}
+
+
+/* Transform an entire vertex buffer using the supplied modelview and projection matrix. */
+
+EXPORT(sqInt) b3dTransformVertexBuffer(void) {
+    sqInt flags;
+    float *modelViewMatrix;
+    float *projectionMatrix;
+    float *vtxArray;
+    sqInt vtxCount;
+
+ flags = interpreterProxy->stackIntegerValue(0);
+ projectionMatrix = stackMatrix(1);
+ modelViewMatrix = stackMatrix(2);
+ vtxCount = interpreterProxy->stackIntegerValue(3);
+ vtxArray = stackPrimitiveVertexArrayofSize(4, vtxCount);
+ if (((projectionMatrix == null) || (modelViewMatrix == null)) || (vtxArray == null)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ transformVBcountbyandflags(vtxArray, vtxCount, modelViewMatrix, projectionMatrix, flags);
+ interpreterProxy->pop(5);
+}
+
+
+/* Return the current version of the transformer */
+
+EXPORT(sqInt) b3dTransformerVersion(void) {
+ interpreterProxy->pop(1);
+ interpreterProxy->pushInteger(1);
+}
+
+EXPORT(sqInt) b3dTransposeMatrix(void) {
+    float *dst;
+    sqInt dstOop;
+    float *src;
+    sqInt srcOop;
+
+ if (!((interpreterProxy->methodArgumentCount()) == 0)) {
+ return interpreterProxy->primitiveFail();
+ }
+ srcOop = interpreterProxy->stackObjectValue(0);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!((interpreterProxy->isWords(srcOop)) && ((interpreterProxy->slotSizeOf(srcOop)) == 16))) {
+ return interpreterProxy->primitiveFail();
+ }
+
+ /* reload srcOop in case of GC */
+
+ dstOop = interpreterProxy->clone(srcOop);
+ srcOop = interpreterProxy->stackObjectValue(0);
+ src = interpreterProxy->firstIndexableField(srcOop);
+
+ /* dst at: 0 put: (src at: 0). */
+
+ dst = interpreterProxy->firstIndexableField(dstOop);
+ dst[1] = (src[4]);
+ dst[2] = (src[8]);
+ dst[3] = (src[12]);
+ dst[4] = (src[1]);
+ dst[6] = (src[9]);
+ dst[7] = (src[13]);
+ dst[8] = (src[2]);
+ dst[9] = (src[6]);
+ dst[11] = (src[14]);
+ dst[12] = (src[3]);
+ dst[13] = (src[7]);
+ dst[14] = (src[11]);
+ interpreterProxy->pop(1);
+ interpreterProxy->push(dstOop);
+}
+
+static double backClipValueFromto(sqInt last, sqInt next) {
+ return (((((float *) last))[PrimVtxRasterPosZ]) - ((((float *) last))[PrimVtxRasterPosW])) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) - (((((float *) next))[PrimVtxRasterPosZ]) - ((((float *) last))[PrimVtxRasterPosZ])));
+}
+
+static double bottomClipValueFromto(sqInt last, sqInt next) {
+ return (0.0 - (((((float *) last))[PrimVtxRasterPosY]) + ((((float *) last))[PrimVtxRasterPosW]))) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) + (((((float *) next))[PrimVtxRasterPosY]) - ((((float *) last))[PrimVtxRasterPosY])));
+}
+
+static sqInt clipPolygoncountwithmask(int *vtxArray, sqInt vtxCount, int *tempVtxArray, sqInt outMask) {
+    sqInt count;
+
+ if (outMask == OutLeftBit) {
+ return clipPolygonLeftFromtocount(tempVtxArray, vtxArray, vtxCount);
+ }
+ if (outMask == OutRightBit) {
+ return clipPolygonRightFromtocount(tempVtxArray, vtxArray, vtxCount);
+ }
+ if (outMask == OutTopBit) {
+ return clipPolygonTopFromtocount(tempVtxArray, vtxArray, vtxCount);
+ }
+ if (outMask == OutBottomBit) {
+ return clipPolygonBottomFromtocount(tempVtxArray, vtxArray, vtxCount);
+ }
+ if (outMask == OutFrontBit) {
+ return clipPolygonFrontFromtocount(tempVtxArray, vtxArray, vtxCount);
+ }
+ if (outMask == OutBackBit) {
+ return clipPolygonBackFromtocount(tempVtxArray, vtxArray, vtxCount);
+ }
+ count = vtxCount;
+ count = clipPolygonLeftFromtocount(vtxArray, tempVtxArray, count);
+ if (count == 0) {
+ return 0;
+ }
+ count = clipPolygonRightFromtocount(tempVtxArray, vtxArray, count);
+ if (count == 0) {
+ return 0;
+ }
+ count = clipPolygonTopFromtocount(vtxArray, tempVtxArray, count);
+ if (count == 0) {
+ return 0;
+ }
+ count = clipPolygonBottomFromtocount(tempVtxArray, vtxArray, count);
+ if (count == 0) {
+ return 0;
+ }
+ count = clipPolygonFrontFromtocount(vtxArray, tempVtxArray, count);
+ if (count == 0) {
+ return 0;
+ }
+ count = clipPolygonBackFromtocount(tempVtxArray, vtxArray, count);
+ return count;
+}
+
+static sqInt clipPolygonBackFromtocount(int *buf1, int *buf2, sqInt n) {
+    sqInt i;
+    sqInt inLast;
+    sqInt inNext;
+    sqInt j;
+    int *last;
+    int *next;
+    sqInt outIndex;
+    double t;
+
+ outIndex = 0;
+ last = buf1 + (n * PrimVertexSize);
+ next = buf1 + PrimVertexSize;
+ inLast = (last[PrimVtxClipFlags]) & InBackBit;
+ for (i = 1; i <= n; i += 1) {
+ inNext = (next[PrimVtxClipFlags]) & InBackBit;
+ if (!(inLast == inNext)) {
+
+ /* Passes clip boundary */
+
+ t = (((((float *) last))[PrimVtxRasterPosZ]) - ((((float *) last))[PrimVtxRasterPosW])) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) - (((((float *) next))[PrimVtxRasterPosZ]) - ((((float *) last))[PrimVtxRasterPosZ])));
+ outIndex += 1;
+ interpolateFromtoatinto(((float *) last), ((float *) next), t, ((float*) (buf2 + (outIndex * PrimVertexSize))));
+ }
+ if (inNext) {
+ outIndex += 1;
+ for (j = 0; j <= (PrimVertexSize - 1); j += 1) {
+ buf2[(outIndex * PrimVertexSize) + j] = (next[j]);
+ }
+ }
+ last = next;
+ inLast = inNext;
+ next += PrimVertexSize;
+ }
+ return outIndex;
+}
+
+static sqInt clipPolygonBottomFromtocount(int *buf1, int *buf2, sqInt n) {
+    sqInt i;
+    sqInt inLast;
+    sqInt inNext;
+    sqInt j;
+    int *last;
+    int *next;
+    sqInt outIndex;
+    double t;
+
+ outIndex = 0;
+ last = buf1 + (n * PrimVertexSize);
+ next = buf1 + PrimVertexSize;
+ inLast = (last[PrimVtxClipFlags]) & InBottomBit;
+ for (i = 1; i <= n; i += 1) {
+ inNext = (next[PrimVtxClipFlags]) & InBottomBit;
+ if (!(inLast == inNext)) {
+
+ /* Passes clip boundary */
+
+ t = (0.0 - (((((float *) last))[PrimVtxRasterPosY]) + ((((float *) last))[PrimVtxRasterPosW]))) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) + (((((float *) next))[PrimVtxRasterPosY]) - ((((float *) last))[PrimVtxRasterPosY])));
+ outIndex += 1;
+ interpolateFromtoatinto(((float *) last), ((float *) next), t, ((float*) (buf2 + (outIndex * PrimVertexSize))));
+ }
+ if (inNext) {
+ outIndex += 1;
+ for (j = 0; j <= (PrimVertexSize - 1); j += 1) {
+ buf2[(outIndex * PrimVertexSize) + j] = (next[j]);
+ }
+ }
+ last = next;
+ inLast = inNext;
+ next += PrimVertexSize;
+ }
+ return outIndex;
+}
+
+static sqInt clipPolygonFrontFromtocount(int *buf1, int *buf2, sqInt n) {
+    sqInt i;
+    sqInt inLast;
+    sqInt inNext;
+    sqInt j;
+    int *last;
+    int *next;
+    sqInt outIndex;
+    double t;
+
+ outIndex = 0;
+ last = buf1 + (n * PrimVertexSize);
+ next = buf1 + PrimVertexSize;
+ inLast = (last[PrimVtxClipFlags]) & InFrontBit;
+ for (i = 1; i <= n; i += 1) {
+ inNext = (next[PrimVtxClipFlags]) & InFrontBit;
+ if (!(inLast == inNext)) {
+
+ /* Passes clip boundary */
+
+ t = (0.0 - (((((float *) last))[PrimVtxRasterPosZ]) + ((((float *) last))[PrimVtxRasterPosW]))) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) + (((((float *) next))[PrimVtxRasterPosZ]) - ((((float *) last))[PrimVtxRasterPosZ])));
+ outIndex += 1;
+ interpolateFromtoatinto(((float *) last), ((float *) next), t, ((float*) (buf2 + (outIndex * PrimVertexSize))));
+ }
+ if (inNext) {
+ outIndex += 1;
+ for (j = 0; j <= (PrimVertexSize - 1); j += 1) {
+ buf2[(outIndex * PrimVertexSize) + j] = (next[j]);
+ }
+ }
+ last = next;
+ inLast = inNext;
+ next += PrimVertexSize;
+ }
+ return outIndex;
+}
+
+static sqInt clipPolygonLeftFromtocount(int *buf1, int *buf2, sqInt n) {
+    sqInt i;
+    sqInt inLast;
+    sqInt inNext;
+    sqInt j;
+    int *last;
+    int *next;
+    sqInt outIndex;
+    double t;
+
+ outIndex = 0;
+ last = buf1 + (n * PrimVertexSize);
+ next = buf1 + PrimVertexSize;
+ inLast = (last[PrimVtxClipFlags]) & InLeftBit;
+ for (i = 1; i <= n; i += 1) {
+ inNext = (next[PrimVtxClipFlags]) & InLeftBit;
+ if (!(inLast == inNext)) {
+
+ /* Passes clip boundary */
+
+ t = (0.0 - (((((float *) last))[PrimVtxRasterPosX]) + ((((float *) last))[PrimVtxRasterPosW]))) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) + (((((float *) next))[PrimVtxRasterPosX]) - ((((float *) last))[PrimVtxRasterPosX])));
+ outIndex += 1;
+ interpolateFromtoatinto(((float *) last), ((float *) next), t, ((float*) (buf2 + (outIndex * PrimVertexSize))));
+ }
+ if (inNext) {
+ outIndex += 1;
+ for (j = 0; j <= (PrimVertexSize - 1); j += 1) {
+ buf2[(outIndex * PrimVertexSize) + j] = (next[j]);
+ }
+ }
+ last = next;
+ inLast = inNext;
+ next += PrimVertexSize;
+ }
+ return outIndex;
+}
+
+static sqInt clipPolygonRightFromtocount(int *buf1, int *buf2, sqInt n) {
+    sqInt i;
+    sqInt inLast;
+    sqInt inNext;
+    sqInt j;
+    int *last;
+    int *next;
+    sqInt outIndex;
+    double t;
+
+ outIndex = 0;
+ last = buf1 + (n * PrimVertexSize);
+ next = buf1 + PrimVertexSize;
+ inLast = (last[PrimVtxClipFlags]) & InRightBit;
+ for (i = 1; i <= n; i += 1) {
+ inNext = (next[PrimVtxClipFlags]) & InRightBit;
+ if (!(inLast == inNext)) {
+
+ /* Passes clip boundary */
+
+ t = (((((float *) last))[PrimVtxRasterPosX]) - ((((float *) last))[PrimVtxRasterPosW])) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) - (((((float *) next))[PrimVtxRasterPosX]) - ((((float *) last))[PrimVtxRasterPosX])));
+ outIndex += 1;
+ interpolateFromtoatinto(((float *) last), ((float *) next), t, ((float*) (buf2 + (outIndex * PrimVertexSize))));
+ }
+ if (inNext) {
+ outIndex += 1;
+ for (j = 0; j <= (PrimVertexSize - 1); j += 1) {
+ buf2[(outIndex * PrimVertexSize) + j] = (next[j]);
+ }
+ }
+ last = next;
+ inLast = inNext;
+ next += PrimVertexSize;
+ }
+ return outIndex;
+}
+
+static sqInt clipPolygonTopFromtocount(int *buf1, int *buf2, sqInt n) {
+    sqInt i;
+    sqInt inLast;
+    sqInt inNext;
+    sqInt j;
+    int *last;
+    int *next;
+    sqInt outIndex;
+    double t;
+
+ outIndex = 0;
+ last = buf1 + (n * PrimVertexSize);
+ next = buf1 + PrimVertexSize;
+ inLast = (last[PrimVtxClipFlags]) & InTopBit;
+ for (i = 1; i <= n; i += 1) {
+ inNext = (next[PrimVtxClipFlags]) & InTopBit;
+ if (!(inLast == inNext)) {
+
+ /* Passes clip boundary */
+
+ t = (((((float *) last))[PrimVtxRasterPosY]) - ((((float *) last))[PrimVtxRasterPosW])) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) - (((((float *) next))[PrimVtxRasterPosY]) - ((((float *) last))[PrimVtxRasterPosY])));
+ outIndex += 1;
+ interpolateFromtoatinto(((float *) last), ((float *) next), t, ((float*) (buf2 + (outIndex * PrimVertexSize))));
+ }
+ if (inNext) {
+ outIndex += 1;
+ for (j = 0; j <= (PrimVertexSize - 1); j += 1) {
+ buf2[(outIndex * PrimVertexSize) + j] = (next[j]);
+ }
+ }
+ last = next;
+ inLast = inNext;
+ next += PrimVertexSize;
+ }
+ return outIndex;
+}
+
+
+/* Compute the attenuation for the current light and vertex */
+
+static sqInt computeAttenuation(void) {
+ lightScale = 1.0;
+ if (lightFlags & FlagAttenuated) {
+ lightScale = 1.0 / ((primLight[PrimLightAttenuationConstant]) + (l2vDistance * ((primLight[PrimLightAttenuationLinear]) + (l2vDistance * (primLight[PrimLightAttenuationSquared])))));
+ }
+}
+
+
+/* Compute the direction for the current light and vertex */
+
+static sqInt computeDirection(void) {
+    double scale;
+
+ if (lightFlags & FlagPositional) {
+ l2vDirection[0] = ((litVertex[PrimVtxPositionX]) - (primLight[PrimLightPositionX]));
+ l2vDirection[1] = ((litVertex[PrimVtxPositionY]) - (primLight[PrimLightPositionY]));
+ l2vDirection[2] = ((litVertex[PrimVtxPositionZ]) - (primLight[PrimLightPositionZ]));
+ l2vDistance = (((l2vDirection[0]) * (l2vDirection[0])) + ((l2vDirection[1]) * (l2vDirection[1]))) + ((l2vDirection[2]) * (l2vDirection[2]));
+ if (!((l2vDistance == 0.0) || (l2vDistance == 1.0))) {
+ l2vDistance = sqrt(l2vDistance);
+ scale = -1.0 / l2vDistance;
+ }
+ l2vDirection[0] = ((l2vDirection[0]) * scale);
+ l2vDirection[1] = ((l2vDirection[1]) * scale);
+ l2vDirection[2] = ((l2vDirection[2]) * scale);
+ } else {
+ if (lightFlags & FlagDirectional) {
+ l2vDirection[0] = (primLight[PrimLightDirectionX]);
+ l2vDirection[1] = (primLight[PrimLightDirectionY]);
+ l2vDirection[2] = (primLight[PrimLightDirectionZ]);
+ }
+ }
+}
+
+
+/* Computes
+ l2vSpecDir _ l2vSpecDir - vtx position safelyNormalized.
+ */
+
+static sqInt computeSpecularDirection(void) {
+    double scale;
+
+ scale = inverseLengthOfFloat(litVertex + PrimVtxPosition);
+ l2vSpecDir[0] = ((l2vSpecDir[0]) - ((litVertex[PrimVtxPositionX]) * scale));
+ l2vSpecDir[1] = ((l2vSpecDir[1]) - ((litVertex[PrimVtxPositionY]) * scale));
+ l2vSpecDir[2] = ((l2vSpecDir[2]) - ((litVertex[PrimVtxPositionZ]) * scale));
+}
+
+
+/* Compute the spot factor for a spot light */
+
+static double computeSpotFactor(void) {
+    double cosAngle;
+    double deltaCos;
+    double minCos;
+
+ cosAngle = dotProductOfFloatwithDouble(primLight + PrimLightDirection, l2vDirection);
+ cosAngle = 0.0 - cosAngle;
+ minCos = primLight[SpotLightMinCos];
+ if (cosAngle < minCos) {
+ return 0.0;
+ }
+ deltaCos = primLight[SpotLightDeltaCos];
+ if (deltaCos <= 1.0e-5) {
+ return 1.0;
+ }
+ cosAngle = (cosAngle - minCos) / deltaCos;
+ return pow(cosAngle,(primLight[SpotLightExponent]));
+}
+
+static sqInt determineClipFlagscount(void *vtxArray, sqInt count) {
+    sqInt flags;
+    sqInt fullMask;
+    sqInt i;
+    float *vtxPtr;
+    double w;
+    double w2;
+    double x;
+    double y;
+    double z;
+
+ vtxPtr = ((float *) vtxArray);
+ fullMask = InAllMask + OutAllMask;
+ for (i = 1; i <= count; i += 1) {
+ w = vtxPtr[PrimVtxRasterPosW];
+ w2 = 0.0 - w;
+ flags = 0;
+ x = vtxPtr[PrimVtxRasterPosX];
+ if (x >= w2) {
+ flags = flags | InLeftBit;
+ } else {
+ flags = flags | OutLeftBit;
+ }
+ if (x <= w) {
+ flags = flags | InRightBit;
+ } else {
+ flags = flags | OutRightBit;
+ }
+ y = vtxPtr[PrimVtxRasterPosY];
+ if (y >= w2) {
+ flags = flags | InBottomBit;
+ } else {
+ flags = flags | OutBottomBit;
+ }
+ if (y <= w) {
+ flags = flags | InTopBit;
+ } else {
+ flags = flags | OutTopBit;
+ }
+ z = vtxPtr[PrimVtxRasterPosZ];
+ if (z >= w2) {
+ flags = flags | InFrontBit;
+ } else {
+ flags = flags | OutFrontBit;
+ }
+ if (z <= w) {
+ flags = flags | InBackBit;
+ } else {
+ flags = flags | OutBackBit;
+ }
+ fullMask = fullMask & flags;
+ (((int *) vtxPtr))[PrimVtxClipFlags] = flags;
+ vtxPtr += PrimVertexSize;
+ }
+ return fullMask;
+}
+
+static double dotProductOfFloatwithDouble(float * v1, double *v2) {
+ return (((v1[0]) * (v2[0])) + ((v1[1]) * (v2[1]))) + ((v1[2]) * (v2[2]));
+}
+
+
+/* Fetch the primitive light source from the given array.
+ Note: No checks are done within here - that happened in stackLightArrayValue: */
+
+static void* fetchLightSourceofObject(sqInt index, sqInt anArray) {
+    sqInt lightOop;
+
+ lightOop = interpreterProxy->fetchPointerofObject(index, anArray);
+ return interpreterProxy->firstIndexableField(lightOop);
+}
+
+static double frontClipValueFromto(sqInt last, sqInt next) {
+ return (0.0 - (((((float *) last))[PrimVtxRasterPosZ]) + ((((float *) last))[PrimVtxRasterPosW]))) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) + (((((float *) next))[PrimVtxRasterPosZ]) - ((((float *) last))[PrimVtxRasterPosZ])));
+}
+
+
+/* Note: This is coded so that plugins can be run from Squeak. */
+
+static VirtualMachine * getInterpreter(void) {
+ return interpreterProxy;
+}
+
+
+/* Note: This is hardcoded so it can be run from Squeak.
+ The module name is used for validating a module *after*
+ it is loaded to check if it does really contain the module
+ we're thinking it contains. This is important! */
+
+EXPORT(const char*) getModuleName(void) {
+ return moduleName;
+}
+
+static sqInt halt(void) {
+ ;
+}
+
+EXPORT(sqInt) initialiseModule(void) {
+ loadBBFn = interpreterProxy->ioLoadFunctionFrom("loadBitBltFrom", bbPluginName);
+ copyBitsFn = interpreterProxy->ioLoadFunctionFrom("copyBitsFromtoat", bbPluginName);
+ return (loadBBFn != 0) && (copyBitsFn != 0);
+}
+
+
+/* Interpolate the primitive vertices last/next at the parameter t */
+
+static sqInt interpolateFromtoatinto(float *last, float *next, double t, float *out) {
+    double delta;
+    sqInt flags;
+    unsigned int lastValue;
+    unsigned int newValue;
+    unsigned int nextValue;
+    unsigned int rgbaLast;
+    unsigned int rgbaNext;
+    double w;
+    double w2;
+    double x;
+    double y;
+    double z;
+
+ delta = (next[PrimVtxRasterPosX]) - (last[PrimVtxRasterPosX]);
+ x = (last[PrimVtxRasterPosX]) + (delta * t);
+ out[PrimVtxRasterPosX] = (((float) x));
+ delta = (next[PrimVtxRasterPosY]) - (last[PrimVtxRasterPosY]);
+ y = (last[PrimVtxRasterPosY]) + (delta * t);
+ out[PrimVtxRasterPosY] = (((float) y));
+ delta = (next[PrimVtxRasterPosZ]) - (last[PrimVtxRasterPosZ]);
+ z = (last[PrimVtxRasterPosZ]) + (delta * t);
+ out[PrimVtxRasterPosZ] = (((float) z));
+ delta = (next[PrimVtxRasterPosW]) - (last[PrimVtxRasterPosW]);
+ w = (last[PrimVtxRasterPosW]) + (delta * t);
+ out[PrimVtxRasterPosW] = (((float) w));
+ w2 = 0.0 - w;
+ flags = 0;
+ if (x >= w2) {
+ flags = flags | InLeftBit;
+ } else {
+ flags = flags | OutLeftBit;
+ }
+ if (x <= w) {
+ flags = flags | InRightBit;
+ } else {
+ flags = flags | OutRightBit;
+ }
+ if (y >= w2) {
+ flags = flags | InBottomBit;
+ } else {
+ flags = flags | OutBottomBit;
+ }
+ if (y <= w) {
+ flags = flags | InTopBit;
+ } else {
+ flags = flags | OutTopBit;
+ }
+ if (z >= w2) {
+ flags = flags | InFrontBit;
+ } else {
+ flags = flags | OutFrontBit;
+ }
+ if (z <= w) {
+ flags = flags | InBackBit;
+ } else {
+ flags = flags | OutBackBit;
+ }
+ (((int *) out))[PrimVtxClipFlags] = flags;
+ rgbaLast = (((unsigned int *) last))[PrimVtxColor32];
+ lastValue = rgbaLast & 255;
+ rgbaLast = ((usqInt) rgbaLast) >> 8;
+ rgbaNext = (((unsigned int *) next))[PrimVtxColor32];
+ nextValue = rgbaNext & 255;
+ rgbaNext = ((usqInt) rgbaNext) >> 8;
+ delta = (((int) (nextValue - lastValue))) * t;
+ newValue = ((sqInt)(lastValue + delta));
+ lastValue = rgbaLast & 255;
+ rgbaLast = ((usqInt) rgbaLast) >> 8;
+ nextValue = rgbaNext & 255;
+ rgbaNext = ((usqInt) rgbaNext) >> 8;
+ delta = (((int) (nextValue - lastValue))) * t;
+ newValue += (((sqInt)(lastValue + delta))) << 8;
+ lastValue = rgbaLast & 255;
+ rgbaLast = ((usqInt) rgbaLast) >> 8;
+ nextValue = rgbaNext & 255;
+ rgbaNext = ((usqInt) rgbaNext) >> 8;
+ delta = (((int) (nextValue - lastValue))) * t;
+ newValue += (((sqInt)(lastValue + delta))) << 16;
+ lastValue = rgbaLast & 255;
+ nextValue = rgbaNext & 255;
+ delta = (((int) (nextValue - lastValue))) * t;
+ newValue += (((sqInt)(lastValue + delta))) << 24;
+ (((unsigned int*) out))[PrimVtxColor32] = newValue;
+ delta = (next[PrimVtxTexCoordU]) - (last[PrimVtxTexCoordU]);
+ out[PrimVtxTexCoordU] = (((float) ((last[PrimVtxTexCoordU]) + (delta * t))));
+ delta = (next[PrimVtxTexCoordV]) - (last[PrimVtxTexCoordV]);
+ out[PrimVtxTexCoordV] = (((float) ((last[PrimVtxTexCoordV]) + (delta * t))));
+}
+
+static double inverseLengthOfDouble(double * aVector) {
+    double scale;
+
+ scale = (((aVector[0]) * (aVector[0])) + ((aVector[1]) * (aVector[1]))) + ((aVector[2]) * (aVector[2]));
+ if ((scale == 0.0) || (scale == 1.0)) {
+ return scale;
+ }
+ return 1.0 / (sqrt(scale));
+}
+
+static double inverseLengthOfFloat(float * aVector) {
+    double scale;
+
+ scale = (((aVector[0]) * (aVector[0])) + ((aVector[1]) * (aVector[1]))) + ((aVector[2]) * (aVector[2]));
+ if ((scale == 0.0) || (scale == 1.0)) {
+ return scale;
+ }
+ return 1.0 / (sqrt(scale));
+}
+
+static double leftClipValueFromto(sqInt last, sqInt next) {
+ return (0.0 - (((((float *) last))[PrimVtxRasterPosX]) + ((((float *) last))[PrimVtxRasterPosW]))) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) + (((((float *) next))[PrimVtxRasterPosX]) - ((((float *) last))[PrimVtxRasterPosX])));
+}
+
+static sqInt loadObjectsFrom(sqInt stackIndex) {
+    sqInt arrayOop;
+    sqInt arraySize;
+    sqInt i;
+    B3DPrimitiveObject **objArray;
+    sqInt objOop;
+    B3DPrimitiveObject *objPtr;
+
+ arrayOop = interpreterProxy->stackObjectValue(stackIndex);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!((interpreterProxy->fetchClassOf(arrayOop)) == (interpreterProxy->classArray()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ arraySize = interpreterProxy->slotSizeOf(arrayOop);
+ if (arraySize > (state.nObjects)) {
+ return interpreterProxy->primitiveFail();
+ }
+ objArray = state.objects;
+ for (i = 0; i <= (arraySize - 1); i += 1) {
+ objOop = interpreterProxy->fetchPointerofObject(i, arrayOop);
+ if (((objOop & 1)) || (!(interpreterProxy->isWords(objOop)))) {
+ return interpreterProxy->primitiveFail();
+ }
+ objPtr = ((B3DPrimitiveObject*) (interpreterProxy->firstIndexableField(objOop)));
+ if (objPtr->magic != B3D_PRIMITIVE_OBJECT_MAGIC) {
+ return interpreterProxy->primitiveFail();
+ }
+ objPtr->__oop__ = objOop;
+ objArray[i] = objPtr;
+ }
+}
+
+static sqInt loadPrimitiveLightSource(void) {
+ lightFlags = (((int*) primLight))[PrimLightFlags];
+}
+
+
+/* Load the necessary values from the current primitive vertex */
+
+static sqInt loadPrimitiveVertex(void) {
+    sqInt rgba;
+
+ rgba = (((int*) litVertex))[PrimVtxColor32];
+ vtxInColor[2] = ((rgba & 255) * (1.0 / 255.0));
+ rgba = ((usqInt) rgba) >> 8;
+ vtxInColor[1] = ((rgba & 255) * (1.0 / 255.0));
+ rgba = ((usqInt) rgba) >> 8;
+ vtxInColor[0] = ((rgba & 255) * (1.0 / 255.0));
+ rgba = ((usqInt) rgba) >> 8;
+ vtxInColor[3] = ((rgba & 255) * (1.0 / 255.0));
+}
+
+
+/* Load the rasterizer state from the given stack index. */
+
+static sqInt loadRasterizerState(sqInt stackIndex) {
+    sqInt obj;
+    sqInt objLen;
+    void *objPtr;
+    sqInt stateOop;
+
+ if ((copyBitsFn == 0) || (loadBBFn == 0)) {
+ if (!(initialiseModule())) {
+ return 0;
+ }
+ }
+ stateOop = interpreterProxy->stackObjectValue(stackIndex);
+ if (interpreterProxy->failed()) {
+ return 0;
+ }
+ if (!((interpreterProxy->isPointers(stateOop)) && ((interpreterProxy->slotSizeOf(stateOop)) >= 10))) {
+ return 0;
+ }
+ obj = interpreterProxy->fetchPointerofObject(0, stateOop);
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.faceAlloc = objPtr;
+ obj = interpreterProxy->fetchPointerofObject(1, stateOop);
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.edgeAlloc = objPtr;
+ obj = interpreterProxy->fetchPointerofObject(2, stateOop);
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.attrAlloc = objPtr;
+ obj = interpreterProxy->fetchPointerofObject(3, stateOop);
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.aet = objPtr;
+ obj = interpreterProxy->fetchPointerofObject(4, stateOop);
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.addedEdges = objPtr;
+ obj = interpreterProxy->fetchPointerofObject(5, stateOop);
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.fillList = objPtr;
+ obj = interpreterProxy->fetchPointerofObject(6, stateOop);
+ if (obj == (interpreterProxy->nilObject())) {
+ state.nObjects = 0;
+ state.objects = NULL;
+ } else {
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objLen = interpreterProxy->slotSizeOf(obj);
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.objects = (B3DPrimitiveObject **)objPtr;
+ state.nObjects = objLen;
+ }
+ obj = interpreterProxy->fetchPointerofObject(7, stateOop);
+ if (obj == (interpreterProxy->nilObject())) {
+ state.nTextures = 0;
+ state.textures = NULL;
+ } else {
+ if (((obj & 1)) || (!(interpreterProxy->isWords(obj)))) {
+ return 0;
+ }
+ objLen = interpreterProxy->byteSizeOf(obj);
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.textures = (B3DTexture *)objPtr;
+ state.nTextures = objLen / sizeof(B3DTexture);
+ }
+ obj = interpreterProxy->fetchPointerofObject(8, stateOop);
+ if (obj == (interpreterProxy->nilObject())) {
+ state.spanSize = 0;
+ state.spanBuffer = NULL;
+ } else {
+ if (!((interpreterProxy->fetchClassOf(obj)) == (interpreterProxy->classBitmap()))) {
+ return 0;
+ }
+ objLen = interpreterProxy->slotSizeOf(obj);
+ objPtr = interpreterProxy->firstIndexableField(obj);
+ state.spanBuffer = (unsigned int *)objPtr;
+ state.spanSize = objLen;
+ }
+ obj = interpreterProxy->fetchPointerofObject(9, stateOop);
+ if (obj == (interpreterProxy->nilObject())) {
+ state.spanDrawer = NULL;
+ } else {
+ if (!(((int (*) (int))loadBBFn)(obj))) {
+ return 0;
+ }
+ state.spanDrawer = (b3dDrawBufferFunction) copyBitsFn;
+ }
+ return !(interpreterProxy->failed());
+}
+
+
+/* Note: This still uses the old-style textures */
+
+static sqInt loadTextureinto(sqInt textureOop, B3DTexture *destPtr) {
+    void *bitsPtr;
+    sqInt form;
+    sqInt formBits;
+    sqInt formDepth;
+    sqInt formHeight;
+    sqInt formWidth;
+    sqInt texEnvMode;
+    sqInt texInterpolate;
+    sqInt texWrap;
+
+ form = textureOop;
+ if (!(interpreterProxy->isPointers(form))) {
+ return 0;
+ }
+ if ((interpreterProxy->slotSizeOf(form)) < 8) {
+ return 0;
+ }
+ formBits = interpreterProxy->fetchPointerofObject(0, form);
+ formWidth = interpreterProxy->fetchIntegerofObject(1, form);
+ formHeight = interpreterProxy->fetchIntegerofObject(2, form);
+ formDepth = interpreterProxy->fetchIntegerofObject(3, form);
+ texWrap = interpreterProxy->booleanValueOf(interpreterProxy->fetchPointerofObject(5, form));
+ texInterpolate = interpreterProxy->booleanValueOf(interpreterProxy->fetchPointerofObject(6, form));
+ texEnvMode = interpreterProxy->fetchIntegerofObject(7, form);
+ if (interpreterProxy->failed()) {
+ return 0;
+ }
+ if ((formWidth < 1) || ((formHeight < 1) || (formDepth != 32))) {
+ return 0;
+ }
+ if (!((interpreterProxy->fetchClassOf(formBits)) == (interpreterProxy->classBitmap()))) {
+ return 0;
+ }
+ if (!((interpreterProxy->byteSizeOf(formBits)) == ((formWidth * formHeight) * 4))) {
+ return 0;
+ }
+ if ((texEnvMode < 0) || (texEnvMode > 1)) {
+ return 0;
+ }
+
+ /* Set the texture parameters */
+
+ bitsPtr = interpreterProxy->firstIndexableField(formBits);
+ return b3dLoadTexture(destPtr, formWidth, formHeight, formDepth, (unsigned int*) bitsPtr, 0, NULL) == B3D_NO_ERROR;
+}
+
+static sqInt loadTexturesFrom(sqInt stackIndex) {
+    sqInt arrayOop;
+    B3DTexture *destPtr;
+    sqInt i;
+    sqInt n;
+    sqInt textureOop;
+
+ arrayOop = interpreterProxy->stackObjectValue(stackIndex);
+ if (!((interpreterProxy->fetchClassOf(arrayOop)) == (interpreterProxy->classArray()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ n = interpreterProxy->slotSizeOf(arrayOop);
+ n = ((n < (state.nTextures)) ? n : (state.nTextures));
+ for (i = 0; i <= (n - 1); i += 1) {
+ destPtr = state.textures + i;
+ textureOop = interpreterProxy->fetchPointerofObject(i, arrayOop);
+ if (!(loadTextureinto(textureOop, destPtr))) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ return 0;
+}
+
+
+/* Load the viewport from the given stack index */
+
+static sqInt loadViewportFrom(sqInt stackIndex) {
+    sqInt oop;
+    sqInt p1;
+    sqInt p2;
+    sqInt x0;
+    sqInt x1;
+    sqInt y0;
+    sqInt y1;
+
+ oop = interpreterProxy->stackObjectValue(stackIndex);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!(interpreterProxy->isPointers(oop))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if ((interpreterProxy->slotSizeOf(oop)) < 2) {
+ return interpreterProxy->primitiveFail();
+ }
+ p1 = interpreterProxy->fetchPointerofObject(0, oop);
+ p2 = interpreterProxy->fetchPointerofObject(1, oop);
+ if (!((interpreterProxy->fetchClassOf(p1)) == (interpreterProxy->classPoint()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (!((interpreterProxy->fetchClassOf(p2)) == (interpreterProxy->classPoint()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ x0 = interpreterProxy->fetchIntegerofObject(0, p1);
+ y0 = interpreterProxy->fetchIntegerofObject(1, p1);
+ x1 = interpreterProxy->fetchIntegerofObject(0, p2);
+ y1 = interpreterProxy->fetchIntegerofObject(1, p2);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ viewport.x0 = x0;
+ viewport.y0 = y0;
+ viewport.x1 = x1;
+ viewport.y1 = y1;
+ return 0;
+}
+
+static sqInt mapVBofSizeinto(void *vtxArray, sqInt vtxCount, sqInt boxArray) {
+    double bottom;
+    sqInt flags;
+    sqInt floatOop;
+    sqInt i;
+    double left;
+    sqInt oop;
+    double right;
+    double top;
+    float *vtxPtr;
+    double w;
+    double x;
+    double y;
+
+ vtxPtr = ((float *) vtxArray);
+ for (i = 1; i <= vtxCount; i += 1) {
+ flags = (((int *) vtxPtr))[PrimVtxClipFlags];
+ w = vtxPtr[PrimVtxRasterPosW];
+ if (!(w == 0.0)) {
+ w = 1.0 / w;
+ }
+ if ((flags & OutLeftBit) != 0) {
+ x = -1.0;
+ } else {
+ if ((flags & OutRightBit) != 0) {
+ x = 1.0;
+ } else {
+ x = (vtxPtr[PrimVtxRasterPosX]) * w;
+ }
+ }
+ if ((flags & OutTopBit) != 0) {
+ y = -1.0;
+ } else {
+ if ((flags & OutBottomBit) != 0) {
+ y = 1.0;
+ } else {
+ y = (vtxPtr[PrimVtxRasterPosY]) * w;
+ }
+ }
+ if (i == 1) {
+ left = right = x;
+ top = bottom = y;
+ }
+ if (x < left) {
+ left = x;
+ }
+ if (x > right) {
+ right = x;
+ }
+ if (y < top) {
+ top = y;
+ }
+ if (y > bottom) {
+ bottom = y;
+ }
+ vtxPtr += PrimVertexSize;
+ }
+ oop = boxArray;
+ interpreterProxy->pushRemappableOop(oop);
+ floatOop = interpreterProxy->floatObjectOf(left);
+ oop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, oop, floatOop);
+ interpreterProxy->pushRemappableOop(oop);
+ floatOop = interpreterProxy->floatObjectOf(top);
+ oop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(1, oop, floatOop);
+ interpreterProxy->pushRemappableOop(oop);
+ floatOop = interpreterProxy->floatObjectOf(right);
+ oop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(2, oop, floatOop);
+ interpreterProxy->pushRemappableOop(oop);
+ floatOop = interpreterProxy->floatObjectOf(bottom);
+ oop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(3, oop, floatOop);
+}
+
+
+/* The module with the given name was just unloaded.
+ Make sure we have no dangling references. */
+
+EXPORT(sqInt) moduleUnloaded(char *aModuleName) {
+ if ((strcmp(aModuleName, bbPluginName)) == 0) {
+
+ /* BitBlt just shut down. How nasty. */
+
+ loadBBFn = 0;
+ copyBitsFn = 0;
+ }
+}
+
+static sqInt msg(char *s) {
+ fprintf(stderr, "\n%s: %s", moduleName, s);
+}
+
+
+/* Primitive. Set the BitBlt plugin to use. */
+
+EXPORT(sqInt) primitiveSetBitBltPlugin(void) {
+    sqInt i;
+    sqInt length;
+    sqInt needReload;
+    sqInt pluginName;
+    char *ptr;
+
+
+ /* Must be string to work */
+
+ pluginName = interpreterProxy->stackValue(0);
+ if (!(interpreterProxy->isBytes(pluginName))) {
+ return interpreterProxy->primitiveFail();
+ }
+ length = interpreterProxy->byteSizeOf(pluginName);
+ if (length >= 256) {
+ return interpreterProxy->primitiveFail();
+ }
+ ptr = interpreterProxy->firstIndexableField(pluginName);
+ needReload = 0;
+ for (i = 0; i <= (length - 1); i += 1) {
+ if (!((bbPluginName[i]) == (ptr[i]))) {
+ bbPluginName[i] = (ptr[i]);
+ needReload = 1;
+ }
+ }
+ if (!((bbPluginName[length]) == 0)) {
+ bbPluginName[length] = 0;
+ needReload = 1;
+ }
+ if (needReload) {
+ if (!(initialiseModule())) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ interpreterProxy->pop(1);
+}
+
+static double processIndexedofSizeidxArrayidxSize(float *vtxArray, sqInt vtxSize, int *idxArray, sqInt idxSize) {
+    sqInt i;
+    sqInt index;
+    double minZ;
+    float *vtxPtr;
+    double wValue;
+    double zValue;
+
+ minZ = 10.0;
+ for (i = 1; i <= idxSize; i += 1) {
+ index = idxArray[i];
+ if (index > 0) {
+ vtxPtr = vtxArray + ((index - 1) * PrimVertexSize);
+ zValue = vtxPtr[PrimVtxRasterPosZ];
+ wValue = vtxPtr[PrimVtxRasterPosW];
+ if (!(wValue == 0.0)) {
+ zValue = zValue / wValue;
+ }
+ if (zValue < minZ) {
+ minZ = zValue;
+ }
+ }
+ }
+ return minZ;
+}
+
+static sqInt processIndexedIDXofSizeidxArrayidxSize(float *vtxArray, sqInt vtxSize, int *idxArray, sqInt idxSize) {
+    sqInt i;
+    sqInt index;
+    sqInt minIndex;
+    double minZ;
+    float *vtxPtr;
+    double wValue;
+    double zValue;
+
+ minZ = 10.0;
+ minIndex = 0;
+ for (i = 1; i <= idxSize; i += 1) {
+ index = idxArray[i];
+ if (index > 0) {
+ vtxPtr = vtxArray + ((index - 1) * PrimVertexSize);
+ zValue = vtxPtr[PrimVtxRasterPosZ];
+ wValue = vtxPtr[PrimVtxRasterPosW];
+ if (!(wValue == 0.0)) {
+ zValue = zValue / wValue;
+ }
+ if ((minIndex == 0) || (zValue < minZ)) {
+ minIndex = i;
+ minZ = zValue;
+ }
+ }
+ }
+ return minIndex;
+}
+
+static double processNonIndexedofSize(float *vtxArray, sqInt vtxSize) {
+    sqInt i;
+    double minZ;
+    float *vtxPtr;
+    double wValue;
+    double zValue;
+
+ minZ = 10.0;
+ vtxPtr = vtxArray;
+ for (i = 1; i <= vtxSize; i += 1) {
+ zValue = vtxPtr[PrimVtxRasterPosZ];
+ wValue = vtxPtr[PrimVtxRasterPosW];
+ if (!(wValue == 0.0)) {
+ zValue = zValue / wValue;
+ }
+ if (zValue < minZ) {
+ minZ = zValue;
+ }
+ }
+ return minZ;
+}
+
+static sqInt processNonIndexedIDXofSize(float *vtxArray, sqInt vtxSize) {
+    sqInt i;
+    sqInt minIndex;
+    double minZ;
+    float *vtxPtr;
+    double wValue;
+    double zValue;
+
+ minZ = 10.0;
+ minIndex = 0;
+ vtxPtr = vtxArray;
+ for (i = 1; i <= vtxSize; i += 1) {
+ zValue = vtxPtr[PrimVtxRasterPosZ];
+ wValue = vtxPtr[PrimVtxRasterPosW];
+ if (!(wValue == 0.0)) {
+ zValue = zValue / wValue;
+ }
+ if ((minIndex == 0) || (zValue < minZ)) {
+ minIndex = i;
+ minZ = zValue;
+ }
+ }
+ return minIndex;
+}
+
+static double rightClipValueFromto(sqInt last, sqInt next) {
+ return (((((float *) last))[PrimVtxRasterPosX]) - ((((float *) last))[PrimVtxRasterPosW])) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) - (((((float *) next))[PrimVtxRasterPosX]) - ((((float *) last))[PrimVtxRasterPosX])));
+}
+
+
+/* Note: This is coded so that is can be run from Squeak. */
+
+EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter) {
+    sqInt ok;
+
+ interpreterProxy = anInterpreter;
+ ok = interpreterProxy->majorVersion() == VM_PROXY_MAJOR;
+ if (ok == 0) {
+ return 0;
+ }
+ ok = interpreterProxy->minorVersion() >= VM_PROXY_MINOR;
+ return ok;
+}
+
+static sqInt shadeVertex(void) {
+    double cosAngle;
+    double specularFactor;
+    double aPart;
+    double bPart;
+    double gPart;
+    double rPart;
+    double aPart1;
+    double bPart1;
+    double gPart1;
+    double rPart1;
+    double aPart2;
+    double bPart2;
+    double gPart2;
+    double rPart2;
+    double scale;
+
+ /* begin computeDirection */
+ if (lightFlags & FlagPositional) {
+ l2vDirection[0] = ((litVertex[PrimVtxPositionX]) - (primLight[PrimLightPositionX]));
+ l2vDirection[1] = ((litVertex[PrimVtxPositionY]) - (primLight[PrimLightPositionY]));
+ l2vDirection[2] = ((litVertex[PrimVtxPositionZ]) - (primLight[PrimLightPositionZ]));
+ l2vDistance = (((l2vDirection[0]) * (l2vDirection[0])) + ((l2vDirection[1]) * (l2vDirection[1]))) + ((l2vDirection[2]) * (l2vDirection[2]));
+ if (!((l2vDistance == 0.0) || (l2vDistance == 1.0))) {
+ l2vDistance = sqrt(l2vDistance);
+ scale = -1.0 / l2vDistance;
+ }
+ l2vDirection[0] = ((l2vDirection[0]) * scale);
+ l2vDirection[1] = ((l2vDirection[1]) * scale);
+ l2vDirection[2] = ((l2vDirection[2]) * scale);
+ } else {
+ if (lightFlags & FlagDirectional) {
+ l2vDirection[0] = (primLight[PrimLightDirectionX]);
+ l2vDirection[1] = (primLight[PrimLightDirectionY]);
+ l2vDirection[2] = (primLight[PrimLightDirectionZ]);
+ }
+ }
+ /* begin computeAttenuation */
+ lightScale = 1.0;
+ if (lightFlags & FlagAttenuated) {
+ lightScale = 1.0 / ((primLight[PrimLightAttenuationConstant]) + (l2vDistance * ((primLight[PrimLightAttenuationLinear]) + (l2vDistance * (primLight[PrimLightAttenuationSquared])))));
+ }
+ if (lightFlags & FlagHasSpot) {
+ lightScale = lightScale * (computeSpotFactor());
+ }
+ if (lightScale > 0.001) {
+ if (lightFlags & FlagAmbientPart) {
+ /* begin addPart:from:trackFlag:scale: */
+ if (vbFlags & VBTrackAmbient) {
+ rPart = ((vtxInColor[0]) * ((primLight + AmbientPart)[0])) * lightScale;
+ gPart = ((vtxInColor[1]) * ((primLight + AmbientPart)[1])) * lightScale;
+ bPart = ((vtxInColor[2]) * ((primLight + AmbientPart)[2])) * lightScale;
+ aPart = ((vtxInColor[3]) * ((primLight + AmbientPart)[3])) * lightScale;
+ } else {
+ rPart = (((primMaterial + AmbientPart)[0]) * ((primLight + AmbientPart)[0])) * lightScale;
+ gPart = (((primMaterial + AmbientPart)[1]) * ((primLight + AmbientPart)[1])) * lightScale;
+ bPart = (((primMaterial + AmbientPart)[2]) * ((primLight + AmbientPart)[2])) * lightScale;
+ aPart = (((primMaterial + AmbientPart)[3]) * ((primLight + AmbientPart)[3])) * lightScale;
+ }
+ vtxOutColor[0] = ((vtxOutColor[0]) + rPart);
+ vtxOutColor[1] = ((vtxOutColor[1]) + gPart);
+ vtxOutColor[2] = ((vtxOutColor[2]) + bPart);
+ vtxOutColor[3] = ((vtxOutColor[3]) + aPart);
+ }
+ if (lightFlags & FlagDiffusePart) {
+
+ /* Compute angle from light->vertex to vertex normal */
+ /* For one-sided lighting negate cosAngle if necessary */
+
+ cosAngle = dotProductOfFloatwithDouble(litVertex + PrimVtxNormal, l2vDirection);
+ if (((vbFlags & VBTwoSidedLighting) == 0) && (cosAngle < 0.0)) {
+ cosAngle = 0.0 - cosAngle;
+ }
+ if (cosAngle > 0.0) {
+ /* begin addPart:from:trackFlag:scale: */
+ if (vbFlags & VBTrackDiffuse) {
+ rPart1 = ((vtxInColor[0]) * ((primLight + DiffusePart)[0])) * (lightScale * cosAngle);
+ gPart1 = ((vtxInColor[1]) * ((primLight + DiffusePart)[1])) * (lightScale * cosAngle);
+ bPart1 = ((vtxInColor[2]) * ((primLight + DiffusePart)[2])) * (lightScale * cosAngle);
+ aPart1 = ((vtxInColor[3]) * ((primLight + DiffusePart)[3])) * (lightScale * cosAngle);
+ } else {
+ rPart1 = (((primMaterial + DiffusePart)[0]) * ((primLight + DiffusePart)[0])) * (lightScale * cosAngle);
+ gPart1 = (((primMaterial + DiffusePart)[1]) * ((primLight + DiffusePart)[1])) * (lightScale * cosAngle);
+ bPart1 = (((primMaterial + DiffusePart)[2]) * ((primLight + DiffusePart)[2])) * (lightScale * cosAngle);
+ aPart1 = (((primMaterial + DiffusePart)[3]) * ((primLight + DiffusePart)[3])) * (lightScale * cosAngle);
+ }
+ vtxOutColor[0] = ((vtxOutColor[0]) + rPart1);
+ vtxOutColor[1] = ((vtxOutColor[1]) + gPart1);
+ vtxOutColor[2] = ((vtxOutColor[2]) + bPart1);
+ vtxOutColor[3] = ((vtxOutColor[3]) + aPart1);
+ }
+ }
+ }
+ if ((lightFlags & FlagSpecularPart) && ((primMaterial[MaterialShininess]) > 0.0)) {
+ l2vSpecDir[0] = (l2vDirection[0]);
+ l2vSpecDir[1] = (l2vDirection[1]);
+ l2vSpecDir[2] = (l2vDirection[2]);
+ if (vbFlags & VBUseLocalViewer) {
+ computeSpecularDirection();
+ } else {
+ l2vSpecDir[2] = ((l2vSpecDir[2]) - 1.0);
+ }
+ cosAngle = dotProductOfFloatwithDouble(litVertex + PrimVtxNormal, l2vSpecDir);
+ if (cosAngle > 0.0) {
+
+ /* Normalize the angle */
+ /* cosAngle should be somewhere between 0 and 1.
+ If not, then the vertex normal was not normalized */
+
+ cosAngle = cosAngle * (inverseLengthOfDouble(l2vSpecDir));
+ if (cosAngle > 1.0) {
+ specularFactor = pow(cosAngle,(primMaterial[MaterialShininess]));
+ } else {
+ if (cosAngle == 0.0) {
+ specularFactor = 1.0;
+ } else {
+ specularFactor = pow(cosAngle,(primMaterial[MaterialShininess]));
+ }
+ }
+ /* begin addPart:from:trackFlag:scale: */
+ if (vbFlags & VBTrackSpecular) {
+ rPart2 = ((vtxInColor[0]) * ((primLight + SpecularPart)[0])) * specularFactor;
+ gPart2 = ((vtxInColor[1]) * ((primLight + SpecularPart)[1])) * specularFactor;
+ bPart2 = ((vtxInColor[2]) * ((primLight + SpecularPart)[2])) * specularFactor;
+ aPart2 = ((vtxInColor[3]) * ((primLight + SpecularPart)[3])) * specularFactor;
+ } else {
+ rPart2 = (((primMaterial + SpecularPart)[0]) * ((primLight + SpecularPart)[0])) * specularFactor;
+ gPart2 = (((primMaterial + SpecularPart)[1]) * ((primLight + SpecularPart)[1])) * specularFactor;
+ bPart2 = (((primMaterial + SpecularPart)[2]) * ((primLight + SpecularPart)[2])) * specularFactor;
+ aPart2 = (((primMaterial + SpecularPart)[3]) * ((primLight + SpecularPart)[3])) * specularFactor;
+ }
+ vtxOutColor[0] = ((vtxOutColor[0]) + rPart2);
+ vtxOutColor[1] = ((vtxOutColor[1]) + gPart2);
+ vtxOutColor[2] = ((vtxOutColor[2]) + bPart2);
+ vtxOutColor[3] = ((vtxOutColor[3]) + aPart2);
+ }
+ }
+}
+
+
+/* Load an Array of B3DPrimitiveLights from the given stack index */
+
+static sqInt stackLightArrayValue(sqInt stackIndex) {
+    sqInt array;
+    sqInt arraySize;
+    sqInt i;
+    sqInt oop;
+
+ array = interpreterProxy->stackObjectValue(stackIndex);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if (!((interpreterProxy->fetchClassOf(array)) == (interpreterProxy->classArray()))) {
+ return interpreterProxy->primitiveFail();
+ }
+ arraySize = interpreterProxy->slotSizeOf(array);
+ for (i = 0; i <= (arraySize - 1); i += 1) {
+ oop = interpreterProxy->fetchPointerofObject(i, array);
+ if ((oop & 1)) {
+ return interpreterProxy->primitiveFail();
+ }
+ if (!((interpreterProxy->isWords(oop)) && ((interpreterProxy->slotSizeOf(oop)) == PrimLightSize))) {
+ return interpreterProxy->primitiveFail();
+ }
+ }
+ return array;
+}
+
+
+/* Load a B3DMaterial from the given stack index */
+
+static void * stackMaterialValue(sqInt stackIndex) {
+    sqInt oop;
+
+ oop = interpreterProxy->stackObjectValue(stackIndex);
+ if (interpreterProxy->failed()) {
+ return null;
+ }
+ if ((interpreterProxy->isWords(oop)) && ((interpreterProxy->slotSizeOf(oop)) == MaterialSize)) {
+ return interpreterProxy->firstIndexableField(oop);
+ }
+ return null;
+}
+
+
+/* Load a 4x4 transformation matrix from the interpreter stack.
+ Return a pointer to the matrix data if successful, nil otherwise. */
+
+static void* stackMatrix(sqInt index) {
+    sqInt oop;
+
+ oop = interpreterProxy->stackObjectValue(index);
+ if (oop == null) {
+ return null;
+ }
+ if ((interpreterProxy->isWords(oop)) && ((interpreterProxy->slotSizeOf(oop)) == 16)) {
+ return interpreterProxy->firstIndexableField(oop);
+ }
+ return null;
+}
+
+
+/* Load a primitive index array from the interpreter stack.
+ If aBool is true then check that all the indexes are in the range (1,maxIndex).
+ Return a pointer to the index data if successful, nil otherwise. */
+
+static void* stackPrimitiveIndexArrayofSizevalidateforVertexSize(sqInt stackIndex, sqInt nItems, sqInt aBool, sqInt maxIndex) {
+    sqInt i;
+    int *idxPtr;
+    sqInt index;
+    sqInt oop;
+    sqInt oopSize;
+
+ oop = interpreterProxy->stackObjectValue(stackIndex);
+ if (oop == null) {
+ return null;
+ }
+ if (!(interpreterProxy->isWords(oop))) {
+ return null;
+ }
+ oopSize = interpreterProxy->slotSizeOf(oop);
+ if (oopSize < nItems) {
+ return null;
+ }
+ idxPtr = ((int *) (interpreterProxy->firstIndexableField(oop)));
+ if (aBool) {
+ for (i = 0; i <= (nItems - 1); i += 1) {
+ index = idxPtr[i];
+ if ((index < 0) || (index > maxIndex)) {
+ return null;
+ }
+ }
+ }
+ return idxPtr;
+}
+
+
+/* Load a primitive vertex from the interpreter stack.
+ Return a pointer to the vertex data if successful, nil otherwise. */
+
+static void* stackPrimitiveVertex(sqInt index) {
+    sqInt oop;
+
+ oop = interpreterProxy->stackObjectValue(index);
+ if (oop == null) {
+ return null;
+ }
+ if ((interpreterProxy->isWords(oop)) && ((interpreterProxy->slotSizeOf(oop)) == PrimVertexSize)) {
+ return interpreterProxy->firstIndexableField(oop);
+ }
+ return null;
+}
+
+
+/* Load a primitive vertex array from the interpreter stack.
+ Return a pointer to the vertex data if successful, nil otherwise. */
+
+static void* stackPrimitiveVertexArrayofSize(sqInt index, sqInt nItems) {
+    sqInt oop;
+    sqInt oopSize;
+
+ oop = interpreterProxy->stackObjectValue(index);
+ if (oop == null) {
+ return null;
+ }
+ if (interpreterProxy->isWords(oop)) {
+ oopSize = interpreterProxy->slotSizeOf(oop);
+ if (((oopSize >= nItems) * PrimVertexSize) && ((oopSize % PrimVertexSize) == 0)) {
+ return interpreterProxy->firstIndexableField(oop);
+ }
+ }
+ return null;
+}
+
+static sqInt storeObjectsInto(sqInt stackIndex) {
+    sqInt arrayOop;
+    sqInt arraySize;
+    sqInt i;
+    sqInt objOop;
+
+ arrayOop = interpreterProxy->stackObjectValue(stackIndex);
+ arraySize = state.nObjects;
+ for (i = 0; i <= (arraySize - 1); i += 1) {
+ objOop = state.objects[i]->__oop__;
+ interpreterProxy->storePointerofObjectwithValue(i, arrayOop, objOop);
+ }
+}
+
+
+/* Store the computed output color back into the current primitive vertex.
+ Clamp the r,g,b,a part to be in the range 0-255. */
+
+static sqInt storePrimitiveVertex(void) {
+    sqInt a;
+    sqInt b;
+    sqInt g;
+    sqInt r;
+
+ r = ((sqInt)((vtxOutColor[0]) * 255));
+ r = (((((r < 255) ? r : 255)) < 0) ? 0 : (((r < 255) ? r : 255)));
+ g = ((sqInt)((vtxOutColor[1]) * 255));
+ g = (((((g < 255) ? g : 255)) < 0) ? 0 : (((g < 255) ? g : 255)));
+ b = ((sqInt)((vtxOutColor[2]) * 255));
+ b = (((((b < 255) ? b : 255)) < 0) ? 0 : (((b < 255) ? b : 255)));
+ a = ((sqInt)((vtxOutColor[3]) * 255));
+
+ /* The following is equal to b + (g << 8) + (r << 16) + (a << 24) */
+
+ a = (((((a < 255) ? a : 255)) < 0) ? 0 : (((a < 255) ? a : 255)));
+ (((int*) litVertex))[PrimVtxColor32] = (b + ((g + ((r + (a << 8)) << 8)) << 8));
+}
+
+static double topClipValueFromto(sqInt last, sqInt next) {
+ return (((((float *) last))[PrimVtxRasterPosY]) - ((((float *) last))[PrimVtxRasterPosW])) / ((((((float *) next))[PrimVtxRasterPosW]) - ((((float *) last))[PrimVtxRasterPosW])) - (((((float *) next))[PrimVtxRasterPosY]) - ((((float *) last))[PrimVtxRasterPosY])));
+}
+
+
+/* Transform src with arg into dst.
+ It is allowed that src == dst but not arg == dst */
+
+static sqInt transformMatrixwithinto(float *src, float *arg, float *dst) {
+    float c1;
+    float c2;
+    float c3;
+    float c4;
+    sqInt i;
+    float *m1;
+    float *m2;
+    float *m3;
+
+ m1 = ((float *) src);
+ m2 = ((float *) arg);
+ m3 = ((float *) dst);
+ for (i = 0; i <= 3; i += 1) {
+
+ /* Compute next row */
+
+ c1 = ((((m1[0]) * (m2[0])) + ((m1[1]) * (m2[4]))) + ((m1[2]) * (m2[8]))) + ((m1[3]) * (m2[12]));
+ c2 = ((((m1[0]) * (m2[1])) + ((m1[1]) * (m2[5]))) + ((m1[2]) * (m2[9]))) + ((m1[3]) * (m2[13]));
+ c3 = ((((m1[0]) * (m2[2])) + ((m1[1]) * (m2[6]))) + ((m1[2]) * (m2[10]))) + ((m1[3]) * (m2[14]));
+
+ /* Store result */
+
+ c4 = ((((m1[0]) * (m2[3])) + ((m1[1]) * (m2[7]))) + ((m1[2]) * (m2[11]))) + ((m1[3]) * (m2[15]));
+ m3[0] = c1;
+ m3[1] = c2;
+ m3[2] = c3;
+ m3[3] = c4;
+ m1 += 4;
+ m3 += 4;
+ }
+}
+
+
+/* Transform the normal of the given primitive vertex */
+
+static sqInt transformPrimitiveNormalbyrescale(float *pVertex, float *matrix, sqInt rescale) {
+    double dot;
+    double rx;
+    double ry;
+    double rz;
+    double x;
+    double y;
+    double z;
+
+ x = pVertex[PrimVtxNormalX];
+ y = pVertex[PrimVtxNormalY];
+ z = pVertex[PrimVtxNormalZ];
+ rx = ((x * (matrix[0])) + (y * (matrix[1]))) + (z * (matrix[2]));
+ ry = ((x * (matrix[4])) + (y * (matrix[5]))) + (z * (matrix[6]));
+ rz = ((x * (matrix[8])) + (y * (matrix[9]))) + (z * (matrix[10]));
+ if (rescale) {
+ dot = ((rx * rx) + (ry * ry)) + (rz * rz);
+ if (dot < 1.0e-20) {
+ rx = ry = rz = 0.0;
+ } else {
+ if (!(dot == 1.0)) {
+ dot = 1.0 / (sqrt(dot));
+ rx = rx * dot;
+ ry = ry * dot;
+ rz = rz * dot;
+ }
+ }
+ }
+ pVertex[PrimVtxNormalX] = (((float) rx));
+ pVertex[PrimVtxNormalY] = (((float) ry));
+ pVertex[PrimVtxNormalZ] = (((float) rz));
+}
+
+
+/* Transform the normal of the given primitive vertex */
+
+static sqInt transformPrimitivePositionby(float *pVertex, float *matrix) {
+    double rw;
+    double rx;
+    double ry;
+    double rz;
+    double x;
+    double y;
+    double z;
+
+ x = pVertex[PrimVtxPositionX];
+ y = pVertex[PrimVtxPositionY];
+ z = pVertex[PrimVtxPositionZ];
+ rx = (((x * (matrix[0])) + (y * (matrix[1]))) + (z * (matrix[2]))) + (matrix[3]);
+ ry = (((x * (matrix[4])) + (y * (matrix[5]))) + (z * (matrix[6]))) + (matrix[7]);
+ rz = (((x * (matrix[8])) + (y * (matrix[9]))) + (z * (matrix[10]))) + (matrix[11]);
+ rw = (((x * (matrix[12])) + (y * (matrix[13]))) + (z * (matrix[14]))) + (matrix[15]);
+ if (rw == 1.0) {
+ pVertex[PrimVtxPositionX] = (((float) rx));
+ pVertex[PrimVtxPositionY] = (((float) ry));
+ pVertex[PrimVtxPositionZ] = (((float) rz));
+ } else {
+ if (rw == 0.0) {
+ rw = 0.0;
+ } else {
+ rw = 1.0 / rw;
+ }
+ pVertex[PrimVtxPositionX] = (((float) (rx * rw)));
+ pVertex[PrimVtxPositionY] = (((float) (ry * rw)));
+ pVertex[PrimVtxPositionZ] = (((float) (rz * rw)));
+ }
+}
+
+
+/* Transform the position of the given primitive vertex assuming that
+ matrix a41 = a42 = a43 = 0.0 and a44 = 1.0 */
+
+static sqInt transformPrimitivePositionFastby(float *pVertex, float *matrix) {
+    double rx;
+    double ry;
+    double rz;
+    double x;
+    double y;
+    double z;
+
+ x = pVertex[PrimVtxPositionX];
+ y = pVertex[PrimVtxPositionY];
+ z = pVertex[PrimVtxPositionZ];
+ rx = (((x * (matrix[0])) + (y * (matrix[1]))) + (z * (matrix[2]))) + (matrix[3]);
+ ry = (((x * (matrix[4])) + (y * (matrix[5]))) + (z * (matrix[6]))) + (matrix[7]);
+ rz = (((x * (matrix[8])) + (y * (matrix[9]))) + (z * (matrix[10]))) + (matrix[11]);
+ pVertex[PrimVtxPositionX] = (((float) rx));
+ pVertex[PrimVtxPositionY] = (((float) ry));
+ pVertex[PrimVtxPositionZ] = (((float) rz));
+}
+
+
+/* Transform the position of the given primitive vertex assuming that
+ matrix a14 = a24 = a34 = a41 = a42 = a43 = 0.0 and a44 = 1.0 */
+
+static sqInt transformPrimitivePositionFasterby(float *pVertex, float *matrix) {
+    double rx;
+    double ry;
+    double rz;
+    double x;
+    double y;
+    double z;
+
+ x = pVertex[PrimVtxPositionX];
+ y = pVertex[PrimVtxPositionY];
+ z = pVertex[PrimVtxPositionZ];
+ rx = ((x * (matrix[0])) + (y * (matrix[1]))) + (z * (matrix[2]));
+ ry = ((x * (matrix[4])) + (y * (matrix[5]))) + (z * (matrix[6]));
+ rz = ((x * (matrix[8])) + (y * (matrix[9]))) + (z * (matrix[10]));
+ pVertex[PrimVtxPositionX] = (((float) rx));
+ pVertex[PrimVtxPositionY] = (((float) ry));
+ pVertex[PrimVtxPositionZ] = (((float) rz));
+}
+
+
+/* Transform the normal of the given primitive vertex */
+
+static sqInt transformPrimitiveRasterPositionby(float *pVertex, float *matrix) {
+    double rw;
+    double rx;
+    double ry;
+    double rz;
+    double x;
+    double y;
+    double z;
+
+ x = pVertex[PrimVtxPositionX];
+ y = pVertex[PrimVtxPositionY];
+ z = pVertex[PrimVtxPositionZ];
+ rx = (((x * (matrix[0])) + (y * (matrix[1]))) + (z * (matrix[2]))) + (matrix[3]);
+ ry = (((x * (matrix[4])) + (y * (matrix[5]))) + (z * (matrix[6]))) + (matrix[7]);
+ rz = (((x * (matrix[8])) + (y * (matrix[9]))) + (z * (matrix[10]))) + (matrix[11]);
+ rw = (((x * (matrix[12])) + (y * (matrix[13]))) + (z * (matrix[14]))) + (matrix[15]);
+ pVertex[PrimVtxRasterPosX] = (((float) rx));
+ pVertex[PrimVtxRasterPosY] = (((float) ry));
+ pVertex[PrimVtxRasterPosZ] = (((float) rz));
+ pVertex[PrimVtxRasterPosW] = (((float) rw));
+}
+
+
+/* Transform the entire vertex array by the given matrices */
+/* TODO: Check the actual trade-offs between vtxCount and analyzing */
+
+static sqInt transformVBcountbyandflags(float *vtxArray, sqInt vtxCount, float *modelViewMatrix, float *projectionMatrix, sqInt flags) {
+    sqInt hasNormals;
+    sqInt i;
+    sqInt mvFlags;
+    float *pVertex;
+    sqInt prFlags;
+    sqInt rescale;
+
+ mvFlags = analyzeMatrix(modelViewMatrix);
+ prFlags = analyzeMatrix(projectionMatrix);
+ pVertex = ((float *) vtxArray);
+
+ /* Check if we have to rescale the normals */
+
+ hasNormals = flags & VBVtxHasNormals;
+ if (hasNormals) {
+ if (mvFlags & FlagM44Identity) {
+ rescale = 0;
+ } else {
+ rescale = analyzeMatrix3x3Length(modelViewMatrix);
+ }
+ }
+ if ((mvFlags & FlagM44NoPerspective) && (prFlags == 0)) {
+ if ((mvFlags == FlagM44NoTranslation) == 0) {
+ for (i = 1; i <= vtxCount; i += 1) {
+ if (hasNormals) {
+ transformPrimitiveNormalbyrescale(pVertex, modelViewMatrix, rescale);
+ }
+ transformPrimitivePositionFastby(pVertex, modelViewMatrix);
+ transformPrimitiveRasterPositionby(pVertex, projectionMatrix);
+ pVertex += PrimVertexSize;
+ }
+ } else {
+ for (i = 1; i <= vtxCount; i += 1) {
+ if (hasNormals) {
+ transformPrimitiveNormalbyrescale(pVertex, modelViewMatrix, rescale);
+ }
+ transformPrimitivePositionFasterby(pVertex, modelViewMatrix);
+ transformPrimitiveRasterPositionby(pVertex, projectionMatrix);
+ pVertex += PrimVertexSize;
+ }
+ }
+ return null;
+ }
+ if ((mvFlags & prFlags) & FlagM44Identity) {
+ for (i = 1; i <= vtxCount; i += 1) {
+ pVertex[PrimVtxRasterPosX] = (pVertex[PrimVtxPositionX]);
+ pVertex[PrimVtxRasterPosY] = (pVertex[PrimVtxPositionY]);
+ pVertex[PrimVtxRasterPosZ] = (pVertex[PrimVtxPositionZ]);
+ pVertex[PrimVtxRasterPosW] = 1.0;
+ pVertex += PrimVertexSize;
+ }
+ return null;
+ }
+ if (mvFlags & FlagM44Identity) {
+ for (i = 1; i <= vtxCount; i += 1) {
+ transformPrimitiveRasterPositionby(pVertex, projectionMatrix);
+ pVertex += PrimVertexSize;
+ }
+ return null;
+ }
+ if (prFlags & FlagM44Identity) {
+ for (i = 1; i <= vtxCount; i += 1) {
+ if (hasNormals) {
+ transformPrimitiveNormalbyrescale(pVertex, modelViewMatrix, rescale);
+ }
+ if (mvFlags == (FlagM44NoPerspective + FlagM44NoPerspective)) {
+ transformPrimitivePositionFasterby(pVertex, modelViewMatrix);
+ } else {
+ if (mvFlags == FlagM44NoPerspective) {
+ transformPrimitivePositionFastby(pVertex, modelViewMatrix);
+ } else {
+ transformPrimitivePositionby(pVertex, modelViewMatrix);
+ }
+ }
+ pVertex[PrimVtxRasterPosX] = (pVertex[PrimVtxPositionX]);
+ pVertex[PrimVtxRasterPosY] = (pVertex[PrimVtxPositionY]);
+ pVertex[PrimVtxRasterPosZ] = (pVertex[PrimVtxPositionZ]);
+ pVertex[PrimVtxRasterPosW] = 1.0;
+ pVertex += PrimVertexSize;
+ }
+ return null;
+ }
+ for (i = 1; i <= vtxCount; i += 1) {
+ if (hasNormals) {
+ transformPrimitiveNormalbyrescale(pVertex, modelViewMatrix, rescale);
+ }
+ transformPrimitivePositionby(pVertex, modelViewMatrix);
+ transformPrimitiveRasterPositionby(pVertex, projectionMatrix);
+ pVertex += PrimVertexSize;
+ }
+}
+
+
+/* Load the word based array of size count from the given oop */
+
+static void* vbLoadArraysize(sqInt oop, sqInt count) {
+ if (oop == null) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ if (oop == (interpreterProxy->nilObject())) {
+ return null;
+ }
+ if (!(interpreterProxy->isWords(oop))) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ if (!((interpreterProxy->slotSizeOf(oop)) == count)) {
+ interpreterProxy->primitiveFail();
+ return null;
+ }
+ return interpreterProxy->firstIndexableField(oop);
+}
+
+
+#ifdef SQUEAK_BUILTIN_PLUGIN
+
+
+void* Squeak3D_exports[][3] = {
+ {"Squeak3D", "b3dShaderVersion", (void*)b3dShaderVersion},
+ {"Squeak3D", "b3dTransformPrimitiveNormal", (void*)b3dTransformPrimitiveNormal},
+ {"Squeak3D", "b3dClipPolygon", (void*)b3dClipPolygon},
+ {"Squeak3D", "b3dOrthoNormInverseMatrix", (void*)b3dOrthoNormInverseMatrix},
+ {"Squeak3D", "b3dTransformVertexBuffer", (void*)b3dTransformVertexBuffer},
+ {"Squeak3D", "b3dComputeMinZ", (void*)b3dComputeMinZ},
+ {"Squeak3D", "b3dInitializeRasterizerState", (void*)b3dInitializeRasterizerState},
+ {"Squeak3D", "b3dDetermineClipFlags", (void*)b3dDetermineClipFlags},
+ {"Squeak3D", "getModuleName", (void*)getModuleName},
+ {"Squeak3D", "setInterpreter", (void*)setInterpreter},
+ {"Squeak3D", "b3dTransformPrimitiveRasterPosition", (void*)b3dTransformPrimitiveRasterPosition},
+ {"Squeak3D", "primitiveSetBitBltPlugin", (void*)primitiveSetBitBltPlugin},
+ {"Squeak3D", "b3dTransformMatrixWithInto", (void*)b3dTransformMatrixWithInto},
+ {"Squeak3D", "b3dStartRasterizer", (void*)b3dStartRasterizer},
+ {"Squeak3D", "b3dShadeVertexBuffer", (void*)b3dShadeVertexBuffer},
+ {"Squeak3D", "b3dRasterizerVersion", (void*)b3dRasterizerVersion},
+ {"Squeak3D", "b3dInitPrimitiveObject", (void*)b3dInitPrimitiveObject},
+ {"Squeak3D", "b3dLoadVertexBuffer", (void*)b3dLoadVertexBuffer},
+ {"Squeak3D", "b3dTransformDirection", (void*)b3dTransformDirection},
+ {"Squeak3D", "moduleUnloaded", (void*)moduleUnloaded},
+ {"Squeak3D", "b3dPrimitiveTextureSize", (void*)b3dPrimitiveTextureSize},
+ {"Squeak3D", "b3dComputeMinIndexZ", (void*)b3dComputeMinIndexZ},
+ {"Squeak3D", "b3dMapVertexBuffer", (void*)b3dMapVertexBuffer},
+ {"Squeak3D", "initialiseModule", (void*)initialiseModule},
+ {"Squeak3D", "b3dTransformerVersion", (void*)b3dTransformerVersion},
+ {"Squeak3D", "b3dTransposeMatrix", (void*)b3dTransposeMatrix},
+ {"Squeak3D", "b3dPrimitiveNextClippedTriangle", (void*)b3dPrimitiveNextClippedTriangle},
+ {"Squeak3D", "b3dTransformPoint", (void*)b3dTransformPoint},
+ {"Squeak3D", "b3dTransformPrimitivePosition", (void*)b3dTransformPrimitivePosition},
+ {"Squeak3D", "b3dPrimitiveObjectSize", (void*)b3dPrimitiveObjectSize},
+ {"Squeak3D", "b3dLoadIndexArray", (void*)b3dLoadIndexArray},
+ {"Squeak3D", "b3dInplaceHouseHolderInvert", (void*)b3dInplaceHouseHolderInvert},
+ {NULL, NULL, NULL}
+};
+
+
+#endif /* ifdef SQ_BUILTIN_PLUGIN */
+
Modified: trunk/platforms/unix/src/plugins.ext
===================================================================
--- trunk/platforms/unix/src/plugins.ext 2011-01-23 07:34:41 UTC (rev 2354)
+++ trunk/platforms/unix/src/plugins.ext 2011-01-23 09:41:21 UTC (rev 2355)
@@ -1,2 +1,2 @@
 # Automatically generated makefile include for external plugins
-EXTERNAL_PLUGINS = B3DAcceleratorPlugin ClipboardExtendedPlugin DBusPlugin SqueakFFIPrims FileCopyPlugin GStreamerPlugin HostWindowPlugin KedamaPlugin KedamaPlugin2 MIDIPlugin Mpeg3Plugin UUIDPlugin AioPlugin UnixOSProcessPlugin XDisplayControlPlugin
+EXTERNAL_PLUGINS = B3DAcceleratorPlugin Squeak3D ClipboardExtendedPlugin DBusPlugin SqueakFFIPrims FileCopyPlugin GStreamerPlugin HostWindowPlugin KedamaPlugin KedamaPlugin2 MIDIPlugin Mpeg3Plugin RomePlugin UUIDPlugin AioPlugin UnixOSProcessPlugin XDisplayControlPlugin
Modified: trunk/platforms/unix/src/vm/intplugins/ADPCMCodecPlugin/ADPCMCodecPlugin.c
===================================================================
--- trunk/platforms/unix/src/vm/intplugins/ADPCMCodecPlugin/ADPCMCodecPlugin.c 2011-01-23 07:34:41 UTC (rev 2354)
+++ trunk/platforms/unix/src/vm/intplugins/ADPCMCodecPlugin/ADPCMCodecPlugin.c 2011-01-23 09:41:21 UTC (rev 2355)
@@ -1,4 +1,4 @@
-/* Automatically generated from Squeak on 23 January 2011 3:55:22 pm
+/* Automatically generated from Squeak on 23 January 2011 6:33:58 pm
    by VMMaker 4.4.7
  */
 
Modified: trunk/platforms/unix/src/vm/intplugins/SoundGenerationPlugin/SoundGenerationPlugin.c
===================================================================
--- trunk/platforms/unix/src/vm/intplugins/SoundGenerationPlugin/SoundGenerationPlugin.c 2011-01-23 07:34:41 UTC (rev 2354)
+++ trunk/platforms/unix/src/vm/intplugins/SoundGenerationPlugin/SoundGenerationPlugin.c 2011-01-23 09:41:21 UTC (rev 2355)
@@ -1,4 +1,4 @@
-/* Automatically generated from Squeak on 23 January 2011 3:55:48 pm
+/* Automatically generated from Squeak on 23 January 2011 6:34:01 pm
    by VMMaker 4.4.7
  */
 
Modified: trunk/platforms/unix/src/vm/sqNamedPrims.h
===================================================================
--- trunk/platforms/unix/src/vm/sqNamedPrims.h 2011-01-23 07:34:41 UTC (rev 2354)
+++ trunk/platforms/unix/src/vm/sqNamedPrims.h 2011-01-23 09:41:21 UTC (rev 2355)
@@ -1,4 +1,4 @@
-/* Automatically generated from Squeak on 23 January 2011 3:55:49 pm
+/* Automatically generated from Squeak on 23 January 2011 6:34:01 pm
    by VMMaker 4.4.7
  */
 /* This is an automatically generated table of all builtin modules in the VM */