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 */ |
Free forum by Nabble | Edit this page |