public Video() { m_Screen = Sdl.SDL_SetVideoMode(640, 512, 32, (Sdl.SDL_SWSURFACE | Sdl.SDL_DOUBLEBUF | Sdl.SDL_ANYFORMAT)); m_ScreenSurf = (Sdl.SDL_Surface)Marshal.PtrToStructure(m_Screen, typeof(Sdl.SDL_Surface)); Sdl.SDL_PixelFormat format = (Sdl.SDL_PixelFormat)Marshal.PtrToStructure(m_ScreenSurf.format, typeof(Sdl.SDL_PixelFormat)); for (int i = 0; i < 512; i++) { int b = ((i) & 0x7) * 0x49 >> 1; int r = ((i >> 3) & 0x7) * 0x49 >> 1; int g = ((i >> 6) & 0x7) * 0x49 >> 1; PALETTE[i] = (r << format.Rshift & format.Rmask) | (g << format.Gshift & format.Gmask) | (b << format.Bshift & format.Bmask); } m_ScreenSurf.pitch /= 4; Sdl.SDL_WM_SetCaption("TurboSharp", null); m_VRAM = new ushort[0x10000]; m_SAT = new SpriteAttribute[0x40]; m_VCE = new ushort[0x200]; m_VCE_Index = 0; for (int i = 0; i < 0x40; i++) { m_SAT[i] = new SpriteAttribute(); } m_RenderLine = 0; m_DoSAT_DMA = false; m_WaitingIRQ = false; m_VCE_DotClock = DotClock.MHZ_5; m_VDC_Increment = 1; m_VDC_BSY = false; // We don't halt the CPU }
public static float AssignSpriteAttribute(GameObject go, SpriteAttribute sa) // return length { float ret = 0f; if (sa == null) { return(ret); } if (sa.isAnimation == true && sa.controller != null) { Animator a = go.GetComponent <Animator>(); if (a == null) { a = go.AddComponent <Animator>(); } a.runtimeAnimatorController = Instantiate(sa.controller); a.speed = sa.speed; a.Play("Entry"); ret = sa.length; } else { Animator a = go.GetComponent <Animator>(); if (a != null) { Destroy(a); } go.GetComponent <SpriteRenderer>().sprite = sa.sprite; } return(ret); }
public bool HasAttribute(SpriteAttribute attr) { return((Attributes & (byte)attr) != 0); }
public virtual DisplayObject SetFieldWithReflection(Texture2D texture, V2DInstance inst) { DisplayObject result = null; Type t = this.GetType(); string instName = inst.InstanceName; int index = -1; Match m = lastDigits.Match(instName); if (m.Groups.Count > 2 && t.GetField(instName) == null) { instName = m.Groups[1].Value; index = int.Parse(m.Groups[2].Value, System.Globalization.NumberStyles.None); } FieldInfo fi = t.GetField(instName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy); if (fi != null) { Type ft = fi.FieldType; if (ft.BaseType.Name == typeof(V2DRuntime.Components.Group <>).Name && // IsSubclassOf etc doesn't work on generics? ft.BaseType.Namespace == typeof(V2DRuntime.Components.Group <>).Namespace) { // eg ButtonTabGroup if (fi.GetValue(this) == null) { ConstructorInfo ci = ft.GetConstructor(new Type[] { typeof(Texture2D), typeof(V2DInstance) }); result = (DisplayObject)ci.Invoke(new object[] { texture, inst }); fi.SetValue(this, result); } } else if (ft.IsArray) { object array = fi.GetValue(this); Type elementType = ft.GetElementType(); if (array == null) { int arrayLength = GetArrayLength(instName); array = Array.CreateInstance(elementType, arrayLength); fi.SetValue(this, array); } // add element ConstructorInfo elementCtor = elementType.GetConstructor(new Type[] { typeof(Texture2D), typeof(V2DInstance) }); result = (DisplayObject)elementCtor.Invoke(new object[] { texture, inst }); MethodInfo mi = array.GetType().GetMethod("SetValue", new Type[] { elementType, index.GetType() }); mi.Invoke(array, new object[] { result, index }); } else if (typeof(System.Collections.ICollection).IsAssignableFrom(ft)) { Type[] genTypes = ft.GetGenericArguments(); if (genTypes.Length == 1) // only support single type generics (eg List<>) for now { Type gt = genTypes[0]; object collection = fi.GetValue(this); if (collection == null) // ensure list created { ConstructorInfo ci = ft.GetConstructor(new Type[] { }); collection = ci.Invoke(new object[] { }); fi.SetValue(this, collection); } // add element ConstructorInfo elementCtor = gt.GetConstructor(new Type[] { typeof(Texture2D), typeof(V2DInstance) }); result = (DisplayObject)elementCtor.Invoke(new object[] { texture, inst }); PropertyInfo cm = collection.GetType().GetProperty("Count"); int cnt = (int)cm.GetValue(collection, new object[] { }); // pad with nulls if needs to skip indexes (order is based on flash depth, not index) while (index > cnt) { MethodInfo mia = collection.GetType().GetMethod("Add"); mia.Invoke(collection, new object[] { null }); cnt = (int)cm.GetValue(collection, new object[] { }); } if (index < cnt) { MethodInfo mia = collection.GetType().GetMethod("RemoveAt"); mia.Invoke(collection, new object[] { index }); } MethodInfo mi = collection.GetType().GetMethod("Insert"); mi.Invoke(collection, new object[] { index, result }); } } //else if (ft.Equals(typeof(TextBox)) || ft.IsSubclassOf(typeof(TextBox))) //{ // ConstructorInfo ci = ft.GetConstructor(new Type[] { }); // result = (DisplayObject)ci.Invoke(new object[] { }); // fi.SetValue(this, result); //} else if (ft.Equals(typeof(DisplayObject)) || ft.IsSubclassOf(typeof(DisplayObject))) { ConstructorInfo ci = ft.GetConstructor(new Type[] { typeof(Texture2D), typeof(V2DInstance) }); result = (DisplayObject)ci.Invoke(new object[] { texture, inst }); fi.SetValue(this, result); } else { throw new ArgumentException("Not supported field type. " + ft.ToString() + " " + instName); } } if (result != null) { result.Index = index; // set for all object, -1 if not in collection result.RootName = instName; // apply attributes System.Attribute[] attrs = System.Attribute.GetCustomAttributes(fi); // reflection foreach (System.Attribute attr in attrs) { if (attr is SpriteAttribute) { SpriteAttribute a = (SpriteAttribute)attr; result.DepthGroup = a.depthGroup; } if (attr is V2DSpriteAttribute) { if (result is V2DSprite) { V2DSpriteAttribute a = (V2DSpriteAttribute)attr; V2DSprite sp = (V2DSprite)result; sp.attributeProperties = a; sp.SetGroupIndex(a.groupIndex); sp.IsStatic = a.isStatic; } } } // need to do this separately to ensure the depth group is set in previous step if (this is Screen) { Screen scr = (Screen)this; // field attirbutes foreach (System.Attribute attr in attrs) { if (attr is V2DShaderAttribute && !scr.shaderMap.ContainsKey(result.DepthGroup)) { V2DShaderAttribute vsa = (V2DShaderAttribute)attr; float[] parameters = new float[] { }; ConstructorInfo ci = vsa.shaderType.GetConstructor(new Type[] { parameters.GetType() }); scr.shaderMap.Add( result.DepthGroup, (V2DShader)ci.Invoke(new object[] { new float[] { vsa.param0, vsa.param1, vsa.param2, vsa.param3, vsa.param4 } }) ); } } } } return(result); }
// private void LoadSprite() { countLoadSprite = 0; loadingSpriteNameList.Clear(); string fullPath = Application.dataPath + "/" + RESOURCES_PATH + "/" + SPRITE_PATH + "/"; // Sprite Directory 이하의 Directory 들을 가져옴 string[] targetDirectoryWithPath = System.IO.Directory.GetDirectories(fullPath); List <string> targetDirectoryWithPathList = new List <string>(targetDirectoryWithPath); targetDirectoryWithPathList.Add(fullPath); for (int i = 0; i < targetDirectoryWithPathList.Count; ++i) { // directory 들 이하의 png file 들을 가져옴 string[] spriteNameWithPath = System.IO.Directory.GetFiles(targetDirectoryWithPathList[i], "*.png"); CustomLog.CompleteLog("Sprite Root: " + targetDirectoryWithPathList[i]); for (int j = 0; j < spriteNameWithPath.Length; ++j) { if (spriteNameWithPath[j].Substring(0, 1) == EXCLUDE_KEYWORD) { continue; } // 4 파트로 나뉜 이름 string[] strType = { "", "", "", "" }; string[] splitName = GetSplitName(spriteNameWithPath[j]); // 소문자로 설정 ToLowerNames(ref splitName); for (int k = 0; k < Mathf.Min(4, splitName.Length); ++k) { strType[k] = splitName[k]; } SpriteAttribute sa = new SpriteAttribute(); // resource.load 를 위한 이름 string resourceLoadName = GetLoadingName(spriteNameWithPath[j]); sa.sprite = Resources.Load <Sprite>(resourceLoadName); if (GetSpriteAttribute(strType) == "") { sa.isAnimation = false; } else { sa.isAnimation = true; sa.frameCount = GetSpriteFrameCount(strType); sa.speed = GetSpriteSpeed(strType); sa.length = (1f / (float)spriteDefaultFramePerSec) / sa.speed * (float)(sa.frameCount - 1); } CutSpriteAttribute(ref strType); // if (sa.sprite == null) { CustomLog.CompleteLogWarning( "Invalid Sprite: " + resourceLoadName, PRINT_DEBUG); continue; } loadingSpriteNameList.Add(strType[0] + " " + strType[1] + " " + strType[2]); string category = strType[0]; string name = strType[1]; string status = strType[2]; if (typeSpriteDic.ContainsKey(category) == false) { typeSpriteDic.Add(category, new Dictionary <string, Dictionary <string, SpriteAttribute> >()); } if (typeSpriteDic[category].ContainsKey(name) == false) { typeSpriteDic[category].Add(name, new Dictionary <string, SpriteAttribute>()); } if (typeSpriteDic[category][name].ContainsKey(status) == false) { typeSpriteDic[category][name].Add(status, sa); } ++countLoadSprite; } } for (int i = 0; i < targetDirectoryWithPathList.Count; ++i) { string[] controllerNameWithPath = System.IO.Directory.GetFiles(targetDirectoryWithPathList[i], "*.controller"); // load 된 sprite 가 animation 이면 attribute 에 controller 추가 for (int k = 0; k < controllerNameWithPath.Length; ++k) { string[] strTypeController = { "", "", "" }; string[] splitControllerName = GetSplitName(controllerNameWithPath[k]); // 소문자로 설정 ToLowerNames(ref splitControllerName); for (int l = 0; l < Mathf.Min(3, splitControllerName.Length); ++l) { strTypeController[l] = splitControllerName[l]; } CutSpriteAttribute(ref strTypeController); SpriteAttribute sa = GetSpriteAttribute(strTypeController[0], strTypeController[1], strTypeController[2]); if (sa != null) { if (sa.isAnimation == true) { string controllerLoadName = GetLoadingName(controllerNameWithPath[k]); sa.controller = Instantiate(Resources.Load <RuntimeAnimatorController>(controllerLoadName)); } } } } CustomLog.CompleteLog("Load Sprite Count: " + countLoadSprite); }
public void LoadSprite() { countLoadSprite = 0; loadingSpriteNameList.Clear(); string fullPath = Application.dataPath + "/" + RESOURCES_PATH + "/" + SPRITE_PATH + "/"; // Sprite Directory 이하의 Directory 들을 가져옴 string[] targetDirectoryWithPath = System.IO.Directory.GetDirectories(fullPath); for (int i = 0; i < targetDirectoryWithPath.Length; ++i) { // directory 들 이하의 png file 들을 가져옴 string[] spriteNameWithPath = System.IO.Directory.GetFiles(targetDirectoryWithPath[i], "*.png"); for (int j = 0; j < spriteNameWithPath.Length; ++j) { if (spriteNameWithPath[j] == EXCLUDE_KEYWORD) { continue; } // 4 파트로 나뉜 이름 string[] strType = { "", "", "", "" }; string[] splitName = GetSplitName(spriteNameWithPath[j]); for (int k = 0; k < splitName.Length; ++k) { strType[k] = splitName[k]; } SpriteAttribute sa = new SpriteAttribute(); // resource.load 를 위한 이름 string resourceLoadName = GetLoadingName(spriteNameWithPath[j]); sa.sprite = Resources.Load <Sprite>(resourceLoadName); sa.frameCount = GetSpriteFrameCount(strType); sa.speed = GetSpriteSpeed(strType, sa.frameCount); sa.cycle = (1f / (float)spriteDefaultFramePerSec) / sa.speed * (float)(sa.frameCount - 1); CutSpriteAttribute(ref strType); // if (sa.sprite == null) { CustomLog.CompleteLogWarning( "Invalid Sprite: " + resourceLoadName, PRINT_DEBUG); continue; } loadingSpriteNameList.Add(strType[0] + " " + strType[1] + " " + strType[2]); string category = strType[0]; string name = strType[1]; string status = strType[2]; if (typeSpriteDic.ContainsKey(category) == false) { typeSpriteDic.Add(category, new Dictionary <string, Dictionary <string, SpriteAttribute> >()); } if (typeSpriteDic[category].ContainsKey(name) == false) { typeSpriteDic[category].Add(name, new Dictionary <string, SpriteAttribute>()); } if (typeSpriteDic[category][name].ContainsKey(status) == false) { typeSpriteDic[category][name].Add(status, sa); } ++countLoadSprite; } } Debug.Log("Load Sprite Count: " + countLoadSprite); }
public static void SetSpriteCycleTime(ref SpriteAttribute sa, float time) { sa.cycle = time; sa.speed = (1f / (float)spriteDefaultFramePerSec) / time * (float)(sa.frameCount - 1); }
public unsafe void Update() { if (m_RenderLine + 1 > m_VDC_VDW) { int DmaCycles = CYCLES_PER_LINE / (int)m_VCE_DotClock; if (m_DoSAT_DMA) { DmaCycles -= 256; // We lose 256 cycles for SAT DMA // COPY SPRITE DATA OVER for (int i = 0, g = m_VDC_VSAR; i < 64; i++) { m_SAT[i].m_Y = m_VRAM[g++] - 64; m_SAT[i].m_X = m_VRAM[g++] - 32; m_SAT[i].m_Pattern = (m_VRAM[g] & 0x07FE) << 5; m_SAT[i].m_CGPage = (m_VRAM[g++] & 0x0001) != 0; m_SAT[i].m_Palette = ((m_VRAM[g] & 0xF) << 4) | ((i == 0) ? 0x4100 : 0x2100); m_SAT[i].m_Priority = (m_VRAM[g] & 0x80) != 0; m_SAT[i].m_Width = ((m_VRAM[g] & 0x100) != 0) ? 2 : 1; m_SAT[i].m_Height = (((m_VRAM[g] & 0x3000) >> 12) + 1) << 4; m_SAT[i].m_HorizontalFlip = (m_VRAM[g] & 0x0800) != 0; m_SAT[i].m_VerticalFlip = (m_VRAM[g++] & 0x8000) != 0; } if (m_VDC_SATBDMA_IRQ) { m_VDC_DS = true; m_WaitingIRQ = true; } m_DoSAT_DMA = false; } if (m_VDC_DMA_Enable) { while (DmaCycles >= 2) { m_VRAM[m_VDC_DSTDECR ? m_VDC_DESR-- : m_VDC_DESR++] = m_VRAM[m_VDC_SRCDECR ? m_VDC_DSR-- : m_VDC_DSR++]; DmaCycles -= 2; if (--m_VDC_LENR == 0) { m_VDC_DMA_Enable = false; if (m_VDC_VRAMDMA_IRQ) { m_VDC_DV = true; m_WaitingIRQ = true; } } } } } else { int i; // Active Display Sdl.SDL_LockSurface(m_Screen); int *spr = (int *)m_ScreenSurf.pixels.ToPointer(); spr += m_ScreenSurf.pitch * 510; for (i = 0; i < (m_VDC_HDR + 1) * 8; i++) { spr[i] = 0; } int BufferIndexes = 0; SpriteAttribute[] SprBuffer = new SpriteAttribute[17]; if (m_VDC_EnableSprites) { int BufferUsage; for (i = 0, BufferUsage = 0; i < 64 && BufferUsage < 17; i++) { int y = m_SAT[i].m_Y; if (m_RenderLine < y || m_RenderLine >= y + m_SAT[i].m_Height) { continue; } BufferUsage += m_SAT[i].m_Width; SprBuffer[BufferIndexes++] = m_SAT[i]; } if (BufferUsage > 16) { if (m_VDC_SprOvIRQ) { m_VDC_OR = true; m_WaitingIRQ = true; } BufferUsage = 16; } } for (i = BufferIndexes - 1; i >= 0; i--) { int SprOffY; if (SprBuffer[i].m_VerticalFlip) { SprOffY = SprBuffer[i].m_Height - 1 - m_RenderLine + SprBuffer[i].m_Y; } else { SprOffY = m_RenderLine - SprBuffer[i].m_Y; } int tile = SprBuffer[i].m_Pattern + ((SprOffY & 0xFFF0) << 3) + (SprOffY & 0xF); int x = SprBuffer[i].m_X; int *spx = spr; spx += x; if (x >= (m_VDC_HDR + 1) << 3) { continue; } if (x > -32) { switch (SprBuffer[i].m_Width) { case 1: DrawSPRTile(ref spx, SprBuffer[i].m_Palette, tile, SprBuffer[i].m_Priority, SprBuffer[i].m_HorizontalFlip); break; case 2: if (SprBuffer[i].m_HorizontalFlip) { DrawSPRTile(ref spx, SprBuffer[i].m_Palette, tile + 64, SprBuffer[i].m_Priority, true); DrawSPRTile(ref spx, SprBuffer[i].m_Palette, tile, SprBuffer[i].m_Priority, true); } else { DrawSPRTile(ref spx, SprBuffer[i].m_Palette, tile, SprBuffer[i].m_Priority, false); DrawSPRTile(ref spx, SprBuffer[i].m_Palette, tile + 64, SprBuffer[i].m_Priority, false); } break; } } } if (m_VDC_EnableBackground) { // Fix for register latch mid frame int RealBYR = (m_VDC_BYR - m_VDC_BYR_Offset) & 0x3FF; int BATMask = (m_VDC_BAT_Width - 1); // Set BAT address to the Y offset of the scanline int BATLine = (((RealBYR + m_RenderLine) >> 3) & (m_VDC_BAT_Height - 1)) * m_VDC_BAT_Width; int BATAddress = (m_VDC_BXR >> 3) & BATMask; int YOverFlow = (RealBYR + m_RenderLine) & 0x7; // We will be offsetting the screen by it's X-Scroll value int *tileMap = spr; tileMap -= m_VDC_BXR & 7; for (i = -1; i <= m_VDC_HDR; i++) { int tile = m_VRAM[BATAddress | BATLine]; DrawBGTile(ref tileMap, (tile & 0xF000) >> 8, (tile & 0xFFF) << 4 | YOverFlow); BATAddress = (BATAddress + 1) & BATMask; } } // Run the outputted value through the VCE int *src_a = (int *)m_ScreenSurf.pixels.ToPointer(), src_b; src_a += (m_ScreenSurf.w - (m_VDC_HDR + 1) * (int)m_VCE_DotClock * 4) / 2; src_b = src_a += m_ScreenSurf.pitch * m_RenderLine * 2; src_b += m_ScreenSurf.pitch; int screenWidth = (m_VDC_HDR + 1) * 8; switch (m_VCE_DotClock) { case DotClock.MHZ_10: for (i = 0; i < screenWidth; i++, spr++) { if ((*spr & 0x6000) == 0x6000) { m_VDC_CR = m_VDC_Spr0Col; } int clr = PALETTE[m_VCE[*spr & 0x1FF]]; *(src_b++) = *(src_a++) = clr; } break; case DotClock.MHZ_7: for (i = 0; i < screenWidth; i += 2) { int clr1 = *(spr++); int clr2 = *(spr++); if ((clr1 & 0x6000) == 0x6000 || (clr2 & 0x6000) == 0x6000) { m_VDC_CR = m_VDC_Spr0Col; } clr1 = PALETTE[m_VCE[clr1 & 0x1FF]]; clr2 = PALETTE[m_VCE[clr2 & 0x1FF]]; *(src_b++) = *(src_a++) = clr1; *(src_b++) = *(src_a++) = ((clr1 & 0xFEFEFE) + (clr2 & 0xFEFEFE)) >> 1; *(src_b++) = *(src_a++) = clr2; } break; case DotClock.MHZ_5: for (i = 0; i < screenWidth; i++, spr++) { if ((*spr & 0x6000) == 0x6000) { m_VDC_CR = m_VDC_Spr0Col; } int clr = PALETTE[m_VCE[*spr & 0x1FF]]; *(src_b++) = *(src_a++) = clr; *(src_b++) = *(src_a++) = clr; } break; } Sdl.SDL_UnlockSurface(m_Screen); } m_RenderLine++; // We are in vertical blank if (m_RenderLine + 1 == m_VDC_VDW) { m_DoSAT_DMA = m_DoSAT_DMA | m_VDC_SATB_ENA; if (m_VDC_VBKIRQ) { m_VDC_VD = true; m_WaitingIRQ = true; } } else if (m_RenderLine + 0x3F == m_VDC_RCR) { if (m_VDC_RCRIRQ) { m_VDC_RR = true; m_WaitingIRQ = true; } } // End of vertical sync if (m_RenderLine >= 262) { int s = System.DateTime.UtcNow.Second; FramesCalculated++; if ((s + 60 - LastSecond) % 60 >= 3) { Console.WriteLine("{0} frames per second", FramesCalculated / 3); FramesCalculated = 0; LastSecond = s; } int ticks = Sdl.SDL_GetTicks(); if (ticks < TargetTicks) { System.Threading.Thread.Sleep((int)(TargetTicks - ticks)); } else { TargetTicks = Sdl.SDL_GetTicks(); } TargetTicks += 1000.0 / 60.0f; Sdl.SDL_Flip(m_Screen); m_RenderLine = 0; } }
/// <summary> /// /// </summary> /// <param name="part"></param> /// <param name="value"></param> /// <returns></returns> public override spritestudio.attribute.AttributeBase CreateKeyFrame( SpritePart part, SpriteAttribute.ValueBase value ) { Value v = (Value) value; return spritestudio.attribute.VertexUpdater.Create( v.lt, v.rt, v.lb, v.rb ); }