bool HelloWorldUpdate() { if(s3eKeyboardGetState(s3eKeyBack) & S3E_KEY_STATE_RELEASED) { s3eDebugTraceLine("back check"); std::hash_map<char*, char*>::iterator ihashMap; if(hashMap.size() > 1) { ihashMap = hashMap.find("ShowAt"); if(ihashMap->second == "both"){ vservManagerFetchingAdData(); }else if(ihashMap->second == "end") { vservManagerFetchingAdData(); } else if(ihashMap->second == "start"){ s3eDeviceExit(); return false; } } } if(CheckButtonStatus("Exit") & S3E_KEY_STATE_RELEASED) /*S3E_KEY_STATE_PRESSED)*/ { s3eDebugTraceLine("Exit check"); HelloWorldShutDown(); return false; } return true; }
void HelloWorldShutDown() { std::hash_map<char*, char*>::iterator ihashMap; if(hashMap.size() > 1) { ihashMap = hashMap.find("ShowAt"); s3eSurfaceUnRegister(S3E_SURFACE_SCREENSIZE, HelloWorldRotationCallBack); if(ihashMap->second == "end" || ihashMap->second == "both"){ vservManagerFetchingAdData(); } else if(ihashMap->second == "start"){ s3eDeviceExit(); } } }
//all shapes are loaded from same image file to reduce file I/O and caching //thiss also allows animated images to be self-contained void PianoRenderCache::Piano_load_shapes(RenderBuffer &buffer, const wxString& filename) { debug_function(10); //Debug debug("load_shapes('%s')", (const char*)filename.c_str()); debug(1, "load shapes file '%s'", (const char*)filename.c_str()); //reload shapes even if file name hasn't changed; color map might be different now // if (!CachedShapeFilename.CmpNoCase(filename)) { debug_more(2, ", no change"); return; } //no change if (!wxFileExists(filename)) return; Piano_flush_shapes(); //invalidate cached data if (!Shapes.LoadFile(filename, wxBITMAP_TYPE_ANY, 0) || !Shapes.IsOk()) { //wxMessageBox("Error loading image file: "+NewPictureName); Shapes.Clear(); return; } if (buffer.GetColorCount() < 2) return; //use colors from shapes file if no user-selected colors // int imgwidth=image.GetWidth(); // int imght =image.GetHeight(); // std::hash_map<WXCOLORREF, int> palcounts; //TODO: use wxImage.GetData for better performance? //TODO: use multiple images within same file? for (int y = Shapes.GetHeight() - 1; y >= 0; --y) //bottom->top for (int x = 0; x < Shapes.GetWidth(); ++x) //left->right if (!Shapes.IsTransparent(x, y)) { xlColor color, mapped; color.Set(Shapes.GetRed(x, y), Shapes.GetGreen(x, y), Shapes.GetBlue(x, y)); if (ColorMap.find(color.GetRGB()) != ColorMap.end()) continue; //already saw this color buffer.palette.GetColor(ColorMap.size() % buffer.GetColorCount(), mapped); //assign user-selected colors to shape palette sequentially, loop if run out of colors debug(10, "shape color[%d] 0x%x => user-selected color [%d] 0x%x", ColorMap.size(), color.GetRGB(), ColorMap.size() % GetColorCount(), mapped.GetRGB()); ColorMap[color.GetRGB()] = mapped; //.GetRGB(); // ShapePalette.push_back(c.GetRGB()); //keep a list of unique colors in order of occurrence from origin L-R, B-T } debug(2, "w %d, h %d, #colors %d", Shapes.GetWidth(), Shapes.GetHeight(), ColorMap.size()); CachedShapeFilename = filename; //don't load same file again }
//-------------------------------------------------------------------------- // Main global function //-------------------------------------------------------------------------- int main() { std::hash_map<char*, char*>::iterator ihashMap; hashInit(); vservManagerInit(hashMap); if(hashMap.size() > 1) { ihashMap = hashMap.find("ShowAt"); if(ihashMap->second == "start" || ihashMap->second == "both"){ vservManagerFetchingAdData(); } else{ HelloWorldMain(); } } return 0; }
bool PianoRenderCache::Piano_RenderKey(RenderBuffer &buffer, Sprite* sprite, std::hash_map<wxPoint_, int>& drawn, int style, wxSize& canvas, wxSize& keywh, const wxString &placement, bool clip) //bool RgbEffects::Sprite::render(wxSize& keywh, wxSize& BufferWH_int, int yscroll, bool Clipping) { debug_function(9); //hash_map<pair<wxPoint, wxSize>, int>& drawn) //PIANO_STYLE_KEYS sprites have 2 states: on (down) and off (up); draw all sprites; top view or edge view int drawstate = sprite->ani_state++; //bump to next active (animation) state if (!drawstate) sprite->ani_state = 0; //stay in inactive state else // if ((xy.size() == 1) && (drawstate == -1)) return false; //inactive on/off sprite; don't need tp draw anything if (drawstate >= sprite->xy.size()) //end of animation // if (it->repeat > 0) drawstate = 0; //loop immediately // else if (it->repeat < 0) drawstate = -rnd(); //loop with delay /*else*/ drawstate = sprite->xy.size() - 1; //stay at last state; don't loop // wxPoint realxy = sprite->destxy; // realxy.y += yscroll; //scrolling debug_more(30, ", dest (%d => %d, %d), #drawn %d", sprite->destxy.x, (clip? sprite->destxy.x: sprite->destxy.x % canvas.x), sprite->destxy.y, drawn.size()); if (clip) if ((sprite->destxy.x >= buffer.BufferWi) || (sprite->destxy.y >= buffer.BufferHt) || (sprite->destxy.x + keywh.x < 0) || (sprite->destxy.y + keywh.y < 0)) return false; //outside of visible rect // debug_more(30, ", here1"); wxPoint_ where = sprite->destxy.y * 65536 + (clip? sprite->destxy.x: sprite->destxy.x % canvas.x); //wrap on even key boundary // debug_more(30, ", here2"); if ((style != PIANO_STYLE_ANIMAGE) && (drawn.find(where) != drawn.end()) && (drawstate <= drawn[where])) { debug_more(30, ", already drawn[0x%x]=%d vs %d", where, drawn[where], drawstate); return false; } //do not redraw older states in same location drawn[where] = drawstate; //remember highest state drawn in this location //don't draw overlapping regions more than once // SetPixel(x-xoffset,(state % ((imght+BufferHt)*speedfactor)) / speedfactor-y,c); //moving up // SetPixel(x-xoffset,BufferHt+imght-y-(state % ((imght+BufferHt)*speedfactor)) / speedfactor,c); //moving down //copy sprite image to pixel buffer, scale up/down: //iterate thru target pixels and pull from sprite in case sizes don't match (need to set all target pixels, but okay to skip some source pixels) float xscale = (float)sprite->wh.x / keywh.x, yscale = (float)sprite->wh.y / keywh.y; //src -> dest scale factor // debug_more(30, ", here3"); //TODO: use wxImage.GetData for better performance? int xofs = !clip? (buffer.BufferWi % (7 * keywh.x)) / 2: 0; //center keys if not clipped if (WantHistory(style)) debug(20, "draw sprite '%s': set x/y %d/%d + %d/%d to 0x%x", (const char*)sprite->name.ToStdString().c_str(), sprite->destxy.x, sprite->destxy.y, keywh.x, keywh.y, drawstate? sprite->on.GetRGB(): sprite->off.GetRGB()); //.Flush(true); else debug(20, "draw sprite '%s': copy from x/y[%d/%d] %d/%d + %d/%d => x/y %d/%d + %d/%d, x/y scale = %f/%f", (const char*)sprite->name.ToStdString().c_str(), drawstate, sprite->xy.size(), sprite->xy[drawstate].x, sprite->xy[drawstate].y, sprite->wh.x, sprite->wh.y, sprite->destxy.x, sprite->destxy.y, keywh.x, keywh.y, 1.0 / xscale, 1.0 / yscale); //.Flush(true); for (int x = 0; x < keywh.x; ++x) //copying to it->w columns in dest for (int y = 0; y < keywh.y; ++y) //copying to it->h rows in dest; vert scaling is more likely, so make Y the inner loop for better pixel caching { // static xlColor cached_rgb; //cached mapped pixel color // static wxPoint cached_xy(-1, -1); wxPoint src_xy(sprite->xy[drawstate].x + x * xscale, sprite->xy[drawstate].y + y * yscale); //TODO: scale doesn't make sense for all cases src_xy.y = Shapes.GetHeight() - src_xy.y - 1; //whoops, origin is top left but wanted bottom left bool transparent = 0; if (WantHistory(style)) cached_rgb = drawstate? sprite->on: sprite->off; //kludge: fill rect with same color to avoid losing pixels due to scaling else if ((src_xy.x != cached_xy.x) || (src_xy.y != cached_xy.y)) //update cached pixel info { cached_xy = src_xy; //prev_xy.x = src_xy.x; prev_y = srcy; //not sure how expensive wx pixel functions are, so cache current pixel info just in case; aliasing/averaging and color mapping also makes thiss more expensive if (Shapes.IsTransparent(src_xy.x, src_xy.y)) transparent = 1; //-1; //-1 matches white, so use + instead else { // xlColor c; //TODO: tile, center, anti-aliasing cached_rgb.Set(Shapes.GetRed(src_xy.x, src_xy.y), Shapes.GetGreen(src_xy.x, src_xy.y), Shapes.GetBlue(src_xy.x, src_xy.y)); //NOTE: need to do pixel merging if scale is not 1:1 if (!ColorMap.empty()) cached_rgb = ColorMap[cached_rgb.GetRGB()]; //map to user-selected colors } debug_more(20, ", LK(%d,%d)", cached_xy.x, cached_xy.y); } if (transparent == 1 /*-1*/) continue; //don't need to draw pixel int wrapx = sprite->destxy.x + x, scrolly = sprite->destxy.y; // if (style == PIANO_STYLE_ANIMAGE) { wrapx *= xscale; scrolly *= yscale; } if (!clip) wrapx %= canvas.x; //wrap on even key boundary // if ((style == PIANO_STYLE_ICICLES) || (style == PIANO_STYLE_EQBARS)) scrolly += canvas.y - keywh.y; //draw at top instead of bottom if (style == PIANO_STYLE_ICICLES) scrolly += canvas.y - keywh.y; //draw at top instead of bottom // debug_more(20, ", %d+%d vs. %d-%d? %d", xofs, wrapx, BufferWi, xofs, xofs + wrapx < BufferWi - xofs); // if (!clip) wrapx = (wrapx + 2 * xofs) % BufferWi - 2 * xofs; //wrap within reduced area, not expanded area debug_more(20, ", (%d,%d)<-0x%x", wrapx, sprite->destxy.y + y, cached_rgb.GetRGB()); if (xofs + wrapx < buffer.BufferWi - xofs) buffer.SetPixel(xofs + wrapx, sprite->destxy.y + y, cached_rgb); //no vertical wrap, only horizontal wrap } // debug.Flush(true); return true; }
//map sprites to screen location: void PianoRenderCache::Piano_load_sprite_map(const wxString& filename) //, int BufferWi, int BufferHt) //, bool clip) { debug_function(10); debug(1, "load sprite map file %s", (const char*)filename.c_str()); wxTextFile f; int numbad = 0; if (!CachedMapFilename.CmpNoCase(filename)) { debug_more(2, ", no change"); return; } //no change if (!wxFileExists(filename)) return; if (!f.Open(filename.c_str())) return; Piano_flush_map(); //invalidate cached data debug(3, "read file"); for (wxString linebuf = f.GetFirstLine(); !f.Eof(); linebuf = f.GetNextLine()) { std::string::size_type ofs; if ((ofs = linebuf.find("#")) != std::string::npos) linebuf.erase(ofs); //remove comments while (!linebuf.empty() && (linebuf.Last() == '\\')) //line continuation { linebuf.RemoveLast(); //remove trailing "\" /*std::*/wxString morebuf = f.GetNextLine(); if (f.Eof()) break; linebuf += morebuf; } while (!linebuf.empty() && isspace(linebuf.Last())) linebuf.RemoveLast(); //trim trailing spaces if (linebuf.empty()) continue; //skip blank lines //#Sprite-name Xon Yon Xoff Yoff W H DestX DestY DestZ debug(20, "got line '%s'", (const char*)linebuf.c_str()); linebuf += "\teol"; //end-of-line check for missing params wxStringTokenizer tkz(linebuf, "\t"); Sprite spr; spr.name = tkz.GetNextToken(); //first column = sprite name if (spr.name.find(".") == -1) spr.name += ".000"; //kludge: change name to match Audacity Polyphonic nodes int srcx_on = wxAtoi(tkz.GetNextToken()); //x coordinate for "on" state int srcy_on = wxAtoi(tkz.GetNextToken()); //y coordinate for "on" state int srcx_off = wxAtoi(tkz.GetNextToken()); //x coordinate for "off" state int srcy_off = wxAtoi(tkz.GetNextToken()); //y coordinate for "off" state spr.wh.x = wxAtoi(tkz.GetNextToken()); //sprite width spr.wh.y = wxAtoi(tkz.GetNextToken()); //spriate height spr.destxy.x = wxAtoi(tkz.GetNextToken()); //destination x coordinate spr.destxy.y = wxAtoi(tkz.GetNextToken()); //destination y coordinate spr.destz = wxAtoi(tkz.GetNextToken()); //destination layer // if (spr.destz > 10) spr.destz = 10; //limit to 10 layers wxString junk = tkz.GetNextToken(); if (/* !junk.empty()*/ junk.Cmp("eol")) { debug_more(20, ", junk at end '%s'", (const char*)junk.c_str()); continue; } //TODO: show error messages? debug_more(10, " => srcx/y on %d/%d, off %d/%d, sprite w/h %d/%d, dest x/y/z %d/%d/%d, junk? '%s'", srcx_on, srcy_on, srcx_off, srcy_off, spr.wh.x, spr.wh.y, spr.destxy.x, spr.destxy.y, spr.destz, (const char*)junk.c_str()); // if (!clip) { spr.destxy.x %= BufferWi; spr.destxy.y %= BufferWi; } //wrap // else if ((spr.destxy.x >= BufferWi) || (spr.destxy.y >= BufferHi) || (spr.destxy.x + keyw < 0) || (spr.destxy.y + keyh < 0)) continue; //outside of visible rect if ((srcx_off != srcx_on) || (srcy_off != srcy_on)) //need to draw when off also { if ((srcx_off < 0) || (srcx_off + spr.wh.x > Shapes.GetWidth()) || (srcy_off < 0) || (srcy_off + spr.wh.y > Shapes.GetHeight())) { debug_more(10, ": NO1"); ++numbad; continue; } //ignore invalid sprites spr.xy.push_back(wxPoint(srcx_off, srcy_off)); //state 0 == key off/up spr.off = find_color(Shapes, ColorMap, spr.xy.back(), spr.wh, "off"); } if ((srcx_on < 0) || (srcx_on + spr.wh.x > Shapes.GetWidth()) || (srcy_on < 0) || (srcy_on + spr.wh.y > Shapes.GetHeight())) { debug_more(10, ": NO2"); ++numbad; continue; } //ignore invalid sprites spr.xy.push_back(wxPoint(srcx_on, srcy_on)); //state 1 == key on/down spr.on = find_color(Shapes, ColorMap, spr.xy.back(), spr.wh, "on"); spr.ani_state = 0; //inactive // spr.repeat = 0; AllSprites[spr.name.ToStdString()] = spr; // if (spr.destz >= ByLayer.size()) ByLayer.resize(spr.destz + 1); //add new layer // ByLayer[spr.destz].push_back(&AllSprites[spr.name.ToStdString()]); debug_more(10, ", added '%s' ok? %d", spr.name.ToStdString().c_str(), AllSprites.find(spr.name.ToStdString()) != AllSprites.end()); } debug(1, "%d shapes loaded, %d invalid", AllSprites.size(), numbad); //, ByLayer.size()); CachedMapFilename = filename; //don't load same file again }