Git Product home page Git Product logo

love2dcs's People

Contributors

bartbes avatar endlesstravel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

love2dcs's Issues

Config file example

is there a config file example for love2dcs?
I need to be able to change my screen size.

maybe allowing for a width and height to be passed in to scene?

Custom Vertex Format

Is it in your plans to add custom vertex formats for meshes? They are necessary for making 3d graphics with shaders.

Mouse does not have a method for getting scroll wheel value

Mouse does not have a method for getting scroll wheel value.
could something like this be implemented public int Mouse.GetScrollValue()
idk if its possible to do but a setter version of this would be nice as well
public void Mouse.SetScrollValue(int value)

Embedded Assemblies?

is it possible to embed these assemblies?
image
I would like them to not show up in my project output, however I don't know if I can do this since they are a output from Love2dCS.dll and not my project.

Lua file's load() called automatically and before Love.Scene.Load()

When you enable the Lua module and specify the main file to load up in BootConfig, the framework will initialize the Lua module and call the Lua file's love.load() function (if it's provided) before the C#'s side of things -> Love.Scene.Load().

This is unexpected.

The other two backbone callbacks supported for Lua, Love.Lua.Update() and Love.Lua.Draw(), are supposed to be manually invoked from C#. And that is a good thing, in my opinion. You are writing a C# app and you should be in control of what gets called when. I see Lua as a service to the app, so the app should decide on this.

I think the same rule should apply to the Load() function. In essence, you would do this:

public override void Load()
{
  Love.Lua.Load();
}

...which would invoke the love.load() function in the main Lua file.

The advantage is that you would be able to call it in an order specified by you. Maybe you need to initialize some C# stuff first, and only then initialize the Lua side of things.

Notes:

I'm not sure what to do with the file scope of the Lua file, which runs even before the load() callback, obviously.

Question about the project and the current status of it

I have a few questions about this project...

  • is this project still being updated and if so how long do you currently plan on supporting it?
  • is this project compatible with linux and mac?
  • is this project compatible with raspberry pi?
  • what features are missing from this project that are included in the lua version?

thankyou I am wondering because this is a awesome library and I love being able to use it with C#

Attempted to read or write protected memory

hello I am getting this..
image

image

ZeldaMagic.Core.Game.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Love;

namespace ZeldaMagic.Core
{
		class Boot : Scene
		{
				public static Game Game { get; set; }

				public static void Run(Game game)
				{
						Game = game;

						BootConfig Config   = new BootConfig();
						Config.WindowWidth  = 160;
						Config.WindowHeight = 144;

						var boot = new Boot();
						Console.Write(boot == null);
						Love.Boot.Run(boot, Config);
				}

				public override void Load()
				{
						Game.OnInit();
				}
				public override void Draw()
				{
						Game.OnTick();
				}
				public override bool Quit()
				{
						Game.OnExit();
						return true;
				}
		}
		public class Game
		{
				public static TileBank    TileBank    { get; set; }
				public static ComboBank   ComboBank   { get; set; }
				public static PaletteBank PaletteBank { get; set; }

				//Does nothing
				public static void Run(Game game)
				{
						TileBank    = new TileBank(16, 64, 8, 8);
						ComboBank   = new ComboBank(8, 32, 16, 16);
						PaletteBank = new PaletteBank(1, 256, 16, 1);
						Boot.Run(game);
				}

				//Hooks
				public virtual void OnInit() 
				{ }
				public virtual void OnTick() 
				{ }
				public virtual void OnExit() 
				{ }

				//Draw methods
				public static void DrawPalette(float x, float y, float w, float h, float scale = 1, uint index = 0, uint palette = 0)
				{

						//PaletteBank.Draw(x, y, w, h, scale, index, palette);
				}
				public static void DrawCombo  (float x, float y, float w, float h, float scale = 1, uint index = 0, uint palette = 0)
				{

						//ComboBank.Draw(x, y, w, h, scale, index, palette);
				}
				public static void DrawTile   (float x, float y, float w, float h, float scale = 1, uint index = 0, uint palette = 0)
				{

						//TileBank.Draw(x, y, w, h, scale, index, palette);
				}
		}
}

ZeldaMagic.Engine.Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZeldaMagic.Core;

namespace ZeldaEngine
{

		public class Engine : Game
		{
				//Main
				public static void Main()
				{
						Run(new Engine());
				}

				public override void OnInit()
				{
						Tile tile = new Tile(16);
						tile.Import("stalfaux.png");
						TileBank.Add (new Tile(16));
						ComboBank.Add(new Combo(16));
				}
				public override void OnTick()
				{
						ComboBank.Draw(0, 0, 2, 2, 1, 0, 0);
				}
				public override void OnExit()
				{

				}
		}
}

I am using latest version as of posting this.

Question about Hosting Love2dcs windows in love2dcs windows

this is a long shot of a question...
Is it possible to host and render love2dcs windows in love2dcs windows?
I am asking this because I want to make a gui library which uses native window frames.

the widgets themselves will be customizable but I want the window frame to look native on the os its running on.

Idea for better input mapping

I had an idea for better input mapping.
Idk if this is possible without majorly modifying love2d but if so you could allow something like this...

void SetInput()
{
    //note the any constants
    if (Keyboard.IsPressed(KeyConstant.Any)) // if any keyboard key is pressed
    {
       Keyboard.MapKey(Keyboard.GetKeyDown()) //Set binding to the first currently pressed key
    }
    else if (Joystick.IsPressed(GamepadButton.Any)); // If Joystick is Down
    {
       Joystick.MapButton(Joystick.GetButtonDown()) //Set binding to the first currently pressed button
    }
    else if (Joystick.IsAxisChanged(GamepadAxis.Any));
    {
      Joystick.MapAxis(Joystick.GetAxisChanged()); //Set binding to the first currently chnaged axis
    } 
}

this is just an idea to make input binding easier
what do you think?

the bindings would have to be so they override the default button, axis, or key so for example X might not be X anymore but instead something else

Unable to set depthstencil

When I try to set a canvas with the format depth24 it gives this error:
'Depth/stencil format Canvases must be used with the 'depthstencil' field of the table passed into setCanvas.'

Love.Graphics.Rectangle is not pixel perfect after graphics.Scale()

so I was making a gui library and scaling up the graphics before drawing my window by 4.0fx4.0f and then scaling back down gives me this..

image

here is a example of my code..

        public override void Render()
        {
            base.Render();

            Graphics.Scale(4.0f, 4.0f);

            //WindowFrame Background
            Graphics.SetColor(new Color(63, 63, 63, 255));
            Graphics.Rectangle(DrawMode.Fill, X + 0, Y + 0, W - 0, H - 0);

            //WindowFrame Border
            Graphics.SetColor(new Color(33, 33, 33, 255));
            Graphics.Rectangle(DrawMode.Line, X + 0, Y + 0, W - 0, H - 0);
            Graphics.Rectangle(DrawMode.Line, X + 3, Y + 3, W - 6, H - 6);

            Graphics.SetColor(new Color(123, 123, 123, 255));
            Graphics.Rectangle(DrawMode.Line, X + 1, Y + 1, W - 2, H - 2);

            Graphics.SetColor(new Color(101, 101, 101, 255));
            Graphics.Rectangle(DrawMode.Line, X + 2, Y + 2, W - 4, H - 4);
            
            //Title Bar
            Graphics.SetColor(new Color(33, 33, 33, 255));
            Graphics.Rectangle(DrawMode.Fill, X + 1, Y +  0, W - 2, 16);
            Graphics.SetColor(new Color(240, 212, 149, 255));
            Graphics.Rectangle(DrawMode.Fill, X + 1, Y +  1, W - 2,  1);
            Graphics.SetColor(new Color(224, 169, 42, 255));
            Graphics.Rectangle(DrawMode.Fill, X + 1, Y +  2, W - 2, 13);
            Graphics.SetColor(new Color(168, 127, 31, 255));
            Graphics.Rectangle(DrawMode.Fill, X + 1, Y + 15, W - 2,  1);

            if (IsClicking())
            {
                Graphics.SetColor(new Color(255, 255, 255, 127));
                Graphics.Rectangle(DrawMode.Fill, X + 1, Y + 1, W - 2, 14);
            }
            else if (IsHovering())
            {
                Graphics.SetColor(new Color(255, 255, 255, 63));
                Graphics.Rectangle(DrawMode.Fill, X + 1, Y + 1, W - 2, 14);
            }

            Graphics.Scale(-4.0f, -4.0f);
        }

idk if this has to do with love2dcs or just love2d but it should be pixel perfect if scaling by 1x1 ratio right?

also when the window is inverted the drawing gets all messed up like this..
image

More Helper Functions

  • Mouse.GetPositionPrevius()
  • Mouse.IsPressed()
  • Mouse.IsReleased()

these are some missing functions that are like the ones that were just added.
@endlesstravel tell me if you can think of more I can edit this.

Vector2.Normalized

Currently, if you need a normalized copy of a Vector2, you need to:

var v = new Vector2();
var normalizedV = Vector2.Normalize(v);

I suggest to add a handy "shortcut" function :

public Vector2 Normalized()
{
    return Vector2.Normalize(this);
}

Or make it inline, whichever is better.

So the previous example would go like this:

var v = new Vector2();
var normalizedV = v.Normalized();

This is inspired by Unity's vector structures, which I'm using daily in my job. It's quite natural to use: https://docs.unity3d.com/ScriptReference/Vector3-normalized.html

Question on how to go about creating a input manager

I have a question on how to create a input manager that supports multiple players along with supporting remapping.

I currently thinking about doing something like this..

public class InputMap
{
		public bool Enabled    { get; set; } = false;

		public bool[] A      { get; set; } = { false, false };
		public bool[] B      { get; set; } = { false, false };
		public bool[] X      { get; set; } = { false, false };
		public bool[] Y      { get; set; } = { false, false };
		public bool[] L      { get; set; } = { false, false };
		public bool[] R      { get; set; } = { false, false };
		public bool[] DPadU  { get; set; } = { false, false };
		public bool[] DPadD  { get; set; } = { false, false };
		public bool[] DPadL  { get; set; } = { false, false };
		public bool[] DPadR  { get; set; } = { false, false };
		public bool[] Start  { get; set; } = { false, false };
		public bool[] Select { get; set; } = { false, false };

		public GamepadButton AMap { get; set; } = GamepadButton.A;
		public GamepadButton BMap { get; set; } = GamepadButton.B;
		public GamepadButton XMap { get; set; } = GamepadButton.X;
		public GamepadButton YMap { get; set; } = GamepadButton.Y;
		public GamepadButton LMap { get; set; } = GamepadButton.LeftShoulder;
		public GamepadButton RMap { get; set; } = GamepadButton.RightShoulder;
		...

}

however since Keyboards, Controller Buttons and Controller axises all use different enums and functions I really don't know how to go about doing this

Coroutines and waiting for something?

do you know how to get the equivalent of unity's coroutines in love2dcs?

here is a example..

    void executeWait(float aux)
    {
        StartCoroutine(Wait(aux));
    }

    IEnumerator Wait(float seconds)
    {
        yield return new WaitForSeconds(seconds);
    }

Vector2.X vs Vector2.x

Vector2 starts with defining the fields:

public float X;
public float Y;

...and then continues to implement these properties:

public float x
{
    get { return X; }
    set { X = value; }
}

public float y
{
    get { return Y; }
    set { Y = value; }
}

I find two issues here:

  1. The properties serve no purpose, as they implement no logic other than simply getting and setting the fields. Accessing the fields directly produces the same exact result.
  2. The naming of the properties is odd. Properties in almost all C# APIs are written in PascalCase, whereas these are written in camelCase. I understand that you had to name them something else than the fields, but that only indicates that they are redundant.

I suggest to remove the properties.

Mouse.ISDown() uses base 1 index ids

I just ran into a problem because I thought Mouse.IsDown(0) was the left button
I suggest making it 0 index based and maybe making it use constant.

How do I create a bitmap font?

can you explain how to create a bitmap font?
I currently have this however I am not sure how to pass in the glyphs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Love;

namespace ZeldaEngine.Editor.Widgets
{
    public class Button : Widget
    {
        FileData FontData;
        Font     Font;

        public Button(Widget parent, float x, float y, float w, float h) : base(parent, x, y, w, h)
        {
            IsDraggable = false;

            FontData = FileSystem.NewFileData("C:\\Users\\Shadowblitz16\\source\\repos\\ZeldaEngine\\ZeldaEngine\\Resources\\GB_Font.png");
            Font = Graphics.NewFont(Font.NewBMFontRasterizer(FontData, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz1234567890_+-={}|[]\\:\";'<>?,./"); //this gives a compile error 
        }
    }
}

Mouse GetXPrevious() and Mouse.GetYPrevious()

could the following functions be implemented..
Mouse GetXPrevious()
Mouse.GetYPrevious()

they would be used to check if a mouse just moved to a position or not
these could be used to do gui enter and leave events without having to store mouse position per control

here is a example..

        public bool MouseJustEntered()
        {
            var mX    = ((int)Mouse.GetX());
            var mY    = ((int)Mouse.GetY());
            var mXOld = ((int)Mouse.GetPreviusX());
            var mYOld = ((int)Mouse.GetPreviusY());

            var checkX = (mX >= X && mX < X + W) && (mXOld < X || mXOld >= X + W);
            var checkY = (mY >= Y && mY < Y + H) && (mYOld < Y || mYOld >= Y + H);

            return (checkX && checkY);
        }

Even more Input Idea's

ok bear with me I know there has already been alot of changes to input that love2d didn't have.

this should be my final suggestion for inputs so I will try to make sure I don't miss anything.
the following functions should be implemented for more control over your game

Mouse

  • MouseButton Mouse.GetDown()
  • MouseButton Mouse.GetDownPrevious()
  • bool Mouse.IsDown(MouseButton button)
  • bool Mouse.IsDownPrevious(MouseButton button)

Keyboard

  • KeyConst Keyboard.GetDown()
  • KeyConst Keyboard.GetDownPrevious()
  • bool Keyboard.IsDown(KeyConst key)
  • bool Keyboard.IsDownPrevious(KeyConst key)

GamepadButton

  • GamepadButton Joystick.GetDown()
  • GamepadButton Joystick.GetDownPrevious()
  • bool Joystick.IsDown(GamepadButton button)
  • bool Joystick.IsDownPrevious(GamepadButton button)

GamepadAxis

  • GamepadAxis Joystick.GetAxis()
  • GamepadAxis Joystick.GetAxisPrevious()
  • bool Joystick.IsAxisChange(GamepadAxis axis, bool deadzone)
  • bool Joystick.IsAxisChangePrevious(GamepadAxis axis, bool deadzone)

doing this makes the newer Pressed and Released functions pointless because now you can make your own class and do something like

var Joystick = Joystick.GetJoysticks()[0];
var buttonCurr = Joystick.GetDown();
var buttonPrev = Joystick.GetDownPrevious();
var anyButtonPressed = 
(
    Joystick.GetDown(buttonCurr) && 
   !Joystick.GetDownPrevious(buttonPrev )
);
var anyButtonReleased = 
(
    !Joystick.GetDown(buttonCurr) && 
     Joystick.GetDownPrevious(buttonPrev )
);

which you could remove them or add pressed and released variants for JoyStickAxes as well so we can check if they just changed from 0 or just changed to 0

idk what do you think @endlesstravel?

Large deltas.

hello for some reason I am getting deltas over 1 and trying to limit them with a accumulator makes them just add continuously

public class GameManager : Scene
{
    Game   Game   { get; set; }
    Canvas Canvas { get; set; }

    int GameW     { get; set; } = 256;
    int GameH     { get; set; } = 240;
    int GameFps   { get; set; } = 30;
    int GameScale { get; set; } = 3;

    float UpdateAccumulator = 0.0f;
    float RenderAccumulator = 0.0f;

    public GameManager(Game game, int gameW, int gameH, int gameFps, int gameScale)
    {
        Game      = game;
        GameW     = gameW;
        GameH     = gameH;
        GameFps   = gameFps;
        GameScale = gameScale;
    }

    public override void Load()
    {
        Canvas = Graphics.NewCanvas(GameW, GameH);
        Canvas.SetFilter(FilterMode.Nearest, FilterMode.Nearest, 0);
        base.Load();
        Game.Create();
    }
    public override void Update(float dt)
    {
        UpdateAccumulator += dt;
        var limit = (1 / GameFps);
        if (UpdateAccumulator >= limit)
        {
            base.Update(dt);
            Game.Update();
            UpdateAccumulator -= limit;
        }
    }
    public override void Draw()
    {
        RenderAccumulator += Timer.GetDelta();
        var limit = (1 / GameFps);
        if (RenderAccumulator >= limit)
        {
            base.Draw();
            Graphics.SetCanvas(Canvas);
            Graphics.Clear(0, 0, 0);
            Game.Render();
            Graphics.SetCanvas();
            Graphics.Draw(Canvas, 0, 0, 0, GameScale, GameScale);
            RenderAccumulator -= limit;
        }
    }
}

Initialize love without love window?

Is there a way to initialize love so that I can use the libraries without having the love window popup?

something like Love.Special.InitNoWindow()?

Suggestion more Vector2 properties and Rotate

It would be helpful to have more Vector2 properties:
Vector2 Right => new Vector2(1, 0);
Vector2 Left => new Vector2(-1, 0);
Vector2 Up => new Vector2(0, -1);
Vector2 Down => new Vector2(0, 1);

Also Vector2.Rotate function:
public static Vector2 Rotate(Vector2 vec, float angle) {
return new Vector2 {
X = Mathf.Cos(angle * vec.x) - Mathf.Sin(angle * vec.y),
Y = Mathf.Sin(angle * vec.x) + Mathf.Cos(angle * vec.y)
};
}

Please expose keyboard and joystick pressed and released as functions

Please expose KeyboardPressed, KeyboardReleased, JoystickPressed, JoystickReleased as functions

The keyboard functions would be in the static Keyboard class and the joystick functions would be in the instance Joystick class.

this makes it alot easier to to check of press and released without having to handle them ourselves. it also should be fairly simple to implement behind the scenes

Canvas does not take size paramaters

the canvas object does not take size parameters nor does it have a way to set the width and height of it.
this extremely limits the library as no canvases smaller or larger then the window can be created.

Audio Tags and Setting start and end loop points

can we have the ability to get audio tags and their values as well as a start and end looping point?
it would be something like this..


    public class Sound
    {
        Source Source;

        public Sound(string filename)
        {
            Source = Audio.NewSource(filename, SourceType.Stream);
            Source.SetLoopStart(Source.GetTag("LOOP START"));
            Source.SetLoopEnd  (Source.GetTag("LOOP END"));
            Source.SetLooping  (true);
        }

        public void Play(bool loop)
        {
            Source.Play();
        }
        public void Stop(bool loop)
        {
            Source.Stop();
        }

    }```

File.Read and file.write suggestions

I had a few suggestions for the File class

File.Read and File.Write should by default use the size of the object for the last parameter.
File.Read and File.Write should take in all basic data types..

object
uint
int
byte
byte[]
float
double 
decimal
bool

best way to do the first suggestion would to be make buffer types that the user can pass in

File.Write(data, DataType.uint)

data = File.Read(DataType.uint)

having trouble with graphics.push() and graphics.pop()

so I am having weird issues where graphics.push() and graphics.pop() doesn't seem to be working quite right.

it seems that the popping may not be working.

it might be a oversight on my end but I am getting this..
image

here is a example of my code..

    public class Widget
    {
        //Child Widgets
        protected Widget                     Parent   { get; private set; }
        protected Dictionary<string, Widget> Children { get; private set; } = new Dictionary<string, Widget>();

        //Properties
        public bool   Visable { get; set; } = true;
        public string    Name { get; set; } = "";
        public int          X { get; set; } = 0;
        public int          Y { get; set; } = 0;
        public int          W { get; set; } = 0;
        public int          H { get; set; } = 0;

        //Callers
        public      Widget()
        {
            OnCreate();
        }
        public void Update()
        {
            OnUpdate();
            foreach (var c in Children.Values)
            {
                c.Update();
            }

        }
        public void Render()
        {
            OnRender();
            Graphics.Push();
            Graphics.Translate(X, Y);
            Graphics.SetScissor(X, Y, W, H);
            foreach (var c in Children.Values)
            {
                c.Render();
            }
            Graphics.Pop();
        }

        //Events
        protected virtual void OnCreate()
        {
            W = Love.Graphics.GetWidth();
            H = Love.Graphics.GetHeight();
        }
        protected virtual void OnUpdate()
        {
            W = Love.Graphics.GetWidth();
            H = Love.Graphics.GetHeight();
        }
        protected virtual void OnRender()
        {
            Graphics.Clear(0, 0, 0);
        }

here is a example of my project
https://drive.google.com/open?id=1fpy0Q-E3aKibt7ffaRt7CxL1LHsMQ2LO

Matrix44 multiplication

I looked in your source code and saw that you implemented matrix multiplication but I can't access those functions in my program

Question about filesystem

so uhh I had a question about the filesystem.

its not going to be sandboxed is it?
it would be really nice to support loading and saving several different formats to the project directory.

like for example maybe ini, json, and xml.
this would just be because love2dcs uses C# instead of lua so loading lua files wouldn't make much sense.
however loading lua could be a thing too.

I was just asking this because I am not familiar with love2d's filesystem since I have never used it, and I don't actually know what it supported in the first place.

11.0.29 Crash in Boot.Init()

I just updated to 11.0.29 and the framework crashes right at the start, when calling Boot.Init().

image

System.BadImageFormatException
HResult=0x8007000B
Message=An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
Source=Love2dCS
StackTrace:
at Love.Love2dDll._wrap_love_dll_open_love_math()
at Love.Boot.Init(BootConfig bootConfig)
at Game.Program.Main(String[] args) in E:\MyDocs\Love2DCS\TestProjects\DocsTutorial_HelloWorld\DocsTutorial_HelloWorld\Program.cs:line 10

Question about Embed Resources

Is it possible to use Embed Resources without converting Bitmap into Love.Image?
How soon will the 64 bit version be? (I would like to help, but I don’t know how...)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.