static void DrawMyChar(Graphics g, CSData dat, int camx, int camy) { g.DrawRectangle(Pens.Cyan, toScreen(dat.MyCharX - 0xA00 - camx), toScreen(dat.MyCharY - 0x1000 - camy), toScreen(0xA00 * 2), toScreen(0x1000 * 2)); g.DrawRectangle(Pens.Cyan, toScreen(dat.MyCharX - 0x400 - camx), toScreen(dat.MyCharY - 0x400 - camy), toScreen(0x400 * 2), toScreen(0x400 * 2)); g.DrawRectangle(Pens.Cyan, toScreen(dat.MyCharX - 0x800 - camx), toScreen(dat.MyCharY - 0x800 - camy), toScreen(0x800 * 2), toScreen(0x800 * 2)); g.DrawLine(Pens.Cyan, toScreen(dat.MyCharX - camx), toScreen(dat.MyCharY - 0x1000 - camy), toScreen(dat.MyCharX - camx), toScreen(dat.MyCharY + 0x1000 - camy)); g.DrawLine(Pens.Cyan, toScreen(dat.MyCharX - 0x0A00 - camx), toScreen(dat.MyCharY - camy), toScreen(dat.MyCharX + 0x0A00 - camx), toScreen(dat.MyCharY - camy)); }
public Form1() { dat = new CSData(); CSSearch = new System.Timers.Timer(1000); CSSearch.Elapsed += (sender, e) => { WorkRestartEvent.Set(); }; var frameSync = Task.Run(() => { while (true) { finishWait.Reset(); var pid = FindCaveStory(); handle = OpenCaveStory(pid); if (handle == 0) { goto wait; } var ptls = GetTls(handle, pid); while (!finishedFlag && (isAlive(handle) != 0)) { UInt32 tid, opt; if (WaitFrame(handle, out pid, out tid, out opt)) { GetCSData(handle, dat, ptls); datLoaded = true; if (frameDelay > 0) { Thread.Sleep(frameDelay); } ContinueFrame(pid, tid); Screen.Invalidate(); } else { continue; } } Detach(handle, pid); wait: datLoaded = false; Screen.Invalidate(); WorkRestartEvent.Reset(); finishWait.Set(); WorkRestartEvent.WaitOne(); if (finishedFlag) { return; } } }); CSSearch.Start(); InitializeComponent(); }
static void DrawSprites(Graphics g, CSData dat, int camx, int camy) { for (int i = 0; i < 512; i++) { DrawOneSprite(g, dat.SpriteDB[i], camx, camy); } for (int i = 0; i < 16; i++) { DrawOneSprite(g, dat.MBSpriteDB[i], camx, camy); } }
static void GetCamXY(CSData dat, out int camx, out int camy) { camx = camMyChar ? dat.MyCharX - (0x2000 * 20 / 2) : dat.CameraX; camy = camMyChar ? dat.MyCharY - (0x2000 * 15 / 2) : dat.CameraY; if (camMyChar) { camx = Math.Max(camx, 0); camx = Math.Min(camx, (dat.MapWidth << 13) - (0x2000 * 21)); camy = Math.Max(camy, 0); camy = Math.Min(camy, (dat.MapHeight << 13) - (0x2000 * 16)); } }
public static Image GetVScreen(CSData dat) { Bitmap vscr = new Bitmap(320 * scale, 240 * scale); Graphics g = Graphics.FromImage(vscr); int camx, camy; GetCamXY(dat, out camx, out camy); DrawTiles(g, dat, camx, camy); DrawSprites(g, dat, camx, camy); DrawBullet(g, dat, camx, camy); DrawMyChar(g, dat, camx, camy); g.Dispose(); return(vscr); }
static void DrawBullet(Graphics g, CSData dat, int camx, int camy) { for (int i = 0; i < 64; i++) { var bs = dat.BulletShotDB[i]; if (bs.Exist == 0) { continue; } g.DrawRectangle(Pens.Yellow, toScreen(bs.X - bs.CollisionRect.left - camx), toScreen(bs.Y - bs.CollisionRect.top - camy), toScreen(bs.CollisionRect.left + bs.CollisionRect.right), toScreen(bs.CollisionRect.top + bs.CollisionRect.bottom)); } }
public static void Present(Graphics g, CSData dat) { g.DrawString( String.Format( "Pos X:{0, 10} = 0x2000*{3, 4} {4} 0x{5, 4:X}", +dat.MyCharX, (dat.MyCharX < 0) ? '-' : ' ', Math.Abs(dat.MyCharX), (dat.MyCharX + 0x1000) / 0x2000, (((dat.MyCharX + 0x1000) % 0x2000 - 0x1000) < 0) ? '-' : '+', Math.Abs((dat.MyCharX + 0x1000) % 0x2000 - 0x1000)), f, Brushes.White, new Point(0, 0)); g.DrawString( String.Format( "Pos Y:{0, 10} = 0x2000*{3, 4} {4} 0x{5, 4:X}", +dat.MyCharY, (dat.MyCharY < 0) ? '-' : ' ', Math.Abs(dat.MyCharY), (dat.MyCharY + 0x1000) / 0x2000, (((dat.MyCharY + 0x1000) % 0x2000 - 0x1000) < 0) ? '-' : '+', Math.Abs((dat.MyCharY + 0x1000) % 0x2000 - 0x1000)), f, Brushes.White, new Point(0, 30)); g.DrawString( String.Format( "Vel X:{0, 10}", dat.MyCharVelX, (dat.MyCharVelX < 0) ? '-' : ' ', Math.Abs(dat.MyCharVelX)), f, Brushes.White, new Point(0, 70)); g.DrawString( String.Format( "Vel Y:{0, 10}", dat.MyCharVelY, (dat.MyCharVelY < 0) ? '-' : ' ', Math.Abs(dat.MyCharVelY)), f, Brushes.White, new Point(0, 100)); { Point p = new Point(130, 250); Size sz = new Size(160, 160); g.DrawRectangle( (dat.MyCharCollisionState & 0x100) != 0 ? Pens.Aqua : Pens.White, new Rectangle( p.X - sz.Width / 2, p.Y - sz.Height / 2, sz.Width, sz.Height)); { Pen ColPen = new Pen(Brushes.LawnGreen, 3); Pen FloPen = new Pen(Brushes.Pink, 6); { if ((dat.MyCharCollisionState & 0x1000) > 0) { g.DrawLine( FloPen, new Point(p.X - sz.Width / 2 - 10, p.Y - sz.Height / 2), new Point(p.X - sz.Width / 2 - 10, p.Y + sz.Height / 2)); } if ((dat.MyCharCollisionState & 0x2000) > 0) { g.DrawLine( FloPen, new Point(p.X - sz.Width / 2, p.Y - sz.Height / 2 - 10), new Point(p.X + sz.Width / 2, p.Y - sz.Height / 2 - 10)); } if ((dat.MyCharCollisionState & 0x4000) > 0) { g.DrawLine( FloPen, new Point(p.X + sz.Width / 2 + 10, p.Y - sz.Height / 2), new Point(p.X + sz.Width / 2 + 10, p.Y + sz.Height / 2)); } if ((dat.MyCharCollisionState & 0x8000) > 0) { g.DrawLine( FloPen, new Point(p.X - sz.Width / 2, p.Y + sz.Height / 2 + 10), new Point(p.X + sz.Width / 2, p.Y + sz.Height / 2 + 10)); } } { if ((dat.MyCharCollisionState & 1) > 0) { g.DrawLine( ColPen, new Point(p.X - sz.Width / 2, p.Y - sz.Height / 2), new Point(p.X - sz.Width / 2, p.Y + sz.Height / 2)); } if ((dat.MyCharCollisionState & 2) > 0) { g.DrawLine( ColPen, new Point(p.X - sz.Width / 2, p.Y - sz.Height / 2), new Point(p.X + sz.Width / 2, p.Y - sz.Height / 2)); } if ((dat.MyCharCollisionState & 4) > 0) { g.DrawLine( ColPen, new Point(p.X + sz.Width / 2, p.Y - sz.Height / 2), new Point(p.X + sz.Width / 2, p.Y + sz.Height / 2)); } if ((dat.MyCharCollisionState & 8) > 0) { g.DrawLine( ColPen, new Point(p.X - sz.Width / 2, p.Y + sz.Height / 2), new Point(p.X + sz.Width / 2, p.Y + sz.Height / 2)); } } { if ((dat.MyCharCollisionState & 0x10) > 0) { g.DrawLine( ColPen, new Point(p.X + sz.Width / 2, p.Y - sz.Height / 2), new Point(p.X - sz.Width / 2, p.Y + sz.Height / 2)); } if ((dat.MyCharCollisionState & 0x20) > 0) { g.DrawLine( ColPen, new Point(p.X - sz.Width / 2, p.Y - sz.Height / 2), new Point(p.X + sz.Width / 2, p.Y + sz.Height / 2)); } } { if ((dat.MyCharCollisionState & 0x10000) > 0) { g.DrawLine( ColPen, new Point(p.X - sz.Width / 2, p.Y - sz.Height / 2), new Point(p.X + sz.Width / 2, p.Y)); } if ((dat.MyCharCollisionState & 0x20000) > 0) { g.DrawLine( ColPen, new Point(p.X + sz.Width / 2, p.Y + sz.Height / 2), new Point(p.X - sz.Width / 2, p.Y)); } if ((dat.MyCharCollisionState & 0x40000) > 0) { g.DrawLine( ColPen, new Point(p.X - sz.Width / 2, p.Y + sz.Height / 2), new Point(p.X + sz.Width / 2, p.Y)); } if ((dat.MyCharCollisionState & 0x80000) > 0) { g.DrawLine( ColPen, new Point(p.X + sz.Width / 2, p.Y - sz.Height / 2), new Point(p.X - sz.Width / 2, p.Y)); } } } { g.DrawLine( new Pen(Brushes.Red, 4), p, new Point( p.X + dat.MyCharVelX * sz.Width / 2 / 1536, p.Y + dat.MyCharVelY * sz.Height / 2 / 1536)); } } g.DrawString(String.Format(" Frame:{0, 10}", dat.Frame), f, Brushes.White, new Point(0, 360)); g.FillRectangle(Brushes.DarkGreen, 200, 401, dat.BoosterFuel * 250 / 50, 28); g.DrawRectangle(dat.BoostInfo != 0 ? Pens.Red : Pens.White, 200, 401, 250, 28); g.DrawString(String.Format("BoosterFuel:{0, 10}", dat.BoosterFuel), f, Brushes.White, new Point(0, 400)); g.FillRectangle(Brushes.DarkSlateBlue, 200, 441, dat.MyCharAir * 250 / 1000, 28); g.DrawRectangle((dat.MyCharCollisionState & 0x100) != 0 ? Pens.Red : Pens.White, 200, 441, 250, 28); g.DrawString(String.Format(" AirRemain:{0, 10}", dat.MyCharAir), f, Brushes.White, new Point(0, 440)); g.FillRectangle(Brushes.DarkSalmon, 200, 481, dat.MyCharDamageTimer * 250 / 128, 28); g.DrawRectangle(Pens.White, 200, 481, 250, 28); g.DrawString(String.Format("DamageTimer: {0, 8}", dat.MyCharDamageTimer), f, Brushes.White, new Point(0, 480)); g.DrawString(String.Format("MyCharState:0x{0, 8:X}", dat.MyCharState), f, Brushes.White, new Point(0, 520)); g.DrawString(String.Format(" holdrand:{0, 10}", dat.holdrand), f, Brushes.White, new Point(0, 560)); Pen ypen = new Pen(Color.Yellow); Brush gbrush = new SolidBrush(Color.Green); g.DrawString(" Sprite", f, Brushes.White, new Point(0, 600)); g.FillRectangle(gbrush, 160, 600, 256, 100); for (int i = 0; i < 4; i++) { for (int j = 0; j < 128; j++) { var n = 128 * i + j; if (dat.SpriteDB[n].Existence != 0) { g.DrawLine(ypen, 160 + 2 * j, 600 + i * 25, 160 + 2 * j, 600 + i * 25 + 25); } } } g.FillRectangle(gbrush, 160, 702, 32, 25); for (int i = 0; i < 16; i++) { if (dat.MBSpriteDB[i].Existence != 0) { g.DrawLine(ypen, 160 + 2 * i, 702, 160 + 2 * i, 727); } } g.DrawString(" Effect", f, Brushes.White, new Point(0, 730)); g.FillRectangle(Brushes.Green, 160, 732, 128, 25); for (int i = 0; i < 64; i++) { if (dat.EffectExist[i] != 0) { g.DrawLine(ypen, 160 + 2 * i, 732, 160 + 2 * i, 732 + 25); } } g.DrawString("NumEffect", f, Brushes.White, new Point(0, 760)); g.FillRectangle(Brushes.Green, 160, 762, 32, 25); for (int i = 0; i < 16; i++) { if (dat.NumEffectExist[i] != 0) { g.DrawLine(ypen, 160 + 2 * i, 762, 160 + 2 * i, 762 + 25); } } g.DrawString(" Shot", f, Brushes.White, new Point(0, 790)); g.FillRectangle(Brushes.Green, 160, 792, 128, 25); for (int i = 0; i < 64; i++) { if (dat.BulletShotDB[i].Exist != 0) { g.DrawLine(ypen, 160 + 2 * i, 792, 160 + 2 * i, 792 + 25); } } g.DrawString(String.Format("Cmd:{0, 10}", dat.ScriptStr.Replace("\r", "").Replace("\n", " ")), f, Brushes.White, new Point(0, 820)); g.FillRectangle(Brushes.DarkSalmon, 200, 861, Math.Min(dat.EventTimer, 16) * 250 / 16, 28); g.DrawRectangle(Pens.White, 200, 861, 250, 28); g.DrawString(String.Format(" EventTimer:{0, 4}", dat.EventTimer), f, Brushes.White, new Point(0, 860)); g.DrawString( String.Format( "{0, 2}'{1:00}\"{2:00}", dat._290Timer / (50 * 60), (dat._290Timer / 50) % 60, (dat._290Timer * 100 / 50) % 100), f, Brushes.White, new Point(325, 210)); g.DrawString( String.Format( "{0}/{1}", dat.MyCharHP, dat.MyCharMaxHP), f, Brushes.White, new Point(325, 240)); var vscr = DoukutsuRenderer.GetVScreen(dat); g.DrawImage(vscr, 470, 210); g.DrawRectangle(Pens.White, 470, 210, 320 * 3, 240 * 3); g.FillRectangle(Brushes.DarkRed, 470 + (dat.UsingBulletIndex % 2) * 480, 88 + (dat.UsingBulletIndex / 2) * 28, 480, 30); for (int i = 0; i < 8; i++) { var trueType = dat.PossessBulletDB[i].type * 3 + dat.PossessBulletDB[i].lv - 1; g.DrawString( String.Format( "{0, 2} Lv{1} Exp{2, 3}/{3, 3} {4, 3}/{5, 3}", GetBulletName(dat.PossessBulletDB[i].type), dat.PossessBulletDB[i].lv, dat.PossessBulletDB[i].exp, trueType < 0 ? "-" : dat.BulletMaxExpTbl[trueType].ToString(), dat.PossessBulletDB[i].shotNum, dat.PossessBulletDB[i].shotNumMax), f, Brushes.White, new PointF(470 + (i % 2) * 480, 85 + (i / 2) * 28)); } vscr.Dispose(); }
static extern void GetCSData(int handle, [Out] CSData dat, int pTls);
static void DrawTiles(Graphics g, CSData dat, int camx, int camy) { int x0 = ((camx >> 9) + 8) >> 4; int y0 = ((camy >> 9) + 8) >> 4; for (int y = 0; y < 16; y++) { for (int x = 0; x < 21; x++) { int index = (y0 + y) * dat.MapWidth + (x0 + x); if (index < 0) { continue; } int type = dat.TileTypeDB[dat.TileMapDB[index]]; if ((type & 0x20) != 0 && type != 0x62) { g.DrawRectangle( Pens.DarkSlateBlue, toScreen((x0 + x) * 0x2000 - camx - 0x0A00), toScreen((y0 + y) * 0x2000 - camy - 0x0A00), toScreen(0xA00 * 2), toScreen(0xA00)); } int type_sub = type & ~0x20; switch (type_sub) { case 0x05: case 0x41: case 0x43: case 0x46: g.DrawPolygon(type == 0x43 ? Pens.GhostWhite : Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x0800)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x0A00), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x0A00), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x0800)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x0800)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x0A00), toScreen((y0 + y) * 0x2000 - camy + 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x0A00), toScreen((y0 + y) * 0x2000 - camy + 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x0800)) }); break; case 0x42: if ((type & 0x20) != 0) { g.DrawRectangle( Pens.MediumVioletRed, toScreen((x0 + x) * 0x2000 - camx - 0x0800), toScreen((y0 + y) * 0x2000 - camy - 0x0600), toScreen(0x800 * 2), toScreen(0x600 * 2)); } else { g.DrawRectangle( Pens.DarkRed, toScreen((x0 + x) * 0x2000 - camx - 0x0800), toScreen((y0 + y) * 0x2000 - camy - 0x0600), toScreen(0x800 * 2), toScreen(0x600 * 2)); } break; case 0x50: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)) }); break; case 0x51: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy)) }); break; case 0x52: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy)) }); break; case 0x53: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy)) }); break; case 0x54: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)) }); break; case 0x55: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)) }); break; case 0x56: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)) }); break; case 0x57: g.DrawPolygon(Pens.Gray, new PointF[] { new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy - 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx + 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)), new PointF( toScreen((x0 + x) * 0x2000 - camx - 0x1000), toScreen((y0 + y) * 0x2000 - camy + 0x1000)) }); break; default: break; } } } }