void DisplayBuffer::setChar(int16_t x, int16_t y, unsigned char c, uint8_t color) { uint16_t displayIdx = y*NUM_CHAR_COLUMNS + x; m_displayBuffer[displayIdx] = c; m_colorBuffer[displayIdx] = color; if(m_pOutputDisplay != NULL) { //Serial.println((int)color, 16); uint16_t fg = lookupColor((color >> 4) & 0x0F); uint16_t bg = lookupColor(color & 0x0F); m_pOutputDisplay->drawFastChar(x*CHAR_WIDTH, y*CHAR_HEIGHT, c, fg, bg); }
void eListboxPythonMultiContent::paint(gPainter &painter, eWindowStyle &style, const ePoint &offset, int selected) { gRegion itemregion(eRect(offset, m_itemsize)); eListboxStyle *local_style = 0; eRect sel_clip(m_selection_clip); bool cursorValid = this->cursorValid(); gRGB border_color; int border_size = 0; if (sel_clip.valid()) sel_clip.moveBy(offset); /* get local listbox style, if present */ if (m_listbox) { local_style = m_listbox->getLocalStyle(); border_size = local_style->m_border_size; border_color = local_style->m_border_color; } painter.clip(itemregion); clearRegion(painter, style, local_style, ePyObject(), ePyObject(), ePyObject(), ePyObject(), selected, itemregion, sel_clip, offset, cursorValid); ePyObject items, buildfunc_ret; if (m_list && cursorValid) { /* a multicontent list can be used in two ways: either each item is a list of (TYPE,...)-tuples, or there is a template defined, which is a list of (TYPE,...)-tuples, and the list is an unformatted tuple. The template then references items from the list. */ items = PyList_GET_ITEM(m_list, m_cursor); // borrowed reference! if (m_buildFunc) { if (PyCallable_Check(m_buildFunc)) // when we have a buildFunc then call it { if (PyTuple_Check(items)) buildfunc_ret = items = PyObject_CallObject(m_buildFunc, items); else eDebug("[eListboxPythonMultiContent] items is no tuple"); } else eDebug("[eListboxPythonMultiContent] buildfunc is not callable"); } if (!items) { eDebug("[eListboxPythonMultiContent] error getting item %d", m_cursor); goto error_out; } if (!m_template) { if (!PyList_Check(items)) { eDebug("[eListboxPythonMultiContent] list entry %d is not a list (non-templated)", m_cursor); goto error_out; } } else { if (!PyTuple_Check(items)) { eDebug("[eListboxPythonMultiContent] list entry %d is not a tuple (templated)", m_cursor); goto error_out; } } ePyObject data; /* if we have a template, use the template for the actual formatting. we will later detect that "data" is present, and refer to that, instead of the immediate value. */ int start = 1; if (m_template) { data = items; items = m_template; start = 0; } int size = PyList_Size(items); for (int i = start; i < size; ++i) { ePyObject item = PyList_GET_ITEM(items, i); // borrowed reference! if (!item) { eDebug("[eListboxPythonMultiContent] ?"); goto error_out; } if (!PyTuple_Check(item)) { eDebug("[eListboxPythonMultiContent] did not receive a tuple."); goto error_out; } int size = PyTuple_Size(item); if (!size) { eDebug("[eListboxPythonMultiContent] receive empty tuple."); goto error_out; } int type = PyInt_AsLong(PyTuple_GET_ITEM(item, 0)); switch (type) { case TYPE_TEXT: // text { /* (0, x, y, width, height, fnt, flags, "bla" [, color, colorSelected, backColor, backColorSelected, borderWidth, borderColor] ) */ ePyObject px = PyTuple_GET_ITEM(item, 1), py = PyTuple_GET_ITEM(item, 2), pwidth = PyTuple_GET_ITEM(item, 3), pheight = PyTuple_GET_ITEM(item, 4), pfnt = PyTuple_GET_ITEM(item, 5), pflags = PyTuple_GET_ITEM(item, 6), pstring = PyTuple_GET_ITEM(item, 7), pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, pborderWidth, pborderColor; if (!(px && py && pwidth && pheight && pfnt && pflags && pstring)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_TEXT, x, y, width, height, fnt, flags, string [, color, backColor, backColorSelected, borderWidth, borderColor])"); goto error_out; } if (size > 8) pforeColor = lookupColor(PyTuple_GET_ITEM(item, 8), data); if (size > 9) pforeColorSelected = lookupColor(PyTuple_GET_ITEM(item, 9), data); if (size > 10) pbackColor = lookupColor(PyTuple_GET_ITEM(item, 10), data); if (size > 11) pbackColorSelected = lookupColor(PyTuple_GET_ITEM(item, 11), data); if (size > 12) { pborderWidth = PyTuple_GET_ITEM(item, 12); if (pborderWidth == Py_None) pborderWidth=ePyObject(); } if (size > 13) pborderColor = lookupColor(PyTuple_GET_ITEM(item, 13), data); if (PyInt_Check(pstring) && data) /* if the string is in fact a number, it refers to the 'data' list. */ pstring = PyTuple_GetItem(data, PyInt_AsLong(pstring)); /* don't do anything if we have 'None' as string */ if (pstring == Py_None) continue; const char *string = (PyString_Check(pstring)) ? PyString_AsString(pstring) : "<not-a-string>"; int x = PyInt_AsLong(px) + offset.x(); int y = PyInt_AsLong(py) + offset.y(); int width = PyInt_AsLong(pwidth); int height = PyInt_AsLong(pheight); int flags = PyInt_AsLong(pflags); int fnt = PyInt_AsLong(pfnt); int bwidth = pborderWidth ? PyInt_AsLong(pborderWidth) : 0; if (m_font.find(fnt) == m_font.end()) { eDebug("[eListboxPythonMultiContent] specified font %d was not found!", fnt); goto error_out; } eRect rect(x+bwidth, y+bwidth, width-bwidth*2, height-bwidth*2); painter.clip(rect); { gRegion rc(rect); bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor); clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear); } painter.setFont(m_font[fnt]); painter.renderText(rect, string, flags, border_color, border_size); painter.clippop(); // draw border if (bwidth) { eRect rect(eRect(x, y, width, height)); painter.clip(rect); if (pborderColor) { unsigned int color = PyInt_AsUnsignedLongMask(pborderColor); painter.setForegroundColor(gRGB(color)); } rect.setRect(x, y, width, bwidth); painter.fill(rect); rect.setRect(x, y+bwidth, bwidth, height-bwidth); painter.fill(rect); rect.setRect(x+bwidth, y+height-bwidth, width-bwidth, bwidth); painter.fill(rect); rect.setRect(x+width-bwidth, y+bwidth, bwidth, height-bwidth); painter.fill(rect); painter.clippop(); } break; } case TYPE_PROGRESS_PIXMAP: // Progress /* (1, x, y, width, height, filled_percent, pixmap [, borderWidth, foreColor, foreColorSelected, backColor, backColorSelected] ) */ case TYPE_PROGRESS: // Progress { /* (1, x, y, width, height, filled_percent [, borderWidth, foreColor, foreColorSelected, backColor, backColorSelected] ) */ ePyObject px = PyTuple_GET_ITEM(item, 1), py = PyTuple_GET_ITEM(item, 2), pwidth = PyTuple_GET_ITEM(item, 3), pheight = PyTuple_GET_ITEM(item, 4), pfilled_perc = PyTuple_GET_ITEM(item, 5), ppixmap, pborderWidth, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected; int idx = 6; if (type == TYPE_PROGRESS) { if (!(px && py && pwidth && pheight && pfilled_perc)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_PROGRESS, x, y, width, height, filled percent [,border width, foreColor, backColor, backColorSelected]))"); goto error_out; } } else { ppixmap = PyTuple_GET_ITEM(item, idx++); if (ppixmap == Py_None) continue; if (!(px && py && pwidth && pheight && pfilled_perc, ppixmap)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_PROGRESS_PIXMAP, x, y, width, height, filled percent, pixmap, [,border width, foreColor, backColor, backColorSelected]))"); goto error_out; } } if (size > idx) { pborderWidth = PyTuple_GET_ITEM(item, idx++); if (pborderWidth == Py_None) pborderWidth = ePyObject(); } if (size > idx) { pforeColor = PyTuple_GET_ITEM(item, idx++); if (pforeColor == Py_None) pforeColor = ePyObject(); } if (size > idx) { pforeColorSelected = PyTuple_GET_ITEM(item, idx++); if (pforeColorSelected == Py_None) pforeColorSelected=ePyObject(); } if (size > idx) { pbackColor = PyTuple_GET_ITEM(item, idx++); if (pbackColor == Py_None) pbackColor=ePyObject(); } if (size > idx) { pbackColorSelected = PyTuple_GET_ITEM(item, idx++); if (pbackColorSelected == Py_None) pbackColorSelected=ePyObject(); } int x = PyInt_AsLong(px) + offset.x(); int y = PyInt_AsLong(py) + offset.y(); int width = PyInt_AsLong(pwidth); int height = PyInt_AsLong(pheight); int filled = PyInt_AsLong(pfilled_perc); if ((filled < 0) && data) /* if the string is in a negative number, it refers to the 'data' list. */ filled = PyInt_AsLong(PyTuple_GetItem(data, -filled)); /* don't do anything if percent out of range */ if ((filled < 0) || (filled > 100)) continue; int bwidth = pborderWidth ? PyInt_AsLong(pborderWidth) : 2; eRect rect(x, y, width, height); painter.clip(rect); { gRegion rc(rect); bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor); clearRegion(painter, style, local_style, pforeColor, pforeColorSelected, pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear); } // border if (bwidth) { rect.setRect(x, y, width, bwidth); painter.fill(rect); rect.setRect(x, y+bwidth, bwidth, height-bwidth); painter.fill(rect); rect.setRect(x+bwidth, y+height-bwidth, width-bwidth, bwidth); painter.fill(rect); rect.setRect(x+width-bwidth, y+bwidth, bwidth, height-bwidth); painter.fill(rect); } rect.setRect(x+bwidth, y+bwidth, (width-bwidth*2) * filled / 100, height-bwidth*2); // progress if (ppixmap) { ePtr<gPixmap> pixmap; if (PyInt_Check(ppixmap) && data) /* if the pixmap is in fact a number, it refers to the data list */ ppixmap = PyTuple_GetItem(data, PyInt_AsLong(ppixmap)); if (SwigFromPython(pixmap, ppixmap)) { eDebug("[eListboxPythonMultiContent] (Pixmap) get pixmap failed"); painter.clippop(); continue; } painter.blit(pixmap, rect.topLeft(), rect, 0); } else painter.fill(rect); painter.clippop(); break; } case TYPE_PIXMAP_ALPHABLEND: case TYPE_PIXMAP_ALPHATEST: case TYPE_PIXMAP: // pixmap { /* (2, x, y, width, height, pixmap [, backColor, backColorSelected] ) */ ePyObject px = PyTuple_GET_ITEM(item, 1), py = PyTuple_GET_ITEM(item, 2), pwidth = PyTuple_GET_ITEM(item, 3), pheight = PyTuple_GET_ITEM(item, 4), ppixmap = PyTuple_GET_ITEM(item, 5), pbackColor, pbackColorSelected; if (!(px && py && pwidth && pheight && ppixmap)) { eDebug("[eListboxPythonMultiContent] received too small tuple (must be (TYPE_PIXMAP, x, y, width, height, pixmap [, backColor, backColorSelected] ))"); goto error_out; } if (PyInt_Check(ppixmap) && data) /* if the pixemap is in fact a number, it refers to the 'data' list. */ ppixmap = PyTuple_GetItem(data, PyInt_AsLong(ppixmap)); /* don't do anything if we have 'None' as pixmap */ if (ppixmap == Py_None) continue; int x = PyInt_AsLong(px) + offset.x(); int y = PyInt_AsLong(py) + offset.y(); int width = PyInt_AsLong(pwidth); int height = PyInt_AsLong(pheight); int flags = 0; ePtr<gPixmap> pixmap; if (SwigFromPython(pixmap, ppixmap)) { eDebug("[eListboxPythonMultiContent] (Pixmap) get pixmap failed"); goto error_out; } if (size > 6) pbackColor = lookupColor(PyTuple_GET_ITEM(item, 6), data); if (size > 7) pbackColorSelected = lookupColor(PyTuple_GET_ITEM(item, 7), data); if (size > 8) flags = PyInt_AsLong(PyTuple_GET_ITEM(item, 8)); eRect rect(x, y, width, height); painter.clip(rect); { gRegion rc(rect); bool mustClear = (selected && pbackColorSelected) || (!selected && pbackColor); clearRegion(painter, style, local_style, ePyObject(), ePyObject(), pbackColor, pbackColorSelected, selected, rc, sel_clip, offset, cursorValid, mustClear); } flags |= (type == TYPE_PIXMAP_ALPHATEST) ? gPainter::BT_ALPHATEST : (type == TYPE_PIXMAP_ALPHABLEND) ? gPainter::BT_ALPHABLEND : 0; if (flags & gPainter::BT_SCALE) painter.blitScale(pixmap, rect, rect, flags); else painter.blit(pixmap, rect.topLeft(), rect, flags); painter.clippop(); break; } default: eWarning("[eListboxPythonMultiContent] received unknown type (%d)", type); goto error_out; } } } if (selected && !sel_clip.valid() && (!local_style || !local_style->m_selection)) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry); error_out: if (buildfunc_ret) Py_DECREF(buildfunc_ret); painter.clippop(); }
void loadFileMap (const char *filename) { FILE * fh; char line[16384]; char tempstr[16384]; char* tmpStr; int fileLines = 0; int globHeight = 0; maxX = 0; minX = 0; maxY = 0; minY = 0; #ifdef ZBTEMP maxZ = 0; minZ = 0; #endif numLocations = 0; numLines = 0; int numPoints = 0; if ((fh = fopen (filename, "r")) != NULL) { fgets (line, 4095, fh); tmpStr = strtok (line, ","); if (tmpStr == NULL) { fprintf(stderr, "Map '%s' appears to be seriously messed up! No Zone Name!\n", filename); return; } strcpy (zoneLong, tmpStr); // Zone name tmpStr = strtok (NULL, ","); if (tmpStr == NULL) { fprintf(stderr, "Map '%s' appears to be seriously messed up! No Short Zone Name!\n", filename); return; } strcpy (zoneShort, tmpStr); // Zone short name fileLines++; while (fgets (line, 16383, fh)) { fileLines++; strcpy (tempstr, strtok (line, ",")); switch (tempstr[0]) { case 'H': tmpStr = strtok (NULL, ",\n"); if (tmpStr == NULL) { fprintf(stderr, "Line %d in map '%s' has an H marker with no Z!\n", fileLines, filename); break; } globHeight = atoi(tmpStr); break; case 'L': case 'M': // don't know if this is right, but what the hell... // L = 0, M = 1 lineType[numLines] = tempstr[0] - 'L'; // Line name tmpStr = strtok (NULL, ","); if (tmpStr == NULL) { fprintf(stderr, "Error reading line name on line %d in map '%s'\n", fileLines, filename); break; } // Line color tmpStr = strtok (NULL, ","); if (tmpStr == NULL) { fprintf(stderr, "Error reading line color on line %d in map '%s'\n", fileLines, filename); break; } lineColor[numLines] = lookupColor (tmpStr); // Number of points tmpStr = strtok (NULL, ","); if (tmpStr == NULL) { fprintf(stderr, "Error reading number of points on line %d in map '%s'\n", fileLines, filename); break; } linePoints[numLines] = atoi (tmpStr); if (linePoints[numLines] > maxPoints) maxPoints = linePoints[numLines]; numPoints = 0; while (1) { tmpStr = strtok (NULL, ",\n"); if (tmpStr == NULL) break; lineX[numLines][numPoints] = atoi (tmpStr); tmpStr = strtok (NULL, ",\n"); if (tmpStr == NULL) { fprintf(stderr, "Line %d in map '%s' has point %d with an X coordinate with no Y!\n", fileLines, filename, numPoints); break; } lineY[numLines][numPoints] = atoi (tmpStr); // currently if it's type M, just eat the Z coord if (lineType[numLines] == 1) { tmpStr = strtok (NULL, ",\n"); if (tmpStr == NULL) { fprintf(stderr, "Line %d in map '%s' has point %d with an X & Y coordinates with no Z with lineType = M!\n", fileLines, filename, numPoints); // should probably abort, here, but hey, see if it works... lineZ[numLines][numPoints] = globHeight; } else lineZ[numLines][numPoints] = atoi (tmpStr); } else lineZ[numLines][numPoints] = globHeight; if (lineX[numLines][numPoints] > maxX) maxX = lineX[numLines][numPoints]; if (lineY[numLines][numPoints] > maxY) maxY = lineY[numLines][numPoints]; if (lineX[numLines][numPoints] < minX) minX = lineX[numLines][numPoints]; if (lineY[numLines][numPoints] < minY) minY = lineY[numLines][numPoints]; #ifdef ZBTEMP if (lineZ[numLines][numPoints] > maxY) maxZ = lineZ[numLines][numPoints]; if (lineZ[numLines][numPoints] < minY) minZ = lineZ[numLines][numPoints]; #endif numPoints++; } if (numPoints > maxPointsReal) maxPointsReal = numPoints; if (numPoints > linePoints[numLines]) { fprintf(stderr, "Line %d in map '%s' has more points (%d > %d) then specified!\n", fileLines, filename, numPoints, linePoints[numLines]); linePoints[numLines] = numPoints; } else if (numPoints < linePoints[numLines]) { fprintf(stderr, "Line %d in map '%s' has fewer points (%d < %d) then specified!\n", fileLines, filename, numPoints, linePoints[numLines]); linePoints[numLines] = numPoints; } numLines++; break; case 'P': // Location name locationName[numLocations] = strtok (NULL, ","); // Location color locationColor[numLocations] = lookupColor(strtok (NULL, ",")); locationX[numLocations] = atoi (strtok (NULL, ",\n")); locationY[numLocations] = atoi (strtok (NULL, ",\n")); // if map label isn't inside map dimensions, change map size if (locationX[numLocations] > maxX) maxX = locationX[numLocations]; if (locationY[numLocations] > maxY) maxY = locationY[numLocations]; if (locationX[numLocations] < minX) minX = locationX[numLocations]; if (locationY[numLocations] < minY) minY = locationY[numLocations]; numLocations++; break; } } fclose (fh); char message[128]; sprintf (message, "%s [%s]", zoneLong, zoneShort); reAdjust (); } #ifdef ZBTEMP fprintf(stderr, "Max Points theoretically in any Line: %d\n", maxPoints); fprintf(stderr, "Max Points really in any Line: %d\n", maxPointsReal); fprintf(stderr, "Min Z in Zone: %d\n", minZ); fprintf(stderr, "Max Z in Zone: %d\n", maxZ); #endif }
// shadePixel -- // // Computes the contribution of the specified circle to the // given pixel. All values are provided in normalized space, where // the screen spans [0,2]^2. The color/opacity of the circle is // computed at the pixel center. void RefRenderer::shadePixel( int circleIndex, float pixelCenterX, float pixelCenterY, float px, float py, float pz, float* pixelData) { float diffX = px - pixelCenterX; float diffY = py - pixelCenterY; float pixelDist = diffX * diffX + diffY * diffY; float rad = radius[circleIndex]; float maxDist = rad * rad; // circle does not contribute to the image if (pixelDist > maxDist) return; float colR, colG, colB; float alpha; // there is a non-zero contribution. Now compute the shading if (sceneName == SNOWFLAKES || sceneName == SNOWFLAKES_SINGLE_FRAME) { // Snowflake opacity falls off with distance from center. // Snowflake color is determined by distance from center and // radially symmetric. The color value f(dist) is looked up // from a table. const float kCircleMaxAlpha = .5f; const float falloffScale = 4.f; float normPixelDist = sqrt(pixelDist) / rad; lookupColor(normPixelDist, colR, colG, colB); float maxAlpha = kCircleMaxAlpha * CLAMP(.6f + .4f * (1.f-pz), 0.f, 1.f); alpha = maxAlpha * exp(-1.f * falloffScale * normPixelDist * normPixelDist); } else { // simple: each circle has an assigned color int index3 = 3 * circleIndex; colR = color[index3]; colG = color[index3+1]; colB = color[index3+2]; alpha = .5f; } // The following code is *very important*: it blends the // contribution of the circle primitive with the current state // of the output image pixel. This is a read-modify-write // operation on the image, and it needs to be atomic. Moreover, // (and even more challenging) all writes to this pixel must be // performed in same order as when the circles are processed // serially. // // That is, if circle 1 and circle 2 both write to pixel P. // circle 1's contribution *must* be blended in first, then // circle 2's. If this invariant is not preserved, the // rendering of transparent circles will not be correct. float oneMinusAlpha = 1.f - alpha; pixelData[0] = alpha * colR + oneMinusAlpha * pixelData[0]; pixelData[1] = alpha * colG + oneMinusAlpha * pixelData[1]; pixelData[2] = alpha * colB + oneMinusAlpha * pixelData[2]; pixelData[3] += alpha; }