private static void PrepareStateMatrix(GpuStateStruct* GpuState)
		{
			// DRAW BEGIN COMMON
			{
				if (GpuState->VertexState.Type.Transform2D)
				//if (true)
				{
					GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity();
					GL.Ortho(0, 480, 272, 0, 0, -0xFFFF);

					GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity();
				}
				else
				{
					GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity();
					GL.MultMatrix(GpuState->VertexState.ProjectionMatrix.Values);

					GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity();
					GpuState->VertexState.ViewMatrix.SetLastColumn();
					GpuState->VertexState.WorldMatrix.SetLastColumn();
					GL.MultMatrix(GpuState->VertexState.ViewMatrix.Values);
					GL.MultMatrix(GpuState->VertexState.WorldMatrix.Values);

					if (float.IsNaN(GpuState->VertexState.WorldMatrix.Values[0]))
					{
						throw (new Exception("Invalid WorldMatrix"));
					}

					//GpuState->VertexState.ViewMatrix.Dump();
					//GpuState->VertexState.WorldMatrix.Dump();

					//Console.WriteLine("NO Transform2D");
				}
			}
		}
示例#2
0
        public override void Transfer(GpuStateStruct* GpuState)
        {
            //return;
            var TextureTransferState = GpuState->TextureTransferState;

            if (
                (TextureTransferState.DestinationAddress.Address == GpuState->DrawBufferState.Address) &&
                (TextureTransferState.DestinationLineWidth == GpuState->DrawBufferState.Width) &&
                (TextureTransferState.BytesPerPixel == GpuState->DrawBufferState.BytesPerPixel)
            )
            {
                //Console.Error.WriteLine("Writting to DrawBuffer");
                TransferToFrameBuffer(GpuState);
            }
            else
            {
                Console.Error.WriteLine("NOT Writting to DrawBuffer");
                TransferGeneric(GpuState);
                /*
                base.Transfer(GpuStateStruct);
                PrepareWrite(GpuStateStruct);
                {

                }
                PrepareRead(GpuStateStruct);
                */
            }
            Console.Error.WriteLine("GpuImpl.Transfer Not Implemented!! : {0}", GpuState->TextureTransferState.ToStringDefault());
        }
示例#3
0
        internal static void PrepareStateMatrix(GpuStateStruct* GpuState, ref Matrix4f WorldViewProjectionMatrix)
        {
            // DRAW BEGIN COMMON
            {
                if (GpuState->VertexState.Type.Transform2D)
                //if (true)
                {
                    WorldViewProjectionMatrix = Matrix4f.Ortho(0, 512, 272, 0, 0, -0xFFFF);
                    //WorldViewProjectionMatrix = Matrix4f.Ortho(0, 480, 272, 0, 0, -0xFFFF);
                }
                else
                {
                    if (float.IsNaN(GpuState->VertexState.WorldMatrix.Values[0]))
                    {
                        //Console.Error.WriteLine("Invalid WorldMatrix");
                        //Console.Error.WriteLine("Projection:");
                        //GpuState->VertexState.ProjectionMatrix.Dump();
                        //Console.Error.WriteLine("View:");
                        //GpuState->VertexState.ViewMatrix.Dump();
                        //Console.Error.WriteLine("World:");
                        //GpuState->VertexState.WorldMatrix.Dump();
                    }

                    GpuState->VertexState.ViewMatrix.SetLastColumn();
                    GpuState->VertexState.WorldMatrix.SetLastColumn();

                    WorldViewProjectionMatrix =
                        Matrix4f.Identity
                        .Multiply(GpuState->VertexState.WorldMatrix.Matrix4)
                        .Multiply(GpuState->VertexState.ViewMatrix.Matrix4)
                        .Multiply(GpuState->VertexState.ProjectionMatrix.Matrix4)
                    ;
                }
            }
        }
		private void PrepareStateDraw(GpuStateStruct* GpuState)
		{
			GL.ColorMask(true, true, true, true);

#if ENABLE_TEXTURES
			PrepareState_Texture_Common(GpuState);
#endif
			PrepareState_Blend(GpuState);

			if (GpuState->VertexState.Type.Transform2D)
			{
				PrepareState_Colors_2D(GpuState);
				GL.Disable(EnableCap.StencilTest);
				GL.Disable(EnableCap.CullFace);
				GL.DepthRange((double)0, (double)1);
				GL.Disable(EnableCap.DepthTest);
				GL.Disable(EnableCap.Lighting);
			}
			else
			{
				PrepareState_Colors_3D(GpuState);
				PrepareState_CullFace(GpuState);
				PrepareState_Lighting(GpuState);
				PrepareState_Depth(GpuState);
				PrepareState_DepthTest(GpuState);
				PrepareState_Stencil(GpuState);
			}
			GL.ShadeModel((GpuState->ShadeModel == ShadingModelEnum.Flat) ? ShadingModel.Flat : ShadingModel.Smooth);
			PrepareState_AlphaTest(GpuState);
		}
        private void PrepareStateCommon(GpuStateStruct* GpuState)
        {
            var Viewport = GpuState->Viewport;
            //ViewportStruct(
            //  Position=Vector3f(X=2048,Y=2048,Z=0.9999847),
            //  Scale=Vector3f(X=480,Y=-272,Z=-32768),
            //  RegionTopLeft=PointS(X=0,Y=0),
            //  RegionBottomRight=PointS(X=479,Y=271)
            //)
            //ViewportStruct(
            //  RegionSize=PointS(X=384,Y=240),
            //  Position=Vector3f(X=2048,Y=2048,Z=0),
            //  Scale=Vector3f(X=480,Y=-272,Z=0),
            //  RegionTopLeft=PointS(X=0,Y=0),
            //  RegionBottomRight=PointS(X=383,Y=239)
            //)
            //Console.Error.WriteLine(Viewport.ToString());

            GL.Hint(HintTarget.PolygonSmoothHint, HintMode.Fastest);
            GL.Hint(HintTarget.LineSmoothHint, HintMode.Fastest);
            GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Fastest);
            GL.Hint(HintTarget.PointSmoothHint, HintMode.Fastest);

            int ScaledWidth = (int)(((double)480 / (double)Viewport.RegionSize.X) * (double)480);
            int ScaledHeight = (int)(((double)272 / (double)Viewport.RegionSize.Y) * (double)272);

            GL.Viewport(
                (int)Viewport.RegionTopLeft.X,
                (int)Viewport.RegionTopLeft.Y,
                ScaledWidth,
                ScaledHeight
            );
        }
		private void PrepareState_Stencil(GpuStateStruct* GpuState)
		{
			if (!GlEnableDisable(GL.GL_STENCIL_TEST, GpuState->StencilState.Enabled))
			{
				return;
			}

			//Console.Error.WriteLine("aaaaaa!");

			//if (state.stencilFuncFunc == 2) { outputDepthAndStencil(); assert(0); }

#if false
											Console.Error.WriteLine(
			"{0}:{1}:{2} - {3}, {4}, {5}",
			StencilFunctionTranslate[(int)GpuState->StencilState.Function],
			GpuState->StencilState.FunctionRef,
			GpuState->StencilState.FunctionMask,
			StencilOperationTranslate[(int)GpuState->StencilState.OperationFail],
			StencilOperationTranslate[(int)GpuState->StencilState.OperationZFail],
			StencilOperationTranslate[(int)GpuState->StencilState.OperationZPass]
		);
#endif

			GL.glStencilFunc(
				StencilFunctionTranslate[(int)GpuState->StencilState.Function],
				GpuState->StencilState.FunctionRef,
				GpuState->StencilState.FunctionMask
			);

			GL.glStencilOp(
				StencilOperationTranslate[(int)GpuState->StencilState.OperationFail],
				StencilOperationTranslate[(int)GpuState->StencilState.OperationZFail],
				StencilOperationTranslate[(int)GpuState->StencilState.OperationZPass]
			);
		}
		private void TransferToFrameBuffer(GpuStateStruct* GpuState)
		{
			var TextureTransferState = GpuState->TextureTransferState;

			var GlPixelFormat = GlPixelFormatList[(int)GpuState->DrawBufferState.Format];

			GL.PixelZoom(1, -1);
			GL.WindowPos2(TextureTransferState.DestinationX, 272 - TextureTransferState.DestinationY);
			//GL.PixelZoom(1, -1);
			//GL.PixelZoom(1, 1);
			GL.PixelStore(PixelStoreParameter.UnpackAlignment, TextureTransferState.BytesPerPixel);
			GL.PixelStore(PixelStoreParameter.UnpackRowLength, TextureTransferState.SourceLineWidth);
			GL.PixelStore(PixelStoreParameter.UnpackSkipPixels, TextureTransferState.SourceX);
			GL.PixelStore(PixelStoreParameter.UnpackSkipRows, TextureTransferState.SourceY);

			{
				GL.DrawPixels(
					TextureTransferState.Width,
					TextureTransferState.Height,
					PixelFormat.Rgba,
					GlPixelFormat.OpenglPixelType,
					new IntPtr(Memory.PspAddressToPointerSafe(
						TextureTransferState.SourceAddress,
						TextureTransferState.Width * TextureTransferState.Height * 4
					))
				);
			}

			GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
			GL.PixelStore(PixelStoreParameter.UnpackRowLength, 0);
			GL.PixelStore(PixelStoreParameter.UnpackSkipPixels, 0);
			GL.PixelStore(PixelStoreParameter.UnpackSkipRows, 0);
		}
		private void PrepareStateDraw(GpuStateStruct* GpuState)
		{
			GL.glColorMask(true, true, true, true);

#if ENABLE_TEXTURES
			PrepareState_Texture_Common(GpuState);
#endif
			PrepareState_Blend(GpuState);

			if (GpuState->VertexState.Type.Transform2D)
			{
				PrepareState_Colors_2D(GpuState);
				GL.glDisable(GL.GL_STENCIL_TEST);
				GL.glDisable(GL.GL_CULL_FACE);
				GL.glDepthRangef(0, 1);
				GL.glDisable(GL.GL_DEPTH_TEST);
				//GL.glDisable(GL.GL_LIGHTNING_TEST);
			}
			else
			{
				PrepareState_Colors_3D(GpuState);
				PrepareState_CullFace(GpuState);
				PrepareState_Lighting(GpuState);
				PrepareState_Depth(GpuState);
				PrepareState_DepthTest(GpuState);
				PrepareState_Stencil(GpuState);
			}
			//GL.ShadeModel((GpuState->ShadeModel == ShadingModelEnum.Flat) ? ShadingModel.Flat : ShadingModel.Smooth);
			PrepareState_AlphaTest(GpuState);
		}
示例#9
0
        private void TransferGeneric(GpuStateStruct* GpuState)
        {
            Console.WriteLine("TransferGeneric Not Implemented");
            var TextureTransferState = GpuState->TextureTransferState;

            var SourceX = TextureTransferState.SourceX;
            var SourceY = TextureTransferState.SourceY;
            var DestinationX = TextureTransferState.DestinationX;
            var DestinationY = TextureTransferState.DestinationY;
            var BytesPerPixel = TextureTransferState.BytesPerPixel;

            var SourceTotalBytes = TextureTransferState.SourceLineWidth * TextureTransferState.Height * BytesPerPixel;
            var DestinationTotalBytes = TextureTransferState.DestinationLineWidth * TextureTransferState.Height * BytesPerPixel;

            var SourcePointer = (byte*)Memory.PspAddressToPointerSafe(TextureTransferState.SourceAddress.Address, SourceTotalBytes);
            var DestinationPointer = (byte*)Memory.PspAddressToPointerSafe(TextureTransferState.DestinationAddress.Address, DestinationTotalBytes);

            for (uint y = 0; y < TextureTransferState.Height; y++)
            {
                var RowSourceOffset = (uint)(
                    (TextureTransferState.SourceLineWidth * (y + SourceY)) + SourceX
                );
                var RowDestinationOffset = (uint)(
                    (TextureTransferState.DestinationLineWidth * (y + DestinationY)) + DestinationX
                );
                PointerUtils.Memcpy(
                    DestinationPointer + RowDestinationOffset * BytesPerPixel,
                    SourcePointer + RowSourceOffset * BytesPerPixel,
                    TextureTransferState.Width * BytesPerPixel
                );
            }

            /*
            // Generic implementation.
            with (gpu.state.textureTransfer) {
                auto srcAddressHost = cast(ubyte*)gpu.memory.getPointer(srcAddress);
                auto dstAddressHost = cast(ubyte*)gpu.memory.getPointer(dstAddress);

                if (gpu.state.drawBuffer.isAnyAddressInBuffer([srcAddress, dstAddress])) {
                    gpu.performBufferOp(BufferOperation.STORE, BufferType.COLOR);
                }

                for (int n = 0; n < height; n++) {
                    int srcOffset = ((n + srcY) * srcLineWidth + srcX) * bpp;
                    int dstOffset = ((n + dstY) * dstLineWidth + dstX) * bpp;
                    (dstAddressHost + dstOffset)[0.. width * bpp] = (srcAddressHost + srcOffset)[0.. width * bpp];
                    //writefln("%08X <- %08X :: [%d]", dstOffset, srcOffset, width * bpp);
                }
                //std.file.write("buffer", dstAddressHost[0..512 * 272 * 4]);

                if (gpu.state.drawBuffer.isAnyAddressInBuffer([dstAddress])) {
                    //gpu.impl.test();
                    //gpu.impl.test("trxkick");
                    gpu.markBufferOp(BufferOperation.LOAD, BufferType.COLOR);
                }
                //gpu.impl.test();
            }
            */
        }
示例#10
0
        private void PrepareState_Blend(GpuStateStruct* GpuState)
        {
            var BlendingState = &GpuState->BlendingState;
            if (!GlEnableDisable(EnableCap.Blend, BlendingState->Enabled))
            {
                return;
            }

            //Console.WriteLine("Blend!");

            var OpenglFunctionSource = BlendFuncSrcTranslate[(int)BlendingState->FunctionSource];
            //var OpenglFunctionDestination = BlendFuncDstTranslate[(int)BlendingState->FunctionDestination];
            var OpenglFunctionDestination = (BlendingFactorDest)BlendFuncSrcTranslate[(int)BlendingState->FunctionDestination];

            Func<ColorfStruct, int> getBlendFix = (Color) =>
            {
                if (Color.IsColorf(0, 0, 0)) return GL_ZERO;
                if (Color.IsColorf(1, 1, 1)) return GL_ONE;
                return GL_CONSTANT_COLOR;
            };

            if (BlendingState->FunctionSource == GuBlendingFactorSource.GU_FIX)
            {
                OpenglFunctionSource = (BlendingFactorSrc)getBlendFix(BlendingState->FixColorSource);
            }

            if (BlendingState->FunctionDestination == GuBlendingFactorDestination.GU_FIX)
            {
                if (((int)OpenglFunctionSource == GL_CONSTANT_COLOR) && (BlendingState->FixColorSource + BlendingState->FixColorDestination).IsColorf(1, 1, 1))
                {
                    OpenglFunctionDestination = (BlendingFactorDest)GL_ONE_MINUS_CONSTANT_COLOR;
                }
                else
                {
                    OpenglFunctionDestination = (BlendingFactorDest)getBlendFix(BlendingState->FixColorDestination);
                }
            }
            //Console.WriteLine("{0}, {1}", OpenglFunctionSource, OpenglFunctionDestination);

            var OpenglBlendEquation = BlendEquationTranslate[(int)BlendingState->Equation];

            /*
            Console.WriteLine(
                "{0} : {1} -> {2}",
                OpenglBlendEquation, OpenglFunctionSource, OpenglFunctionDestination
            );
            */

            GL.BlendEquation(OpenglBlendEquation);
            GL.BlendFunc(OpenglFunctionSource, OpenglFunctionDestination);

            GL.BlendColor(
                BlendingState->FixColorDestination.Red,
                BlendingState->FixColorDestination.Green,
                BlendingState->FixColorDestination.Blue,
                BlendingState->FixColorDestination.Alpha
            );
        }
		private void PrepareStateMatrix(GpuStateStruct* GpuState)
		{
			var VertexType = GpuState->VertexState.Type;
			var TextureState = &GpuState->TextureMappingState.TextureState;

			if (VertexType.Transform2D)
			{
				projectionMatrix.SetMatrix4(Matrix4Ortho);
				worldMatrix.SetMatrix4(Matrix4Identity);
				viewMatrix.SetMatrix4(Matrix4Identity);
				GL.glDepthRangef(0f, 1f);
			}
			else
			{
				projectionMatrix.SetMatrix4(GpuState->VertexState.ProjectionMatrix.Values);
				worldMatrix.SetMatrix4(GpuState->VertexState.WorldMatrix.Values);
				viewMatrix.SetMatrix4(GpuState->VertexState.ViewMatrix.Values);
			}

			/*
			// DRAW BEGIN COMMON
			{
				if (GpuState->VertexState.Type.Transform2D)
				//if (true)
				{
					GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity();
					GL.Ortho(0, 480, 272, 0, 0, -0xFFFF);

					GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity();
				}
				else
				{
					GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity();
					GL.MultMatrix(GpuState->VertexState.ProjectionMatrix.Values);

					GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity();
					GpuState->VertexState.ViewMatrix.SetLastColumn();
					GpuState->VertexState.WorldMatrix.SetLastColumn();
					GL.MultMatrix(GpuState->VertexState.ViewMatrix.Values);
					GL.MultMatrix(GpuState->VertexState.WorldMatrix.Values);

					if (float.IsNaN(GpuState->VertexState.WorldMatrix.Values[0]))
					{
						throw (new Exception("Invalid WorldMatrix"));
					}

					//GpuState->VertexState.ViewMatrix.Dump();
					//GpuState->VertexState.WorldMatrix.Dump();

					//Console.WriteLine("NO Transform2D");
				}
			}
			*/
		}
示例#12
0
        private void PrepareState_AlphaTest(GpuStateStruct* GpuState)
        {
            if (!GlEnableDisable(EnableCap.AlphaTest, GpuState->AlphaTestState.Enabled))
            {
                return;
            }

            GL.AlphaFunc(
                (AlphaFunction)TestTranslate[(int)GpuState->AlphaTestState.Function],
                GpuState->AlphaTestState.Value
            );
        }
		static void PrepareStateClear(GpuStateStruct* GpuState)
		{
			bool ccolorMask = false, calphaMask = false;

			//return;

			GL.glDisable(GL.GL_BLEND);
			//GL.glDisable(GLEnableCap.Lighting);
			GL.glDisable(GL.GL_TEXTURE_2D);
			//GL.glDisable(EnableCap.AlphaTest);
			GL.glDisable(GL.GL_DEPTH_TEST);
			GL.glDisable(GL.GL_STENCIL_TEST);
			//GL.glDisable(EnableCap.Fog);
			//GL.glDisable(EnableCap.ColorLogicOp);
			GL.glDisable(GL.GL_CULL_FACE);
			GL.glDepthMask(false);

			if (GpuState->ClearFlags.HasFlag(ClearBufferSet.ColorBuffer))
			{
				ccolorMask = true;
			}

			if (GlEnableDisable(GL.GL_STENCIL_TEST, GpuState->ClearFlags.HasFlag(ClearBufferSet.StencilBuffer)))
			{
				calphaMask = true;
				// Sets to 0x00 the stencil.
				// @TODO @FIXME! : Color should be extracted from the color! (as alpha component)
				GL.glStencilFunc(GL.GL_ALWAYS, 0x00, 0xFF);
				GL.glStencilOp(GL.GL_REPLACE, GL.GL_REPLACE, GL.GL_REPLACE);
				//Console.Error.WriteLine("Stencil!");
				//GL.Enable(EnableCap.DepthTest);
			}

			//int i; glGetIntegerv(GL_STENCIL_BITS, &i); writefln("GL_STENCIL_BITS: %d", i);

			if (GpuState->ClearFlags.HasFlag(ClearBufferSet.DepthBuffer))
			{
				GL.glEnable(GL.GL_DEPTH_TEST);
				GL.glDepthFunc(GL.GL_ALWAYS);
				GL.glDepthMask(true);
				GL.glDepthRangef(0f, 0f);
				//GL.DepthRange((double)-1, (double)0);

				//glDepthRange(0.0, 1.0); // Original value
			}

			GL.glColorMask(ccolorMask, ccolorMask, ccolorMask, calphaMask);

			//glClearDepth(0.0); glClear(GL_COLOR_BUFFER_BIT);

			//if (state.clearFlags & ClearBufferMask.GU_COLOR_BUFFER_BIT) glClear(GL_DEPTH_BUFFER_BIT);
			//GL.Clear(ClearBufferMask.StencilBufferBit);
		}
示例#14
0
		private void PrepareState_AlphaTest(GpuStateStruct* GpuState)
		{
			//if (!GL.EnableDisable(EnableCap.AlphaTest, GpuState->AlphaTestState.Enabled))
			//{
			//	return;
			//}
			//
			//GL.glAlphaFunc(
			//	(AlphaFunction)DepthFunctionTranslate[(int)GpuState->AlphaTestState.Function],
			//	GpuState->AlphaTestState.Value
			//);
		}
	    static void PrepareStateClear(GpuStateStruct* GpuState)
		{
			bool ccolorMask = false, calphaMask = false;

			//return;

			GL.Disable(EnableCap.Blend);
			GL.Disable(EnableCap.Lighting);
			GL.Disable(EnableCap.Texture2D);
			GL.Disable(EnableCap.AlphaTest);
			GL.Disable(EnableCap.DepthTest);
			GL.Disable(EnableCap.StencilTest);
			GL.Disable(EnableCap.Fog);
			GL.Disable(EnableCap.ColorLogicOp);
			GL.Disable(EnableCap.CullFace);
			GL.DepthMask(false);

			if (GpuState->ClearFlags.HasFlag(ClearBufferSet.ColorBuffer))
			{
				ccolorMask = true;
			}

			if (GlEnableDisable(EnableCap.StencilTest, GpuState->ClearFlags.HasFlag(ClearBufferSet.StencilBuffer)))
			{
				calphaMask = true;
				// Sets to 0x00 the stencil.
				// @TODO @FIXME! : Color should be extracted from the color! (as alpha component)
				GL.StencilFunc(StencilFunction.Always, 0x00, 0xFF);
				GL.StencilOp(StencilOp.Replace, StencilOp.Replace, StencilOp.Replace);
				//Console.Error.WriteLine("Stencil!");
				//GL.Enable(EnableCap.DepthTest);
			}

			//int i; glGetIntegerv(GL_STENCIL_BITS, &i); writefln("GL_STENCIL_BITS: %d", i);

			if (GpuState->ClearFlags.HasFlag(ClearBufferSet.DepthBuffer))
			{
				GL.Enable(EnableCap.DepthTest);
				GL.DepthFunc(DepthFunction.Always);
				GL.DepthMask(true);
				GL.DepthRange((double)0, (double)0);
				//GL.DepthRange((double)-1, (double)0);

				//glDepthRange(0.0, 1.0); // Original value
			}

			GL.ColorMask(ccolorMask, ccolorMask, ccolorMask, calphaMask);

			//glClearDepth(0.0); glClear(GL_COLOR_BUFFER_BIT);

			//if (state.clearFlags & ClearBufferMask.GU_COLOR_BUFFER_BIT) glClear(GL_DEPTH_BUFFER_BIT);
			//GL.Clear(ClearBufferMask.StencilBufferBit);
		}
示例#16
0
        public static void PrepareStateCommon(GpuStateStruct* GpuState, int ScaleViewport)
        {
            var Viewport = GpuState->Viewport;
            //ViewportStruct(
            //  Position=Vector3f(X=2048,Y=2048,Z=0.9999847),
            //  Scale=Vector3f(X=480,Y=-272,Z=-32768),
            //  RegionTopLeft=PointS(X=0,Y=0),
            //  RegionBottomRight=PointS(X=479,Y=271)
            //)
            //ViewportStruct(
            //  RegionSize=PointS(X=384,Y=240),
            //  Position=Vector3f(X=2048,Y=2048,Z=0),
            //  Scale=Vector3f(X=480,Y=-272,Z=0),
            //  RegionTopLeft=PointS(X=0,Y=0),
            //  RegionBottomRight=PointS(X=383,Y=239)
            //)
            //Console.Error.WriteLine(Viewport.ToString());

            //GL.Hint(HintTarget.PolygonSmoothHint, HintMode.Fastest);
            //GL.Hint(HintTarget.LineSmoothHint, HintMode.Fastest);
            //GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Fastest);
            //GL.Hint(HintTarget.PointSmoothHint, HintMode.Fastest);

            /*
                            int halfHeight = Math.abs(context.viewport_height);
                            int halfWidth = Math.abs(context.viewport_width);
                            int viewportX = context.viewport_cx - halfWidth - context.offset_x;
                            int viewportY = context.viewport_cy - halfHeight - context.offset_y;
                            int viewportWidth = 2 * halfWidth;
                            int viewportHeight = 2 * halfHeight;

                            // For OpenGL, translate the viewportY from the upper left corner
                            // to the lower left corner.
                            viewportY = Screen.height - viewportY - viewportHeight;

                            re.setViewport(viewportX, viewportY, viewportWidth, viewportHeight);
            */

            //int ScreenWidth = 480;
            //int ScreenHeight = 272;
            //
            //int ScaledWidth = (int)(((double)ScreenWidth / (double)Viewport.RegionSize.X) * (double)ScreenWidth);
            //int ScaledHeight = (int)(((double)ScreenHeight / (double)Viewport.RegionSize.Y) * (double)ScreenHeight);
            //
            //GL.glViewport(
            //	(int)Viewport.RegionTopLeft.X * ScaleViewport,
            //	(int)Viewport.RegionTopLeft.Y * ScaleViewport,
            //	ScaledWidth * ScaleViewport,
            //	ScaledHeight * ScaleViewport
            //);
        }
示例#17
0
		private void PrepareState_Clip(GpuStateStruct* GpuState)
		{
			if (!GL.EnableDisable(GL.GL_SCISSOR_TEST, GpuState->ClipPlaneState.Enabled))
			{
				return;
			}
			var Scissor = &GpuState->ClipPlaneState.Scissor;
			GL.glScissor(
				Scissor->Left * ScaleViewport,
				Scissor->Top * ScaleViewport,
				(Scissor->Right - Scissor->Left) * ScaleViewport,
				(Scissor->Bottom - Scissor->Top) * ScaleViewport
			);
		}
		private void PrepareState_AlphaTest(GpuStateStruct* GpuState)
		{
			/*
			if (GlEnableDisable(GL.GL_ALPHA_TEST, GpuState->AlphaTestState.Enabled))
			{
				return;
			}

			GL.AlphaFunc(
				(AlphaFunction)DepthFunctionTranslate[(int)GpuState->AlphaTestState.Function],
				GpuState->AlphaTestState.Value
			);
			*/
		}
示例#19
0
        private void PrepareState(GpuStateStruct* GpuState)
        {
            GL.ColorMask(true, true, true, true);

            PrepareState_Texture(GpuState);
            PrepareState_CullFace(GpuState);
            PrepareState_Colors(GpuState);
            PrepareState_Lighting(GpuState);
            PrepareState_Blend(GpuState);
            PrepareState_Depth(GpuState);
            PrepareState_DepthTest(GpuState);
            PrepareState_Stencil(GpuState);
            PrepareState_AlphaTest(GpuState);

            GL.ShadeModel((GpuState->ShadeModel == ShadingModelEnum.Flat) ? ShadingModel.Flat : ShadingModel.Smooth);
        }
示例#20
0
        public void StartPrimitive(GpuStateStruct* GpuState, State.GuPrimitiveType PrimitiveType, uint VertexAddress, int VertexCount, ref State.VertexTypeStruct VertexType)
        {
            this.GpuState = GpuState;
            this.VertexType = VertexType;
            var ViewMatrix = GpuState->VertexState.ViewMatrix.Matrix4;
            var WorldMatrix = GpuState->VertexState.WorldMatrix.Matrix4;
            ModelMatrix = Matrix4.Mult(ViewMatrix, WorldMatrix);

            this.CurrentPrimitiveType = PrimitiveType;
            WavefrontObjWriter.StartComment("Start: " + this.CurrentPrimitiveType + " : VertexAddress: 0x" + String.Format("{0:X}", VertexAddress) + " : " + VertexCount + " : " + this.VertexType);
            PrimitiveIndices.Clear();

            //throw new NotImplementedException();
            /*
            Console.WriteLine("ViewMatrix (DEMO):");
            Console.WriteLine("{0}", Matrix4.Translation(new Vector3(0f, 0f, -3.5f)));
            Console.WriteLine("ViewMatrix:");
            Console.WriteLine("{0}", ViewMatrix);
            */
        }
		private static void PrepareStateCommon(GpuStateStruct* GpuState)
		{
			var Viewport = GpuState->Viewport;

			//GL.Hint(HintTarget.PolygonSmoothHint, HintMode.Fastest);
			//GL.Hint(HintTarget.LineSmoothHint, HintMode.Fastest);
			//GL.Hint(HintTarget.PerspectiveCorrectionHint, HintMode.Fastest);
			//GL.Hint(HintTarget.PointSmoothHint, HintMode.Fastest);

			int ScreenWidth = 480;
			int ScreenHeight = 272;

			int ScaledWidth = (int)(((double)ScreenWidth / (double)Viewport.RegionSize.X) * (double)ScreenWidth);
			int ScaledHeight = (int)(((double)ScreenHeight / (double)Viewport.RegionSize.Y) * (double)ScreenHeight);

			GL.glViewport(
				(int)Viewport.RegionTopLeft.X,
				(int)Viewport.RegionTopLeft.Y,
				ScaledWidth,
				ScaledHeight
			);
		}
示例#22
0
        public void BindCurrentDrawBufferTexture(GpuStateStruct* GpuState)
        {
            if (CachedBindAddress != GpuState->DrawBufferState.Address)
            {
                GL.glFlush();
                GL.glFinish();

                CachedBindAddress = GpuState->DrawBufferState.Address;
                var Key = new DrawBufferKey()
                {
                    Address = GpuState->DrawBufferState.Address,
                    //Width = (int)GpuState->DrawBufferState.Width,
                    //Height = (int)272,
                };
                if (CurrentDrawBuffer != null)
                {
                    CurrentDrawBuffer.Unbind();
                }
                CurrentDrawBuffer = GetOrCreateDrawBufferTexture(Key);
                CurrentDrawBuffer.Bind();
            }
        }
		private void TransferToFrameBuffer(GpuStateStruct* GpuState)
		{
			var TextureTransferState = GpuState->TextureTransferState;

			var GlPixelFormat = GlPixelFormatList[(int)GpuState->DrawBufferState.Format];

			Console.Error.WriteLine("TransferToFrameBuffer not implemented");


			//GL.glReadPixels
			//GL.glPixelZoom(1, -1);
			//GL.glWindowPos2(TextureTransferState.DestinationX, 272 - TextureTransferState.DestinationY);
			////GL.PixelZoom(1, -1);
			////GL.PixelZoom(1, 1);
			//GL.glPixelStore(PixelStoreParameter.UnpackAlignment, TextureTransferState.BytesPerPixel);
			//GL.glPixelStore(PixelStoreParameter.UnpackRowLength, TextureTransferState.SourceLineWidth);
			//GL.glPixelStore(PixelStoreParameter.UnpackSkipPixels, TextureTransferState.SourceX);
			//GL.glPixelStore(PixelStoreParameter.UnpackSkipRows, TextureTransferState.SourceY);
			//
			//{
			//	GL.glDrawPixels(
			//		TextureTransferState.Width,
			//		TextureTransferState.Height,
			//		GL.GL_RGBA,
			//		GlPixelFormat.OpenglPixelType,
			//		new IntPtr(Memory.PspAddressToPointerSafe(
			//			TextureTransferState.SourceAddress,
			//			TextureTransferState.Width * TextureTransferState.Height * 4
			//		))
			//	);
			//}
			//
			//GL.glPixelStore(PixelStoreParameter.UnpackAlignment, 1);
			//GL.glPixelStore(PixelStoreParameter.UnpackRowLength, 0);
			//GL.glPixelStore(PixelStoreParameter.UnpackSkipPixels, 0);
			//GL.glPixelStore(PixelStoreParameter.UnpackSkipRows, 0);
		}
示例#24
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="GpuState"></param>
        private unsafe void _Prim(GpuStateStruct* GpuState, GuPrimitiveType PrimitiveType, ushort VertexCount)
        {
            //if (PrimitiveType == GuPrimitiveType.TriangleStrip) VertexCount++;

            //Console.WriteLine("Prim: {0}, {1}", PrimitiveType, VertexCount);
            this.GpuState = GpuState;

            //Console.WriteLine("--------------------------------------------------------");
            VertexType = GpuState->VertexState.Type;

            ReadVertexDelegate ReadVertex = ReadVertex_Void;
            VertexReader.SetVertexTypeStruct(
                VertexType,
                (byte*)Memory.PspAddressToPointerSafe(GpuState->GetAddressRelativeToBaseOffset(GpuState->VertexAddress), 0)
            );

            #if DEBUG_VERTEX_TYPE
            try
            {
                if (!File.Exists("VertexType_" + VertexType.Value))
                {
                    File.WriteAllBytes(
                        "VertexType_" + VertexType.Value,
                        PointerUtils.PointerToByteArray((byte*)Memory.PspAddressToPointerSafe(GpuState->VertexAddress), 16 * 1024)
                    );
                    File.WriteAllText(
                        "VertexType_" + VertexType.Value + "_str",
                        VertexCount + "," + PrimitiveType + "\n" +
                        VertexType.ToString()
                    );
                    OutputVertexInfoStream = File.OpenWrite("VertexType_" + VertexType.Value + "_list");
                }
            }
            catch
            {
            }
            #endif
            //IndexReader.SetVertexTypeStruct(VertexType, VertexCount, (byte*)Memory.PspAddressToPointerSafe(GpuState->IndexAddress));

            uint TotalVerticesWithoutMorphing = VertexCount;

            //Console.Error.WriteLine("GpuState->IndexAddress: {0:X}", GpuState->IndexAddress);

            // Invalid
            /*
            if (GpuState->IndexAddress == 0xFFFFFFFF)
            {
                //Debug.Fail("Invalid IndexAddress");
                throw (new Exception("Invalid IndexAddress == 0xFFFFFFFF"));
            }
            */

            void* IndexPointer = null;
            if (VertexType.Index != VertexTypeStruct.IndexEnum.Void)
            {
                IndexPointer = Memory.PspAddressToPointerSafe(GpuState->GetAddressRelativeToBaseOffset(GpuState->IndexAddress), 0);
            }

            //Console.Error.WriteLine(VertexType.Index);
            switch (VertexType.Index)
            {
                case VertexTypeStruct.IndexEnum.Void:
                    break;
                case VertexTypeStruct.IndexEnum.Byte:
                    ReadVertex = ReadVertex_Byte;
                    IndexListByte = (byte *)IndexPointer;
                    TotalVerticesWithoutMorphing = 0;
                    for (int n = 0; n < VertexCount; n++)
                    {
                        if (TotalVerticesWithoutMorphing < IndexListByte[n]) TotalVerticesWithoutMorphing = IndexListByte[n];
                    }
                    break;
                case VertexTypeStruct.IndexEnum.Short:
                    ReadVertex = ReadVertex_Short;
                    IndexListShort = (ushort*)IndexPointer;
                    TotalVerticesWithoutMorphing = 0;
                    //VertexCount--;
                    for (int n = 0; n < VertexCount; n++)
                    {
                        //Console.Error.WriteLine(IndexListShort[n]);
                        if (TotalVerticesWithoutMorphing < IndexListShort[n]) TotalVerticesWithoutMorphing = IndexListShort[n];
                    }
                    break;
                default:
                    throw (new NotImplementedException());
            }
            TotalVerticesWithoutMorphing++;

            //Console.WriteLine(TotalVerticesWithoutMorphing);

            int MorpingVertexCount = (int)VertexType.MorphingVertexCount + 1;
            int z = 0;
            VertexInfo TempVertexInfo;

            float* Morphs = &GpuState->MorphingState.MorphWeight0;

            //for (int n = 0; n < MorpingVertexCount; n++) Console.Write("{0}, ", Morphs[n]); Console.WriteLine("");

            //int VertexInfoFloatCount = (sizeof(Color4F) + sizeof(Vector3F) * 3) / sizeof(float);
            int VertexInfoFloatCount = (sizeof(VertexInfo)) / sizeof(float);
            fixed (VertexInfo* VerticesPtr = Vertices)
            {
            #if true
                if (MorpingVertexCount == 1)
                {
                    VertexReader.ReadVertices(0, VerticesPtr, (int)TotalVerticesWithoutMorphing);
                }
                else
                {
                    var ComponentsIn = (float*)&TempVertexInfo;
                    for (int n = 0; n < TotalVerticesWithoutMorphing; n++)
                    {
                        var ComponentsOut = (float*)&VerticesPtr[n];
                        for (int cc = 0; cc < VertexInfoFloatCount; cc++) ComponentsOut[cc] = 0;
                        for (int m = 0; m < MorpingVertexCount; m++)
                        {
                            VertexReader.ReadVertex(z++, &TempVertexInfo);
                            for (int cc = 0; cc < VertexInfoFloatCount; cc++) ComponentsOut[cc] += ComponentsIn[cc] * Morphs[m];
                        }
                        VerticesPtr[n].Normal = VerticesPtr[n].Normal.Normalize();
                    }
                }
            #else
                var ComponentsIn = (float*)&TempVertexInfo;
                for (int n = 0; n < TotalVerticesWithoutMorphing; n++)
                {
                    if (MorpingVertexCount == 1)
                    {
                        VertexReader.ReadVertex(z++, &TempVertexInfo);
                        VerticesPtr[n] = TempVertexInfo;
                        //VertexReader.ReadVertices(0, VerticesPtr, TotalVerticesWithoutMorphing);
                    }
                    else
                    {
                        var ComponentsOut = (float*)&VerticesPtr[n];
                        for (int cc = 0; cc < VertexInfoFloatCount; cc++) ComponentsOut[cc] = 0;
                        for (int m = 0; m < MorpingVertexCount; m++)
                        {
                            VertexReader.ReadVertex(z++, &TempVertexInfo);
                            for (int cc = 0; cc < VertexInfoFloatCount; cc++) ComponentsOut[cc] += ComponentsIn[cc] * Morphs[m];
                        }
                    }
                }
            #endif
            }

            //VertexType.Texture == VertexTypeStruct.TextureEnum.Byte
            //return;
            //PrepareRead(GpuState);

            PrepareStateCommon(GpuState);

            if (GpuState->ClearingMode)
            {
                PrepareStateClear(GpuState);
            }
            else
            {
                PrepareStateDraw(GpuState);
            }

            PrepareStateMatrix(GpuState);

            //GL.Enable(EnableCap.Blend);

            /*
            if (CurrentTexture != null)
            {
                if (CurrentTexture.TextureHash == 0x2202293873)
                {
                    Console.Error.WriteLine(CurrentTexture);
                    Console.Error.WriteLine(VertexCount);
                }
            }
            */

            _CaptureStartPrimitive(PrimitiveType, GpuState->GetAddressRelativeToBaseOffset(GpuState->VertexAddress), VertexCount, ref VertexType);

            // DRAW ACTUALLY
            {
                //uint VertexSize = GpuState->VertexState.Type.GetVertexSize();

                //byte* VertexPtr = (byte*)Memory.PspAddressToPointerSafe(GpuState->VertexAddress);

                //Console.WriteLine(VertexSize);

                var BeginMode = default(BeginMode);

                switch (PrimitiveType)
                {
                    case GuPrimitiveType.Lines: BeginMode = BeginMode.Lines; break;
                    case GuPrimitiveType.LineStrip: BeginMode = BeginMode.LineStrip; break;
                    case GuPrimitiveType.Triangles: BeginMode = BeginMode.Triangles; break;
                    case GuPrimitiveType.Points: BeginMode = BeginMode.Points; break;
                    case GuPrimitiveType.TriangleFan: BeginMode = BeginMode.TriangleFan; break;
                    case GuPrimitiveType.TriangleStrip: BeginMode = BeginMode.TriangleStrip; break;
                    case GuPrimitiveType.Sprites: BeginMode = BeginMode.Quads; break;
                    default: throw (new NotImplementedException("Not implemented PrimitiveType:'" + PrimitiveType + "'"));
                }

                if (PrimitiveType == GuPrimitiveType.Sprites)
                {
                    GL.Disable(EnableCap.CullFace);
                }

                //Console.WriteLine(BeginMode);

                //lock (GpuLock)
                {
                    //Console.Error.WriteLine("GL.Begin : Thread : {0}", Thread.CurrentThread.ManagedThreadId);
                    GL.Begin(BeginMode);
                    {
                        if (PrimitiveType == GuPrimitiveType.Sprites)
                        {
                            GL.Disable(EnableCap.CullFace);
                            for (int n = 0; n < VertexCount; n += 2)
                            {
                                VertexInfo V1, V2, V3, V4;

                                ReadVertex(n + 0, &V1);
                                ReadVertex(n + 1, &V3);
                                {
                                    //if (GpuState->ClearingMode) Console.WriteLine("{0} - {1}", VertexInfoTopLeft, VertexInfoBottomRight);

                                    var Color = V3.Color;
                                    var TZ = V1.Texture.Z;
                                    var PZ = V1.Position.Z;
                                    var NZ = V1.Normal.Z;

                                    V2 = new VertexInfo()
                                    {
                                        Texture = new Vector3F(V3.Texture.X, V1.Texture.Y, TZ),
                                        Position = new Vector3F(V3.Position.X, V1.Position.Y, PZ),
                                        Normal = new Vector3F(V3.Normal.X, V1.Normal.Y, NZ),
                                    };

                                    V4 = new VertexInfo()
                                    {
                                        Texture = new Vector3F(V1.Texture.X, V3.Texture.Y, TZ),
                                        Position = new Vector3(V1.Position.X, V3.Position.Y, PZ),
                                        Normal = new Vector3F(V1.Normal.X, V3.Normal.Y, NZ),
                                    };

                                    V4.Color = V3.Color = V2.Color = V1.Color = Color;
                                    V4.Position.Z = V3.Position.Z = V2.Position.Z = V1.Position.Z = PZ;
                                    V4.Normal.Z = V3.Normal.Z = V2.Normal.Z = V1.Normal.Z = NZ;
                                    V4.Texture.Z = V3.Texture.Z = V2.Texture.Z = V1.Texture.Z = NZ;
                                }
                                PutVertex(ref V1, ref VertexType);
                                PutVertex(ref V2, ref VertexType);
                                PutVertex(ref V3, ref VertexType);
                                PutVertex(ref V4, ref VertexType);
                            }
                        }
                        else
                        {
                            VertexInfo VertexInfo;
                            //Console.Error.WriteLine("{0} : {1} : {2}", BeginMode, VertexCount, VertexType.Index);
                            for (int n = 0; n < VertexCount; n++)
                            {
                                ReadVertex(n, &VertexInfo);
                                PutVertex(ref VertexInfo, ref VertexType);
                            }
                        }
                    }
                    GL.End();
                }
            }

            _CaptureEndPrimitive();

            //Console.WriteLine(VertexCount);

            //PrepareWrite(GpuState);

            #if DEBUG_VERTEX_TYPE
            if (OutputVertexInfoStream != null)
            {
                OutputVertexInfoStream.Close();
                OutputVertexInfoStream = null;
            }
            #endif
        }
示例#25
0
        private void PrepareWrite(GpuStateStruct* GpuState)
        {
            //Console.WriteLine("PrepareWrite");
            try
            {
                var GlPixelFormat = GlPixelFormatList[(int)GpuState->DrawBufferState.Format];
                int Width = (int)GpuState->DrawBufferState.Width;
                int Height = 272;
                int ScanWidth = PixelFormatDecoder.GetPixelsSize(GlPixelFormat.GuPixelFormat, Width);
                int PixelSize = PixelFormatDecoder.GetPixelsSize(GlPixelFormat.GuPixelFormat, 1);
                //GpuState->DrawBufferState.Format
                var Address = (void *)Memory.PspAddressToPointerSafe(GpuState->DrawBufferState.Address);

                //Console.WriteLine("{0}", GlPixelFormat.GuPixelFormat);

                //Console.WriteLine("{0:X}", GpuState->DrawBufferState.Address);
                GL.PixelStore(PixelStoreParameter.PackAlignment, PixelSize);

            #if false
                //GL.WindowPos2(0, 272);
                //GL.PixelZoom(1, -1);

                GL.WindowPos2(0, 0);
                GL.PixelZoom(1, 1);

                GL.ReadPixels(0, 0, Width, Height, PixelFormat.Rgba, GlPixelFormat.OpenglPixelType, new IntPtr(Address));
            #else
                fixed (void* _TempBufferPtr = &TempBuffer[0])
                {
                    GL.ReadPixels(0, 0, Width, Height, PixelFormat.Rgba, GlPixelFormat.OpenglPixelType, new IntPtr(_TempBufferPtr));

                    var Input = (byte*)_TempBufferPtr;
                    var Output = (byte*)Address;

                    for (int Row = 0; Row < Height; Row++)
                    {
                        var ScanIn = (byte *)&Input[ScanWidth * Row];
                        var ScanOut = (byte*)&Output[ScanWidth * (Height - Row - 1)];
                        //Console.WriteLine("{0}:{1},{2},{3}", Row, PixelSize, Width, ScanWidth);
                        PointerUtils.Memcpy(ScanOut, ScanIn, ScanWidth);
                    }
                }
            #endif
            }
            catch (Exception Exception)
            {
                Console.WriteLine(Exception);
            }

            if (SwapBuffers)
            {
                GraphicsContext.SwapBuffers();
            }
        }
示例#26
0
        private void PrepareRead(GpuStateStruct* GpuState)
        {
            #if true
            //#else
            var GlPixelFormat = GlPixelFormatList[(int)GpuState->DrawBufferState.Format];
            int Width = (int)GpuState->DrawBufferState.Width;
            int Height = 272;
            int ScanWidth = PixelFormatDecoder.GetPixelsSize(GlPixelFormat.GuPixelFormat, Width);
            int PixelSize = PixelFormatDecoder.GetPixelsSize(GlPixelFormat.GuPixelFormat, 1);
            //GpuState->DrawBufferState.Format
            var Address = (void*)Memory.PspAddressToPointerSafe(GpuState->DrawBufferState.Address, 0);
            GL.PixelStore(PixelStoreParameter.PackAlignment, PixelSize);
            //Console.WriteLine("PrepareRead: {0:X}", Address);

            try
            {
                GL.WindowPos2(0, 272);
                GL.PixelZoom(1, -1);

                GL.DrawPixels(Width, Height, PixelFormat.Rgba, GlPixelFormat.OpenglPixelType, new IntPtr(Address));
                //GL.DrawPixels(512, 272, PixelFormat.AbgrExt, PixelType.UnsignedInt8888, new IntPtr(Memory.PspAddressToPointerSafe(Address)));

                //GL.WindowPos2(0, 0);
                //GL.PixelZoom(1, 1);
            }
            catch (Exception Exception)
            {
                Console.WriteLine(Exception);
            }
            #endif
        }
示例#27
0
 public override void TextureSync(GpuStateStruct* GpuState)
 {
     //Console.WriteLine("TextureSync!");
     //base.TextureSync(GpuState);
 }
示例#28
0
 public override void TextureFlush(GpuStateStruct* GpuState)
 {
     TextureCache.RecheckAll();
     //Console.WriteLine("TextureFlush!");
     //base.TextureFlush(GpuState);
 }
示例#29
0
 public unsafe override void Prim(GpuStateStruct* GpuState, GuPrimitiveType PrimitiveType, ushort VertexCount)
 {
     //Console.WriteLine("VertexCount: {0}", VertexCount);
     var Start = DateTime.UtcNow;
     {
         _Prim(GpuState, PrimitiveType, VertexCount);
     }
     var End = DateTime.UtcNow;
     //Console.Error.WriteLine("Prim: {0}", End - Start);
 }
示例#30
0
 public override void Finish(GpuStateStruct* GpuState)
 {
     //PrepareWrite(GpuState);
     //return;
     /*
     if (GpuState->DrawBufferState.LowAddress != 0)
     {
         //var Address = PspMemory.FrameBufferOffset | GpuState->DrawBufferState.LowAddress;
         var Address = GpuState->DrawBufferState.Address;
         try
         {
             Console.WriteLine("{0:X}", Address);
             Memory.CheckAndEnforceAddressValid(Address);
             GL.ReadPixels(0, 0, 512, 272, PixelFormat.Rgba, PixelType.UnsignedInt8888, new IntPtr(Memory.PspAddressToPointerSafe(Address)));
         }
         catch (Exception Exception)
         {
             // 0x04000000
             Console.WriteLine("Address: {0:X}", Address);
             Console.WriteLine(Exception);
             //throw(Exception);
         }
     }
     */
 }