//					System.out.println("LOADIMAGECOMPRESSED: handle="+handle+" imagePtr="+imagePtr+" len2="+len2);
public int ExecuteGFXCommand(int cmd, int len, byte[] cmddata, int[] hasret)
	{
		len -= 4; // for the 4 byte header
	    hasret[0] = 0; // Nothing to return by default
//		System.out.println("GFXCMD=" + cmd);
		// make sure the frame is still valid or we could crash on fullscreen mode switches
		if((cmd != GFXCMD_INIT) && (cmd != GFXCMD_DEINIT))
		{
			if((f != null) ? (!f.isDisplayable() || !f.isValid() || !f.isShowing()) : true) {
//				System.out.println("GFXCMD while frame not displayable");
				// spin until the frame is valid and displayable, if we don't we'll lose parts of the UI or crash
				while((f != null) ? (!f.isDisplayable() || !f.isValid() || !f.isShowing()) : true) {
					try {
						Thread.sleep(10);
					} catch(InterruptedException ex) {}
				}
			}
		}
		if (c != null)
		{
			switch(cmd)
			{
				case GFXCMD_INIT:
				case GFXCMD_DEINIT:
				case GFXCMD_STARTFRAME:
				case GFXCMD_FLIPBUFFER:
					c.setCursor(null);
					break;
				case GFXCMD_DRAWRECT:
				case GFXCMD_FILLRECT:
				case GFXCMD_CLEARRECT:
				case GFXCMD_DRAWOVAL:
				case GFXCMD_FILLOVAL:
				case GFXCMD_DRAWROUNDRECT:
				case GFXCMD_FILLROUNDRECT:
				case GFXCMD_DRAWTEXT:
				case GFXCMD_DRAWTEXTURED:
				case GFXCMD_DRAWLINE:
				case GFXCMD_LOADIMAGE:
				case GFXCMD_LOADIMAGETARGETED:
				case GFXCMD_UNLOADIMAGE:
				case GFXCMD_LOADFONT:
				case GFXCMD_UNLOADFONT:
				case GFXCMD_SETTARGETSURFACE:
				case GFXCMD_CREATESURFACE:
					break;
				case GFXCMD_PREPIMAGE:
				case GFXCMD_LOADIMAGELINE:
				case GFXCMD_LOADIMAGECOMPRESSED:
				case GFXCMD_XFMIMAGE:
				case GFXCMD_LOADCACHEDIMAGE:
				case GFXCMD_PREPIMAGETARGETED:
					if (!cursorHidden)
						c.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
					break;
			}
		}
		switch(cmd)
		{
			case GFXCMD_INIT:
				hasret[0] = 1;
//				System.out.println("INIT");
				// start up native renderer
				init0();
				int windowTitleStyle = 0;
				try
				{
					windowTitleStyle = Integer.parseInt(MiniClient.myProperties.getProperty("window_title_style", "0"));
				}
				catch (NumberFormatException e){}
				if (!"true".equals(MiniClient.myProperties.getProperty("enable_custom_title_bar", MiniClient.MAC_OS_X ? "false" : "true")))
					windowTitleStyle = 10; // platform default
				f = new MiniClientWindow(myConn.getWindowTitle(), windowTitleStyle);
				java.awt.LayoutManager layer = new java.awt.LayoutManager()
					{
						public void addLayoutComponent(String name, java.awt.Component comp)
						{}
						public java.awt.Dimension minimumLayoutSize(java.awt.Container parent)
						{
							return preferredLayoutSize(parent);
						}
						public java.awt.Dimension preferredLayoutSize(java.awt.Container parent)
						{
							return parent.getPreferredSize();
						}
						public void removeLayoutComponent(java.awt.Component comp)
						{}
						public void layoutContainer(java.awt.Container parent)
						{
							c.setBounds(parent.getInsets().left, parent.getInsets().top, parent.getWidth() - parent.getInsets().left - parent.getInsets().right,
								parent.getHeight() - parent.getInsets().top - parent.getInsets().bottom);
//System.out.println("LAYOUT frame bounds=" + f.getBounds() + " videoBounds=" + videoBounds + " parentBounds=" + parent.getBounds());
						}
					};
				f.getContentPane().setLayout(layer);
				try
				{
					bgImage = java.awt.Toolkit.getDefaultToolkit().createImage(getClass().getClassLoader().getResource("images/Background.jpg"));
					ensureImageIsLoaded(bgImage);
					logoImage = java.awt.Toolkit.getDefaultToolkit().createImage(getClass().getClassLoader().getResource("images/SageLogo256.png"));
					ensureImageIsLoaded(logoImage);
				}
				catch (Exception e)
				{
					System.out.println("ERROR:" + e);
					e.printStackTrace();
				}
				f.setFocusTraversalKeysEnabled(false);
				/*
					if not connecting to localhost:
						- draw background to bounds (scaled)
						- draw logo to {{2% from left, 15% from top}{20% view width, 7% view height}}, no clipping, alpha = 0.85, adjust size to keep aspect ratio
						- load Arial 32 bold
						- draw the following text, double spaced using Arial 32 bold, white with black shadow (offset by (+2,+2))
							"SageTV Placeshifter is connecting to"
							"the server: "+myConn.getServerName()
							"Please Wait..."
						text is centered in the view on the middle line, use font metrics to determine proper location
						 g.setFont(pleaseWaitFont);
						 g.setColor(java.awt.Color.black);
						 y += 2;
						 g.drawString(str1, 2 + (getWidth()/2) - (fm.stringWidth(str1)/2), y + fm.getAscent());
						 y += fm.getHeight();
						 g.drawString(str2, 2 + (getWidth()/2) - (fm.stringWidth(str2)/2), y + fm.getAscent());
						 y += 2*fm.getHeight();
						 g.drawString(str3, 2 + (getWidth()/2) - (fm.stringWidth(str3)/2), y + fm.getAscent());
						 g.setColor(java.awt.Color.white);
						 y = (getHeight() / 2) - fh/2;
						 g.drawString(str1, (getWidth()/2) - (fm.stringWidth(str1)/2), y + fm.getAscent());
						 y += fm.getHeight();
						 g.drawString(str2, (getWidth()/2) - (fm.stringWidth(str2)/2), y + fm.getAscent());
						 y += 2*fm.getHeight();
						 g.drawString(str3, (getWidth()/2) - (fm.stringWidth(str3)/2), y + fm.getAscent());
				 */
				java.awt.Dimension panelSize = f.getContentPane().getSize();
				c = new QuartzRendererView();
				c.setSize(panelSize);
				c.setFocusTraversalKeysEnabled(false);
				f.getContentPane().add(c);
				try
				{
					java.awt.Image frameIcon = java.awt.Toolkit.getDefaultToolkit().createImage(getClass().getClassLoader().getResource("images/tvicon.gif"));
					ensureImageIsLoaded(frameIcon);
					f.setIconImage(frameIcon);
				}
				catch (Exception e)
				{
					System.out.println("ERROR:" + e);
					e.printStackTrace();
				}
				f.addWindowListener(new java.awt.event.WindowAdapter()
				{
					public void windowClosing(java.awt.event.WindowEvent evt)
					{
						if (!f.isFullScreen() || System.getProperty("os.name").toLowerCase().indexOf("windows") != -1)
						{
							MiniClient.myProperties.setProperty("main_window_width", Integer.toString(f.getWidth()));
							MiniClient.myProperties.setProperty("main_window_height", Integer.toString(f.getHeight()));
							MiniClient.myProperties.setProperty("main_window_x", Integer.toString(f.getX()));
							MiniClient.myProperties.setProperty("main_window_y", Integer.toString(f.getY()));
						}
						myConn.close();
/*						try
						{
							if (myConn.getMediaCmd().getPlaya() != null)
							{
								myConn.getMediaCmd().getPlaya().stop();
								myConn.getMediaCmd().getPlaya().free();
							}
						}catch (Exception e){}
						System.exit(0);*/
						close();
//						f.dispose();
					}
				});
				c.addComponentListener(new java.awt.event.ComponentAdapter()
				{
					public void componentResized(java.awt.event.ComponentEvent evt)
					{
						myConn.postResizeEvent(new java.awt.Dimension(c.getWidth(), c.getHeight()));
					}
				});
				f.addKeyListener(this);
				c.addKeyListener(this);
				//f.addMouseListener(this);
				f.addMouseWheelListener(this);
				c.addMouseListener(this);
				if (ENABLE_MOUSE_MOTION_EVENTS)
				{
					//f.addMouseMotionListener(this);
					c.addMouseMotionListener(this);
				}
				int frameX = 100;
				int frameY = 100;
				int frameW = 720;
				int frameH = 480;
				try
				{
					frameW = Integer.parseInt(MiniClient.myProperties.getProperty("main_window_width", "720"));
					frameH = Integer.parseInt(MiniClient.myProperties.getProperty("main_window_height", "480"));
					frameX = Integer.parseInt(MiniClient.myProperties.getProperty("main_window_x", "100"));
					frameY = Integer.parseInt(MiniClient.myProperties.getProperty("main_window_y", "100"));
				}
				catch (NumberFormatException e){}
				java.awt.Point newPos = new java.awt.Point(frameX, frameY);
				boolean foundScreen = sage.UIUtils.isPointOnAScreen(newPos);
				if (!foundScreen)
				{
					newPos.x = 150;
					newPos.y = 150;
				}
				f.setVisible(true);
				f.setSize(1,1);
				f.setSize(Math.max(frameW, 320), Math.max(frameH, 240));
				f.setLocation(newPos);
				if (MiniClient.fsStartup)
					f.setFullScreen(true);
				MiniClient.hideSplash();
//				f.setVisible(true);
				return 1;
			case GFXCMD_DEINIT:
//				System.out.println("DEINIT");
				close();
				break;
			case GFXCMD_DRAWRECT:
				if(len==36)
				{
					float x, y, width, height;
					int thickness, argbTL, argbTR, argbBR, argbBL;
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					width=(float)readInt(8, cmddata);
					height=(float)readInt(12, cmddata);
					thickness=readInt(16, cmddata);
					argbTL=readInt(20, cmddata);
					argbTR=readInt(24, cmddata);
					argbBR=readInt(28, cmddata);
					argbBL=readInt(32, cmddata);
//					System.out.println("DRAWRECT: dest=("+x+","+y+" "+width+"x"+height+") thickness="+thickness+" argbTL="+Integer.toHexString(argbTL)+" argbTR="+Integer.toHexString(argbTR)+" argbBL="+Integer.toHexString(argbBL)+" argbBR="+Integer.toHexString(argbBR));
					// FIXME: no gradients on framed rects yet...
					drawRect0(new java.awt.geom.Rectangle2D.Float(x, y, width, height), null,
							  0,
							  new java.awt.Color(argbTL, true), thickness,
							  null, 0.0f, 0.0f,
							  null, 0.0f, 0.0f,
							  1.0f);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_DRAWRECT : " + len);
				}
				break;
			case GFXCMD_FILLRECT:
				// x, y, width, height, argbTL, argbTR, argbBR, argbBL
				if(len==32)
				{
					float x, y, width, height;
					int argbTL, argbTR, argbBR, argbBL;
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					width=(float)readInt(8, cmddata);
					height=(float)readInt(12, cmddata);
					argbTL=readInt(16, cmddata);
					argbTR=readInt(20, cmddata);
					argbBR=readInt(24, cmddata);
					argbBL=readInt(28, cmddata);
//					System.out.println("FILLRECT: dest=("+x+","+y+" "+width+"x"+height+") argbTL="+Integer.toHexString(argbTL)+" argbTR="+Integer.toHexString(argbTR)+" argbBL="+Integer.toHexString(argbBL)+" argbBR="+Integer.toHexString(argbBR));
					java.awt.GradientPaint gp = getGradient(x, y, width, height, argbTL, argbTR, argbBL, argbBR);
					java.awt.geom.Rectangle2D.Float bounds = new java.awt.geom.Rectangle2D.Float(x, y, width, height);
					if(gp != null) {
						drawRect0(bounds, null,
								  0,
								  null, 0,
								  gp.getColor1(), (float)gp.getPoint1().getX(), (float)gp.getPoint1().getY(),
								  gp.getColor2(), (float)gp.getPoint2().getX(), (float)gp.getPoint2().getY(),
								  //(float)((argbTL>>24)&0xff)/255.0f);
								  1.0f); // alpha already supplied
					} else {
						drawRect0(bounds, null,
								  0,
								  null, 0,
								  new java.awt.Color(argbTL, true), 0.0f, 0.0f,
								  null, 0.0f, 0.0f,
								  1.0f);
					}
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_FILLRECT : " + len);
				}
				break;
			case GFXCMD_CLEARRECT:
				// x, y, width, height, argbTL, argbTR, argbBR, argbBL
				if(len==32)
				{
					int x, y, width, height,
						argbTL, argbTR, argbBR, argbBL;
					x=readInt(0, cmddata);
					y=readInt(4, cmddata);
					width=readInt(8, cmddata);
					height=readInt(12, cmddata);
					argbTL=readInt(16, cmddata);
					argbTR=readInt(20, cmddata);
					argbBR=readInt(24, cmddata);
					argbBL=readInt(28, cmddata);
//					System.out.println("CLEARRECT: dest=("+x+","+y+" "+width+"x"+height+") argbTL="+Integer.toHexString(argbTL)+" argbTR="+Integer.toHexString(argbTR)+" argbBL="+Integer.toHexString(argbBL)+" argbBR="+Integer.toHexString(argbBR));
					java.awt.geom.Rectangle2D.Float destRect = new java.awt.geom.Rectangle2D.Float(x, y, width, height);
					clearRect0(destRect);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_CLEARRECT : " + len);
				}
				break;
			case GFXCMD_DRAWOVAL:
				// x, y, width, height, thickness, argbTL, argbTR, argbBR, argbBL,
				// clipX, clipY, clipW, clipH
				if(len==52)
				{
					float x, y, width, height, clipX, clipY, clipW, clipH;
					int thickness, argbTL, argbTR, argbBR, argbBL;
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					width=(float)readInt(8, cmddata);
					height=(float)readInt(12, cmddata);
					thickness=readInt(16, cmddata);
					argbTL=readInt(20, cmddata);
					argbTR=readInt(24, cmddata);
					argbBR=readInt(28, cmddata);
					argbBL=readInt(32, cmddata);
					clipX=(float)readInt(36, cmddata);
					clipY=(float)readInt(40, cmddata);
					clipW=(float)readInt(44, cmddata);
					clipH=(float)readInt(48, cmddata);
//					System.out.println("DRAWOVAL: dest=("+x+","+y+" "+width+"x"+height+") clip=("+clipX+","+clipY+" "+clipW+"x"+clipH+") thickness="+thickness+" argbTL="+Integer.toHexString(argbTL)+" argbTR="+Integer.toHexString(argbTR)+" argbBL="+Integer.toHexString(argbBL)+" argbBR="+Integer.toHexString(argbBR));
					// FIXME: no gradient for framed ovals
					java.awt.geom.Rectangle2D.Float bounds = new java.awt.geom.Rectangle2D.Float(x, y, width, height);
					java.awt.geom.Rectangle2D.Float clipRect = new java.awt.geom.Rectangle2D.Float(clipX, clipY, clipW, clipH);
					drawOval0(bounds, clipRect,
							  new java.awt.Color(argbTL, true), thickness,
							  null, 0.0f, 0.0f,
							  null, 0.0f, 0.0f,
							  1.0f);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_DRAWOVAL : " + len);
				}
				break;
			case GFXCMD_FILLOVAL:
				// x, y, width, height, argbTL, argbTR, argbBR, argbBL,
				// clipX, clipY, clipW, clipH
				if(len==48)
				{
					float x, y, width, height,
						clipX, clipY, clipW, clipH;
					int argbTL, argbTR, argbBR, argbBL;
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					width=(float)readInt(8, cmddata);
					height=(float)readInt(12, cmddata);
					argbTL=readInt(16, cmddata);
					argbTR=readInt(20, cmddata);
					argbBR=readInt(24, cmddata);
					argbBL=readInt(28, cmddata);
					clipX=(float)readInt(32, cmddata);
					clipY=(float)readInt(36, cmddata);
					clipW=(float)readInt(40, cmddata);
					clipH=(float)readInt(44, cmddata);
//					System.out.println("FILLOVAL: dest=("+x+","+y+" "+width+"x"+height+") clip=("+clipX+","+clipY+" "+clipW+"x"+clipH+") argbTL="+Integer.toHexString(argbTL)+" argbTR="+Integer.toHexString(argbTR)+" argbBL="+Integer.toHexString(argbBL)+" argbBR="+Integer.toHexString(argbBR));
					java.awt.GradientPaint gp = getGradient(x, y, width, height, argbTL, argbTR, argbBL, argbBR);
					java.awt.geom.Rectangle2D.Float bounds = new java.awt.geom.Rectangle2D.Float(x, y, width, height);
					java.awt.geom.Rectangle2D.Float clipRect = new java.awt.geom.Rectangle2D.Float(clipX, clipY, clipW, clipH);
					if(gp != null) {
						drawOval0(bounds, clipRect,
								  null, 0,
								  gp.getColor1(), (float)gp.getPoint1().getX(), (float)gp.getPoint1().getY(),
								  gp.getColor2(), (float)gp.getPoint2().getX(), (float)gp.getPoint2().getY(),
								  1.0f);
					} else {
						drawOval0(bounds, clipRect,
								  null, 0,
								  new java.awt.Color(argbTL, true), 0.0f, 0.0f,
								  null, 0.0f, 0.0f,
								  1.0f);
					}
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_FILLOVAL : " + len);
				}
				break;
			case GFXCMD_DRAWROUNDRECT:
				// x, y, width, height, thickness, arcRadius, argbTL, argbTR, argbBR, argbBL,
				// clipX, clipY, clipW, clipH
				if(len==56)
				{
					float x, y, width, height,
						clipX, clipY, clipW, clipH;
					int thickness, arcRadius,
						argbTL, argbTR, argbBR, argbBL;
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					width=(float)readInt(8, cmddata);
					height=(float)readInt(12, cmddata);
					thickness=readInt(16, cmddata);
					arcRadius=readInt(20, cmddata);
					argbTL=readInt(24, cmddata);
					argbTR=readInt(28, cmddata);
					argbBR=readInt(32, cmddata);
					argbBL=readInt(36, cmddata);
					clipX=(float)readInt(40, cmddata);
					clipY=(float)readInt(44, cmddata);
					clipW=(float)readInt(48, cmddata);
					clipH=(float)readInt(52, cmddata);
//					System.out.println("DRAWROUNDRECT: dest=("+x+","+y+" "+width+"x"+height+") clip=("+clipX+","+clipY+" "+clipW+"x"+clipH+") thickness="+thickness+" arcRadius="+arcRadius+" argbTL="+Integer.toHexString(argbTL)+" argbTR="+Integer.toHexString(argbTR)+" argbBL="+Integer.toHexString(argbBL)+" argbBR="+Integer.toHexString(argbBR));
					// FIXME: no gradients on stroked shapes
					java.awt.geom.Rectangle2D.Float bounds = new java.awt.geom.Rectangle2D.Float(x, y, width, height);
					java.awt.geom.Rectangle2D.Float clipRect = new java.awt.geom.Rectangle2D.Float(clipX, clipY, clipW, clipH);
					drawRect0(bounds, clipRect,
							  arcRadius,
							  new java.awt.Color(argbTL, true), thickness,
							  null, 0.0f, 0.0f,
							  null, 0.0f, 0.0f,
							  1.0f);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_DRAWROUNDRECT : " + len);
				}
				break;
			case GFXCMD_FILLROUNDRECT:
				// x, y, width, height, arcRadius, argbTL, argbTR, argbBR, argbBL,
				// clipX, clipY, clipW, clipH
				if(len==52)
				{
					float x, y, width, height,
						clipX, clipY, clipW, clipH;
					int arcRadius, argbTL, argbTR, argbBR, argbBL;
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					width=(float)readInt(8, cmddata);
					height=(float)readInt(12, cmddata);
					arcRadius=readInt(16, cmddata);
					argbTL=readInt(20, cmddata);
					argbTR=readInt(24, cmddata);
					argbBR=readInt(28, cmddata);
					argbBL=readInt(32, cmddata);
					clipX=(float)readInt(36, cmddata);
					clipY=(float)readInt(40, cmddata);
					clipW=(float)readInt(44, cmddata);
					clipH=(float)readInt(48, cmddata);
//					System.out.println("FILLROUNDRECT: dest=("+x+","+y+" "+width+"x"+height+") clip=("+clipX+","+clipY+" "+clipW+"x"+clipH+") arcRadius="+arcRadius+" argbTL="+Integer.toHexString(argbTL)+" argbTR="+Integer.toHexString(argbTR)+" argbBL="+Integer.toHexString(argbBL)+" argbBR="+Integer.toHexString(argbBR));
					java.awt.GradientPaint gp = getGradient(x, y, width, height, argbTL, argbTR, argbBL, argbBR);
					java.awt.geom.Rectangle2D.Float bounds = new java.awt.geom.Rectangle2D.Float(x, y, width, height);
					java.awt.geom.Rectangle2D.Float clipRect = new java.awt.geom.Rectangle2D.Float(clipX, clipY, clipW, clipH);
					if(gp != null) {
						drawRect0(bounds, clipRect,
								  arcRadius,
								  null, 0,
								  gp.getColor1(), (float)gp.getPoint1().getX(), (float)gp.getPoint1().getY(),
								  gp.getColor2(), (float)gp.getPoint2().getX(), (float)gp.getPoint2().getY(),
								  //(float)((argbTL>>24)&0xff)/255.0f);
								  1.0f);
					} else {
						drawRect0(bounds, clipRect,
								  arcRadius,
								  null, 0,
								  new java.awt.Color(argbTL, true), 0.0f, 0.0f,
								  null, 0.0f, 0.0f,
								  1.0f);
					}
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_FILLROUNDRECT : " + len);
				}
				break;
			case GFXCMD_DRAWTEXT:
				// x, y, len, text, handle, argb, clipX, clipY, clipW, clipH
				if(len>=36 && len>=(36+readInt(8, cmddata)*2))
				{
					float x, y, clipX, clipY, clipW, clipH;
					int textlen, fontHandle, argb;
					StringBuffer text = new StringBuffer();
					int i;
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					textlen=readInt(8, cmddata);
					for(i=0;i<textlen;i++)
					{
						text.append((char)readShort(12+i*2, cmddata));
					}
					fontHandle=readInt(textlen*2+12, cmddata);
					argb=readInt(textlen*2+16, cmddata);
					clipX=(float)readInt(textlen*2+20, cmddata);
					clipY=(float)readInt(textlen*2+24, cmddata);
					clipW=(float)readInt(textlen*2+28, cmddata);
					clipH=(float)readInt(textlen*2+32, cmddata);
					// TODO: check if this is needed
//					if (System.getProperty("java.version").startsWith("1.4"))
//						clipW = clipW * 5 / 4;
//					System.out.println("DRAWTEXT: dest=("+x+","+y+") clip=("+clipX+","+clipY+" "+clipW+"x"+clipH+") fontHandle="+fontHandle+" argb="+Integer.toHexString(argb)+" text="+text.toString());
					McFont fontPtr = (McFont)fontMap.get(new Integer(fontHandle));
					if(fontPtr != null) {
						// use AWT string bounds or we'll clip on occasion
						String theString = text.toString();
//						java.awt.Dimension textSize = fontPtr.getStringSize(theString);
						float[] positions = fontPtr.getGlyphPositions(theString);
//						System.out.println("drawText: \""+theString+"\"  loc=("+x+","+y+") num positions="+positions.length);
						drawTextWithPositions0(theString, fontPtr.nativeFont,
							x, y, positions, new java.awt.geom.Rectangle2D.Float(clipX,clipY,clipW,clipH),
							new java.awt.Color(argb, true));
					}
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_DRAWTEXT : " + len);
				}
				break;
			case GFXCMD_DRAWTEXTURED:
				// x, y, width, height, handle, srcx, srcy, srcwidth, srcheight, blend
				if(len==40)
				{
					float x, y, width, height,
						srcx, srcy, srcwidth, srcheight;
					int handle, blend; // blend is a color, use alpha component for blending
					x=(float)readInt(0, cmddata);
					y=(float)readInt(4, cmddata);
					width=(float)readInt(8, cmddata);
					height=(float)readInt(12, cmddata);
					handle=readInt(16, cmddata);			// either an image handle or layer handle (if not in imageMap)
					srcx=(float)readInt(20, cmddata);
					srcy=(float)readInt(24, cmddata);
					srcwidth=(float)readInt(28, cmddata);
					srcheight=(float)readInt(32, cmddata);
					blend=readInt(36, cmddata);
					/*
						if height < 0
							disable blending
						if width < 0 (font mode, composite with background and blend with given color)
							blend with full RGBA color
						else
							blend with alpha only
					 */
//					System.out.println("DRAWTEXTURED: handle="+handle+" dest=("+x+","+y+" "+width+"x"+height+") src=("+srcx+","+srcy+" "+srcwidth+"x"+srcheight+") blend="+Integer.toHexString(blend));
					boolean doBlend = true;
					if(height < 0) {
						doBlend = false;
						height *= -1;
					}
					if(width < 0) {
						width *= -1;
					} else {
						if(doBlend)
							blend |= 0x00ffffff; // only use alpha
					}
					Long imagePtr = (Long)imageMap.get(new Integer(handle));
					java.awt.geom.Rectangle2D.Float destRect = new java.awt.geom.Rectangle2D.Float(x,y,width,height);
					java.awt.geom.Rectangle2D.Float srcRect = new java.awt.geom.Rectangle2D.Float(srcx,srcy,srcwidth,srcheight);
					if(imagePtr != null) {
						myConn.registerImageAccess(handle);
//						System.out.println("              (drawing image) imagePtr="+imagePtr);
						drawImage1(imagePtr.longValue(),
								   destRect, srcRect,
								   (doBlend) ? new java.awt.Color(blend, true) : null);
					} else {
						imagePtr = (Long)layerMap.get(new Integer(handle));
						if(imagePtr != null) {
							myConn.registerImageAccess(handle);
//							System.out.println("              (compositing surface) layerPtr="+Long.toHexString(imagePtr.longValue())+" currentLayer="+currentLayer);
							float alpha = (doBlend ? (float)(((blend >> 24)&0xff))/255.0f : 1.0f);
							composite0(imagePtr.longValue(), currentLayer, srcRect, destRect, alpha, doBlend);
						}
						else
						{
							System.out.println("ERROR invalid handle passed for texture rendering of: " + handle);
							abortRenderCycle = true;
						}
					}
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_DRAWTEXTURED : " + len);
				}
				break;
			case GFXCMD_DRAWLINE:
				// x1, y1, x2, y2, argb1, argb2
				if(len==24)
				{
					float x1, y1, x2, y2;
					int argb1, argb2;
					x1=readInt(0, cmddata);
					y1=readInt(4, cmddata);
					x2=readInt(8, cmddata);
					y2=readInt(12, cmddata);
					argb1=readInt(16, cmddata);
					argb2=readInt(20, cmddata);
//					System.out.println("DRAWLINE: start=("+x1+","+y1+") end=("+x2+","+y2+") argb1="+Integer.toHexString(argb1)+" argb2="+Integer.toHexString(argb2));
					drawLine0(x1, y1, x2, y2, 1, new java.awt.Color(argb1, true));
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_DRAWLINE : " + len);
				}
				break;
			case GFXCMD_LOADIMAGE:
				// width, height
				if(len>=8)
				{
					int width, height;
					int imghandle = 0;
					width=readInt(0, cmddata);
					height=readInt(4, cmddata);
//					System.out.println("LOADIMAGE: size=("+width+"x"+height+")");
					if (width * height * 4 + imageCacheSize > imageCacheLimit)
					{
						imghandle = 0;
					}
					else
					{
						// creating a new image from bitmap data being sent over myConn, create a new empty image
						long imagePtr = createNewImage0(width, height);
						imghandle = handleCount++;
//						System.out.println("           imghandle="+imghandle+" imagePtr="+imagePtr);
						imageMap.put(new Integer(imghandle), new Long(imagePtr));	// actual value is filled in later when it's prepared
						imageCacheSize += width * height * 4;
					}
					hasret[0]=1;
					return imghandle;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_LOADIMAGE : " + len);
				}
				break;
			case GFXCMD_LOADIMAGETARGETED:
				// handle, width, height // Not used unless we do uncompressed images
				if(len>=12)
				{
					int width, height;
					int imghandle = readInt(0, cmddata);
					width=readInt(4, cmddata);
					height=readInt(8, cmddata);
					while (width * height * 4 + imageCacheSize > imageCacheLimit)
					{
						// Keep freeing the oldest image until we have enough memory to do this
						int oldestImage = myConn.getOldestImage();
						if (oldestImage != 0)
						{
System.out.println("Freeing image to make room in cache");
							unloadImage(oldestImage);
							myConn.postImageUnload(oldestImage);
						}
						else
						{
							System.out.println("ERROR cannot free enough from the cache to support loading a new image!!!");
							break;
						}
					}
					long imagePtr = createNewImage0(width, height);
//						System.out.println("           imghandle="+imghandle+" imagePtr="+imagePtr);
					imageMap.put(new Integer(imghandle), new Long(imagePtr));	// actual value is filled in later when it's prepared
					imageCacheSize += width * height * 4;
					myConn.registerImageAccess(imghandle);
					hasret[0]=0;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_LOADIMAGETARGETED : " + len);
				}
				break;
			case GFXCMD_CREATESURFACE:
				// width, height
				if(len>=8)
				{
					int width, height;
					int handle = handleCount++;;
					width=readInt(0, cmddata);
					height=readInt(4, cmddata);
					// width/height is managed here
					long layerPtr = createLayer0(c.getSize());
					layerMap.put(new Integer(handle), new Long(layerPtr));
//					System.out.println("CREATESURFACE: ("+width+","+height+") handle="+handle+" layerPtr="+layerPtr);
					hasret[0]=1;
					return handle;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_CREATESURFACE : " + len);
				}
				break;
			case GFXCMD_PREPIMAGE:
				// width, height
				if(len>=8)
				{
					int width, height;
					//int imghandle = handleCount++;;
					width=readInt(0, cmddata);
					height=readInt(4, cmddata);
					int imghandle = 1;
//					System.out.println("PREPIMAGE: size=("+width+"x"+height+")");
					if (width * height * 4 + imageCacheSize > imageCacheLimit)
						imghandle = 0;
					else if (len >= 12)
					{
						// We've got enough room for it and there's a cache ID, check if we've got it cached locally
						int strlen = readInt(8, cmddata);
						if (strlen > 1)
						{
							String rezName = new String(cmddata, 16, strlen - 1);
//							System.out.println("           rezName="+rezName);
							lastImageResourceID = rezName;
							// We use this hashcode to match it up on the loadCompressedImage call so we know we're caching the right thing
							lastImageResourceIDHandle = imghandle = Math.abs(lastImageResourceID.hashCode());
							java.io.File cachedFile = myConn.getCachedImageFile(rezName);
							if (cachedFile != null)
							{
								// We've got it locally in our cache! Read it from there.
								long imagePtr = createImageFromPath0(cachedFile.getAbsolutePath());
								if(imagePtr != 0)
								{
									java.awt.Dimension imgSize = getImageDimensions0(imagePtr);
									if(imgSize != null)
									{
										if(imgSize.getWidth() == width && imgSize.getHeight() == height)
										{
											// valid image in cache, use it
											imghandle = handleCount++;
//											System.out.println("           loaded from cache, imagePtr="+imagePtr+" handle="+imghandle);
											imageMap.put(new Integer(imghandle), new Long(imagePtr));
											imageCacheSize += getImageSize0(imagePtr);
											hasret[0] = 1;
											return -1 * imghandle;
										}
										else
											freeNativeImage0(imagePtr);
									}
									else
										freeNativeImage0(imagePtr);
								}
							}
						}
					}
					//imghandle=STBGFX.GFX_loadImage(width, height);
					hasret[0]=1;
					return imghandle;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_PREPIMAGE : " + len);
				}
				break;
			case GFXCMD_PREPIMAGETARGETED:
				// handle, width, height, [rezID]
				if(len>=12)
				{
					int imghandle, width, height;
					imghandle = readInt(0, cmddata);
					width=readInt(4, cmddata);
					height=readInt(8, cmddata);
					int strlen = readInt(12, cmddata);
					while (width * height * 4 + imageCacheSize > imageCacheLimit)
					{
						// Keep freeing the oldest image until we have enough memory to do this
						int oldestImage = myConn.getOldestImage();
						if (oldestImage != 0)
						{
System.out.println("Freeing image to make room in cache");
							unloadImage(oldestImage);
							myConn.postImageUnload(oldestImage);
						}
						else
						{
							System.out.println("ERROR cannot free enough from the cache to support loading a new image!!!");
							break;
						}
					}
					if (len >= 16)
					{
						// We will not have this cached locally...but setup our vars to track it
						String rezName = new String(cmddata, 20, strlen - 1);
						lastImageResourceID = rezName;
						lastImageResourceIDHandle = imghandle;
System.out.println("Prepped targeted image with handle " + imghandle + " resource=" + rezName);
					}
					myConn.registerImageAccess(imghandle);
					hasret[0]=0;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_PREPIMAGE : " + len);
				}
				break;
			case GFXCMD_LOADCACHEDIMAGE:
				// width, height
				if(len>=18)
				{
					int width, height, imghandle;
					imghandle = readInt(0, cmddata);
					width = readInt(4, cmddata);
					height = readInt(8, cmddata);
					int strlen = readInt(12, cmddata);
					String rezName = new String(cmddata, 20, strlen - 1);
System.out.println("imghandle=" + imghandle + " width=" + width + " height=" + height + " strlen=" + strlen + " rezName=" + rezName);
					while (width * height * 4 + imageCacheSize > imageCacheLimit)
					{
						// Keep freeing the oldest image until we have enough memory to do this
						int oldestImage = myConn.getOldestImage();
						if (oldestImage != 0)
						{
System.out.println("Freeing image to make room in cache");
							unloadImage(oldestImage);
							myConn.postImageUnload(oldestImage);
						}
						else
						{
							System.out.println("ERROR cannot free enough from the cache to support loading a new image!!!");
							break;
						}
					}
					myConn.registerImageAccess(imghandle);
					try
					{
						System.out.println("Loading resource from cache: " + rezName);
						java.io.File cachedFile = myConn.getCachedImageFile(rezName);
						if (cachedFile != null)
						{
							// We've got it locally in our cache! Read it from there.
							System.out.println("Image found in cache!");
							// We've got it locally in our cache! Read it from there.
							long imagePtr = createImageFromPath0(cachedFile.getAbsolutePath());
							if(imagePtr != 0)
							{
								java.awt.Dimension imgSize = getImageDimensions0(imagePtr);
								if(imgSize != null && imgSize.getWidth() == width && imgSize.getHeight() == height)
								{
									// valid image in cache, use it
//											System.out.println("           loaded from cache, imagePtr="+imagePtr+" handle="+imghandle);
									imageMap.put(new Integer(imghandle), new Long(imagePtr));
									imageCacheSize += getImageSize0(imagePtr);
								}
								else
								{
									if (imgSize != null)
									{
										// It doesn't match the cache
										System.out.println("CACHE ID verification failed for rezName=" + rezName + " target=" + width + "x" + height + " actual=" + imgSize.getWidth() + "x" + imgSize.getHeight());
									}
									else
										System.out.println("CACHE Load failed for rezName=" + rezName);
									cachedFile.delete();
									freeNativeImage0(imagePtr);
									// This load failed but the server thought it would succeed, so we need to inform it that the image is no longer loaded.
									myConn.postImageUnload(imghandle);
									myConn.postOfflineCacheChange(false, rezName);
								}
							}
							else
							{
								cachedFile.delete();
								// This load failed but the server thought it would succeed, so we need to inform it that the image is no longer loaded.
								myConn.postImageUnload(imghandle);
								myConn.postOfflineCacheChange(false, rezName);
							}
						}
						else
						{
							System.out.println("ERROR Image not found in cache that should be there! rezName=" + rezName);
							// This load failed but the server thought it would succeed, so we need to inform it that the image is no longer loaded.
							myConn.postImageUnload(imghandle);
							myConn.postOfflineCacheChange(false, rezName);
						}
					}
					catch (java.io.IOException e)
					{
						System.out.println("ERROR loading compressed image: " + e);
					}
					hasret[0]=0;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_PREPIMAGE : " + len);
				}
				break;
			case GFXCMD_UNLOADIMAGE:
				// handle
				if(len==4)
				{
					int handle;
					handle=readInt(0, cmddata);
					unloadImage(handle);
					myConn.clearImageAccess(handle);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_UNLOADIMAGE : " + len);
				}
				break;
			case GFXCMD_SETTARGETSURFACE:
				// handle
				if(len==4)
				{
					int handle;
					handle=readInt(0, cmddata);
					//STBGFX.GFX_unloadImage(handle);
					Long layerPtr = (Long)layerMap.get(new Integer(handle));
//					System.out.println("SETTARGETSURFACE: handle="+handle+" layerPtr="+ (layerPtr == null ? "0" : Long.toHexString(layerPtr.longValue())));
					currentLayer = (layerPtr != null) ? layerPtr.longValue() : 0;
					java.awt.Rectangle clipRect = new java.awt.Rectangle(0, 0, c.getWidth(), c.getHeight());
					setLayer0(currentLayer, c.getSize(), clipRect);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_SETTARGETSURFACE : " + len);
				}
				break;
			case GFXCMD_LOADFONT:
				// namelen, name, style, size
				if(len>=12 && len>=(12+readInt(0, cmddata)))
				{
					int namelen, style, size;
					StringBuffer name = new StringBuffer();
					int i;
					int fonthandle = handleCount++;
					namelen=readInt(0, cmddata);
					for(i=0;i<namelen-1;i++) // skip the terminating \0 character
					{
						name.append((char) cmddata[8 + i]); // an extra 4 for the header
					}
					style=readInt(namelen+4, cmddata);
					size=readInt(namelen+8, cmddata);
//					System.out.println("LOADFONT: handle="+fonthandle+" name="+name.toString()+" style="+Integer.toHexString(style)+" size="+size);
					McFont fontPtr = new McFont(name.toString(), style, size);
//					long fontPtr = loadFont0(name.toString(), style, size);
					if(fontPtr == null) {
						// FIXME: implement!
						// we don't have the font on this sytem (yet) see if it's cached and try to load it manually
//						String cacheName = name.toString() + "-" + style;
//						fontPtr = loadCachedFont0(cacheDir.getAbsolutePath(), name.toString() + "-" + myConn.getServerName(), style, size);
//						if (fontPtr == 0) {
							// Return that we don't have this font so it'll load it into our cache
							hasret[0] = 1;
							return 0;
//						}
					}
//					System.out.println("          fontPtr=" + fontPtr);
					fontMap.put(new Integer(fonthandle), fontPtr);
					hasret[0] = 1;
					return fonthandle;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_LOADFONT : " + len);
				}
				break;
			case GFXCMD_UNLOADFONT:
				// handle
				if(len==4)
				{
					int handle;
					handle=readInt(0, cmddata);
					//STBGFX.GFX_unloadFont(handle);
					McFont fontPtr = (McFont)fontMap.get(new Integer(handle));
//					System.out.println("UNLOADFONT: handle="+handle+" fontPtr="+fontPtr);
					if(fontPtr != null) fontPtr.unload();
					fontMap.remove(new Integer(handle));
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_UNLOADFONT : " + len);
				}
				break;
			case GFXCMD_LOADFONTSTREAM:
			    // namelen, name, len, data
				if (len>=8)
				{
					StringBuffer name = new StringBuffer();
					int namelen = readInt(0, cmddata);
					for(int i=0;i<namelen-1;i++) // skip the terminating \0 character
					{
						name.append((char) cmddata[8 + i]); // an extra 4 for the header
					}
					int datalen = readInt(4 + namelen, cmddata);
					if (len >= datalen + 8 + namelen)
					{
//						System.out.println("Saving font " + name.toString() + " to cache");
						myConn.saveCacheData(name.toString() + "-" + myConn.getServerName(), cmddata, 12 + namelen, datalen);
					}
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_LOADFONTSTREAM : " + len);
				}
				break;
			case GFXCMD_FLIPBUFFER:
//				System.out.println("FLIPBUFFER");
				if (abortRenderCycle)
				{
System.out.println("ERROR in painting cycle, ABORT was set...send full repaint command");
					myConn.postRepaintEvent(0, 0, c.getWidth(), c.getHeight());
				}
				else
				{
					present0(c.nativeView, new java.awt.Rectangle(0, 0, c.getWidth(), c.getHeight()));
				}
				hasret[0] = 1;
				//STBGFX.GFX_flipBuffer();
				firstFrameDone = true;
				return 0;
			case GFXCMD_STARTFRAME:
//				System.out.println("STARTFRAME");
				// prepare for a new frame to be rendered
				setTargetView0(c.nativeView);
				setLayer0(0, c.getSize(), null); // this makes sure the drawing surface gets resized properly
				abortRenderCycle = false;
				break;
			case GFXCMD_LOADIMAGELINE:
				// handle, line, len, data
				if(len>=12 && len>=(12+readInt(8, cmddata)))
				{
					int handle, line, len2;
					//unsigned char *data=&cmddata[12];
					handle=readInt(0, cmddata);
					line=readInt(4, cmddata);
					len2=readInt(8, cmddata);
					// the last number is the offset into the data array to start reading from
					//STBGFX.GFX_loadImageLine(handle, line, len, data, 12);
					//int dataPos = 12;
					Long imagePtr = (Long)imageMap.get(new Integer(handle));
//					System.out.println("LOADIMAGELINE: handle="+handle+" imagePtr="+imagePtr+" line="+line+" len2="+len2);
					if(imagePtr != null)
						loadImageLine0(imagePtr.longValue(), line, cmddata, 16/*12*/, len2);
					myConn.registerImageAccess(handle);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_LOADIMAGELINE : " + len);
				}
				break;
			case GFXCMD_LOADIMAGECOMPRESSED:
				// handle, line, len, data
				if(len>=8 && len>=(8+readInt(4, cmddata)))
				{
					int handle, len2;
					handle=readInt(0, cmddata);
					len2=readInt(4, cmddata);
					if (lastImageResourceID != null && lastImageResourceIDHandle == handle)
					{
						myConn.saveCacheData(lastImageResourceID, cmddata, 12, len2);
						myConn.postOfflineCacheChange(true, lastImageResourceID);
					}
					if (!myConn.doesUseAdvancedImageCaching())
					{
						handle = handleCount++;
						hasret[0] = 1;
					}
					else
						hasret[0] = 0;
					myConn.registerImageAccess(handle);
					long imagePtr = createImageFromBytes0(cmddata, 12, len2, null); // FIXME: grab extension if possible
//					System.out.println("LOADIMAGECOMPRESSED: handle="+handle+" imagePtr="+imagePtr+" len2="+len2);
					imageMap.put(new Integer(handle), new Long(imagePtr));
					imageCacheSize += getImageSize0(imagePtr);
					return handle;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_LOADIMAGECOMPRESSED : " + len);
				}
				break;
			case GFXCMD_XFMIMAGE:
				// srcHandle, destHandle, destWidth, destHeight, maskCornerArc
				if (len >= 20)
				{
					int srcHandle, destHandle, destWidth, destHeight, maskCornerArc;
					srcHandle = readInt(0, cmddata);
					destHandle = readInt(4, cmddata);		// seems to be unused
					destWidth = readInt(8,  cmddata);		// scaled size (ignore?)
					destHeight = readInt(12, cmddata);
					maskCornerArc = readInt(16, cmddata);
					int rvHandle = destHandle;
					if (!myConn.doesUseAdvancedImageCaching())
					{
						rvHandle = handleCount++;
						hasret[0] = 1;
					}
					else
						hasret[0] = 0;
					// we cheat and apply the transforms to a metaimage object without actually creating a new image (saves oodles of memory)
					Long srcImg = (Long)imageMap.get(new Integer(srcHandle));
//					System.out.println("XFMIMAGE: srcHandle="+srcHandle+" srcImg="+srcImg+" destHandle="+destHandle+" destWidth="+destWidth+" destHeight="+destHeight+" maskCornerArc="+maskCornerArc);
					if(srcImg != null) {
						long newImage = transformImage0(srcImg.longValue(), destWidth, destHeight, maskCornerArc);
						if(newImage != 0) {
//							System.out.println("          newImage="+newImage);
							imageMap.put(new Integer(rvHandle), new Long(newImage));
						}
					}
					return rvHandle;
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_XFMIMAGE : " + len);
				}
				break;
			case GFXCMD_SETVIDEOPROP:
				if (len >= 40)
				{
					java.awt.Rectangle srcRect = new java.awt.Rectangle(readInt(4, cmddata), readInt(8, cmddata),
						readInt(12, cmddata), readInt(16, cmddata));
					java.awt.Rectangle destRect = new java.awt.Rectangle(readInt(20, cmddata), readInt(24, cmddata),
						readInt(28, cmddata), readInt(32, cmddata));
					System.out.println("SETVIDEOPROP: srcRect="+srcRect+" dstRect="+destRect);
					setVideoBounds(srcRect, destRect);
				}
				else
				{
					System.out.println("Invalid len for GFXCMD_SETVIDEOPROP: " + len);
				}
				break;
			default:
				return -1;
		}
		return 0;
	}
myConn.registerImageAccess(handle);
long imagePtr = createImageFromBytes0(cmddata, 12, len2, null); // FIXME: grab extension if possible
// System.out.println("LOADIMAGECOMPRESSED: handle="+handle+" imagePtr="+imagePtr+" len2="+len2);
imageMap.put(new Integer(handle), new Long(imagePtr));
imageCacheSize += getImageSize0(imagePtr);
}
if (!myConn.doesUseAdvancedImageCaching())
{
handle = handleCount++;
hasret[0] = 1;
}
else
hasret[0] = 0;
myConn.registerImageAccess(handle);
long imagePtr = createImageFromBytes0(cmddata, 12, len2, null); // FIXME: grab extension if possible
// System.out.println("LOADIMAGECOMPRESSED: handle="+handle+" imagePtr="+imagePtr+" len2="+len2);
imageMap.put(new Integer(handle), new Long(imagePtr));
imageCacheSize += getImageSize0(imagePtr);
return handle;
}
else
{
System.out.println("Invalid len for GFXCMD_LOADIMAGECOMPRESSED : " + len);
}
break;
case GFXCMD_XFMIMAGE:
// handle, line, len, data
if(len>=8 && len>=(8+readInt(4, cmddata)))
{
int handle, len2;
handle=readInt(0, cmddata);
len2=readInt(4, cmddata);
if (lastImageResourceID != null && lastImageResourceIDHandle == handle)
{
myConn.saveCacheData(lastImageResourceID, cmddata, 12, len2);
myConn.postOfflineCacheChange(true, lastImageResourceID);
}
if (!myConn.doesUseAdvancedImageCaching())
{
handle = handleCount++;
hasret[0] = 1;
}
else
hasret[0] = 0;
myConn.registerImageAccess(handle);
long imagePtr = createImageFromBytes0(cmddata, 12, len2, null); // FIXME: grab extension if possible
// System.out.println("LOADIMAGECOMPRESSED: handle="+handle+" imagePtr="+imagePtr+" len2="+len2);
imageMap.put(new Integer(handle), new Long(imagePtr));
imageCacheSize += getImageSize0(imagePtr);
return handle;
}
else
{
System.out.println("Invalid len for GFXCMD_LOADIMAGECOMPRESSED : " + len);
}
break;
case GFXCMD_XFMIMAGE:
// srcHandle, destHandle, destWidth, destHeight, maskCornerArc
if (len >= 20)
{
int srcHandle, destHandle, destWidth, destHeight, maskCornerArc;
srcHandle = readInt(0, cmddata);
destHandle = readInt(4, cmddata); // seems to be unused
destWidth = readInt(8, cmddata); // scaled size (ignore?)
destHeight = readInt(12, cmddata);
maskCornerArc = readInt(16, cmddata);
int rvHandle = destHandle;