From 0566ecfdd7aba67a213c1b23465ed6f07e3cdb7e Mon Sep 17 00:00:00 2001 From: xeons Date: Mon, 29 Jun 2015 21:08:19 -0500 Subject: [PATCH] Initial commit --- About.dfm | 169 ++++++ About.pas | 33 ++ BlockEditor.dfm | Bin 0 -> 1246 bytes BlockEditor.pas | 160 +++++ Map.pas | 128 ++++ MapEditor.ddp | Bin 0 -> 51 bytes MapEditor.dfm | 1475 ++++++++++++++++++++++++++++++++++++++++++++++ MapEditor.pas | 1151 ++++++++++++++++++++++++++++++++++++ Misc.pas | 30 + Pokémap.ico | Bin 0 -> 1080 bytes RedMap.bdsproj | 170 ++++++ RedMap.dof | 132 +++++ RedMap.dpr | 20 + RedMap.res | Bin 0 -> 1220 bytes Tileset.pas | 93 +++ event-object.png | Bin 0 -> 1352 bytes 16 files changed, 3561 insertions(+) create mode 100644 About.dfm create mode 100644 About.pas create mode 100644 BlockEditor.dfm create mode 100644 BlockEditor.pas create mode 100644 Map.pas create mode 100644 MapEditor.ddp create mode 100644 MapEditor.dfm create mode 100644 MapEditor.pas create mode 100644 Misc.pas create mode 100644 Pokémap.ico create mode 100644 RedMap.bdsproj create mode 100644 RedMap.dof create mode 100644 RedMap.dpr create mode 100644 RedMap.res create mode 100644 Tileset.pas create mode 100644 event-object.png diff --git a/About.dfm b/About.dfm new file mode 100644 index 0000000..cf57c1f --- /dev/null +++ b/About.dfm @@ -0,0 +1,169 @@ +object AboutDialog: TAboutDialog + Left = 0 + Top = 0 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSingle + Caption = 'About' + ClientHeight = 255 + ClientWidth = 417 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + PixelsPerInch = 96 + TextHeight = 13 + object Shape1: TShape + Left = 64 + Top = 0 + Width = 353 + Height = 216 + Pen.Color = clWhite + end + object Bevel1: TBevel + Left = 0 + Top = 216 + Width = 417 + Height = 2 + end + object Shape2: TShape + Left = 0 + Top = 0 + Width = 65 + Height = 217 + Brush.Color = clRed + Pen.Color = clSkyBlue + Pen.Style = psClear + Pen.Width = 0 + end + object AppNameLabel: TLabel + Left = 72 + Top = 8 + Width = 46 + Height = 13 + Caption = 'RedMap' + Color = clWhite + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Transparent = False + end + object Label1: TLabel + Left = 72 + Top = 192 + Width = 271 + Height = 13 + Caption = 'Joint effort by Xeon, Koolboyman, and BlueSonic' + Color = clWhite + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + object VersionLabel: TLabel + Left = 72 + Top = 24 + Width = 79 + Height = 13 + Caption = 'Version 2.0 Beta' + Color = clWhite + ParentColor = False + end + object Image1: TImage + Left = 16 + Top = 16 + Width = 32 + Height = 32 + Picture.Data = { + 055449636F6E0000010002001010100000000000280100002600000020201000 + 00000000E80200004E0100002800000010000000200000000100040000000000 + C000000000000000000000001000000000000000000000000000800000800000 + 00808000800000008000800080800000C0C0C000808080000000FF0000FF0000 + 00FFFF00FF000000FF00FF00FFFF0000FFFFFF000000000000000000000F7000 + 000F7000880F7088880F7088880F7088880F70880000000000000000FFFFFFFF + FFFFFFFFF888888FF888888FFFFFFFFFFFFFFFFF0FFF00FF0F0FF00F00FF0F0F + 0F0F00FF0F0F0F0F00FF0F0F0F0F0F0F0F0F000F00FFF00F0F0FF0FF77777777 + 7777770700000000000000007777777777777777E7E7FFFF0000FFFF0000FFFF + 0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF + 0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF280000002000000040000000 + 0100040000000000800200000000000000000000100000000000000000000000 + 000080000080000000808000800000008000800080800000C0C0C00080808000 + 0000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000000000 + 000000000000000000000000000F7000000F70000000000000000000880F7088 + 880F70888888888887000000880F7088880F7088888888888700000000000000 + 000000007777777777000000FFFFFFFFFFFFFFFFFFFFFFFFFF000000F888888F + F888888F77777777FF000000FFFFFFFFFFFFFFFF77777777770000000FFF00FF + 0F0FF00FF777778FFF00000000FF0F0F0F0F00FFFFFFFFFFFF0000000F0F0F0F + 00FF0F0F778F7777FF0000000F0F0F0F0F0F000F778F7777FF00000000FFF00F + 0F0FF0FFFFFFFFFFFF00000077777777777777077777778FFF00000000000000 + 000000007777778FFF0000007777777777777777FFFFFFFFFF000000F777778F + F777778FF777778FFF000000FFFFFFFFFFFFFFFFFFFFFFFFFF000000778F7777 + 778F7777778F7777FF000000778F7777778F7777778F7777FF000000FFFFFFFF + FFFFFFFFFFFFFFFFFF0000007777778F7777778F7777778FFF0000007777778F + 7777778F7777778FFF000000FFFFFFFFFFFFFFFFFFFFFFFFFF00000080000008 + 8000000880000008FF00000007F8F88007F8F88007F8F880FF0000000F7F8780 + 0F7F87800F7F8780FF0000000FF7F8F00FF7F8F00FF7F8F0FF0000000FFF7F80 + 0FFF7F800FFF7F80FF0000000FFFF7F00FFFF7F00FFFF7F0FF00000080000008 + 8000000880000008FF000000777777777777777777777777FF000000E7E7FFFF + 0000003F0000001F0000001F0000001F0000001F0000001F0000001F0000001F + 0000001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F + 0000001F0000001F0000001F0000001F0000001F0000001F0000001F0000001F + 0000001F0000001F0000001F0000001F0000001F0000001F0000001F0D0A} + end + object Button1: TButton + Left = 336 + Top = 224 + Width = 75 + Height = 23 + Cancel = True + Caption = 'OK' + Default = True + ModalResult = 1 + TabOrder = 0 + end + object Memo1: TMemo + Left = 72 + Top = 48 + Width = 337 + Height = 137 + BorderStyle = bsNone + Lines.Strings = ( + 'Special thanks to BlueSonic (aka Jigglypuff) for letting me use ' + 'some of GoldMap to forge this frankenstein of a program. And ' + 'for putting up with all my questions regarding Delphi.' + '' + 'Koolboyman for the immense amount of data and information you ' + 'provided me. ' + '' + 'Tauwasser for showing me how the warp-to points, connection ' + 'data, and ram addresses where calculated. ' + '' + 'And also, tons of respect to the author of ZeroMap, you where ' + 'my inspiration for how to go about displaying the connected ' + 'maps.' + '' + 'This program is not endorsed or supported by Nintendo, and the ' + 'author is not affiliated with any other corporate entity.' + '' + 'This program is Freeware and provided "as is". The author ' + + 'cannot be held liable for damages any kind arising from it'#39's use' + + ' or ' + 'presence.' + '' + 'Pok'#233'mon is copyright of '#169'1995-2005 ' + 'Nintendo/Creatures Inc./GAME FREAK Inc.') + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 1 + end +end diff --git a/About.pas b/About.pas new file mode 100644 index 0000000..0efd5da --- /dev/null +++ b/About.pas @@ -0,0 +1,33 @@ +unit About; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, StdCtrls, pngimage, ExtCtrls; + +type + TAboutDialog = class(TForm) + Shape1: TShape; + Bevel1: TBevel; + Shape2: TShape; + AppNameLabel: TLabel; + Label1: TLabel; + VersionLabel: TLabel; + Image1: TImage; + Button1: TButton; + Memo1: TMemo; + private + { Private declarations } + public + { Public declarations } + end; + +var + AboutDialog: TAboutDialog; + +implementation + +{$R *.dfm} + +end. diff --git a/BlockEditor.dfm b/BlockEditor.dfm new file mode 100644 index 0000000000000000000000000000000000000000..10adde938003b3b2b2452fd4eca30cc70784be4c GIT binary patch literal 1246 zcmah|O>Yx15OuQceq^_$m0ARXLyt&EReOXJ&8ATzn(nGGRGh%sohDWsJ9r(M-nj8o z_#^xX{s?FA+PmpTDsl7J^WMC9GydB`xP6wy?@v2@oLqF1ivc>?`L%%%PP<1txXna1 zJ- z%E$T?lewaTyOAM2u$7{iQQ)cvbUabc4;0$?lICjSyl8C3f(hvb8EY%vB^g9r!PQ|r zA+iAFMJMOO{^z)Naxpx`E&F5uQN}JQ&&4%{r3%f1Ez$fFnCP6$z;!X1h#9d!BR53b z3Cm*%L_t#a7x<|tXsO%Vo{M270eGwhgY*+_^E{20Gke}j=@M9xYGZgdX?|&y^{dKT z$i-)51T4UmfjJpZo6FMDroU;LZtl5t{>rh<67Uw)_?9tnjo?{D@N%8NHHce==p@f2 z6vZ0HtBT|GI)`6j3`>7T#$X3o&ao|)ww0b~Wv5~}s96r&cp(ctNH>!mNycHq2Vzk` zM_hAnf3;|uW_4Ys48%8hB&EDA4KYH((w~$tPzvtqcxQDu-%%~(s1_1tvPXEH3d&Vo z%Bb19!}YkBwG6AJh4pp_#&i>{)#=#E@$XIexK{J^=|_;NN+$9UOOj3XX9@28Aa_)p z3l2UeBeRlCgaVurEnJuKjd?5oktu{8`v2*_ZSU4RkN154*~}#2MuWFiBTa}9@^E{h zl;F{ad9J^a4U7-YZ>z6f^*6N<&sVGNT9DU)E3#lJxb3>(=?}+fHuZMz5}PYs^&h#3 Bk9Gh6 literal 0 HcmV?d00001 diff --git a/BlockEditor.pas b/BlockEditor.pas new file mode 100644 index 0000000..88b4856 --- /dev/null +++ b/BlockEditor.pas @@ -0,0 +1,160 @@ +//****************************************************************************** +//GoldMap +//by BlueSonic (aka Jigglypuff) +//****************************************************************************** +unit BlockEditor; + +interface + +uses +SysUtils, Controls, Classes, Forms, StdCtrls, ExtCtrls, Graphics; + +type + TBlockEditorForm = class(TForm) + ScrollBox1: TScrollBox; + TileLabel: TLabel; + BlockLabel: TLabel; + UpdateButton: TButton; + AddressLabel: TLabel; + BlockEditBox: TImage; + BlockBox: TPaintBox; + TilePalette: TImage; + procedure FormCreate(Sender: TObject); + procedure BlockBoxMouseMove(Sender: TObject; Shift: TShiftState; X,Y: Integer); + procedure BlockBoxMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); + procedure LoadTile; + procedure SaveTile; + procedure UpdateTile; + procedure TilePaletteMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); + procedure TilePaletteMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure BlockEditBoxMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); + procedure UpdateButtonClick(Sender: TObject); + procedure BlockBoxPaint(Sender: TObject); + procedure BlockEditBoxMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + public + BlockStart,SelTile,TileNumber : Integer; + BlockData: array [0..15] of Byte; + end; + +implementation + +uses MapEditor; + +{$R *.DFM} + +procedure TBlockeditorForm.LoadTile; +begin + Rom.Position := BlockStart; + //loads block + Rom.Read(BlockData, SizeOf(BlockData)); +end; + +procedure TBlockeditorForm.SaveTile; +begin + Rom.Position := BlockStart; + //Saves block + Rom.Write(BlockData, SizeOf(BlockData)); +end; + +procedure TBlockeditorForm.UpdateTile; +var + X,Y,I: Integer; + TileX, TileY, TileNumber: Byte; +begin + I := 0; + //draws tiles into block + for Y := 0 to 3 do + for X := 0 to 3 do + begin + TileNumber := BlockData[I]; + //calculate x and y coordinate where to copy tile from, the tileset picture has 16 tiles per line + TileY := TileNumber div 16; + TileX := TileNumber mod 16; + //draw tile to block picture + BlockEditBox.Picture.Bitmap.Canvas.CopyRect(Rect(X*8,Y*8,X*8+8,Y*8+8),Tiles.Canvas,Rect(TileX*8,TileY*8,TileX*8+8,TileY*8+8)); + Inc(I); + end; +end; + +procedure TBlockEditorForm.FormCreate(Sender: TObject); +begin + //create block bitmap + BlockEditBox.Picture.Bitmap := TBitmap.Create; + BlockEditBox.Picture.Bitmap.Height := 32; + BlockEditBox.Picture.Bitmap.Width := 32; + BlockEditBox.Picture.Bitmap.PixelFormat := pf24bit; + //initalize other stuff + //BlockBox.Picture.Bitmap := MainForm.BlockPalette.Picture.Bitmap; + BlockBox.Height := MapEditorForm.BlockPalette.Height; + TilePalette.Picture.Graphic := Tiles; + //TilePalette.Height := Tiles.Height; + Caption := 'Block Editor - Tileset ' + IntToStr(LoadedTileset); + BlockStart := TilesetStart; + LoadTile; + UpdateTile; +end; + +procedure TBlockEditorForm.BlockBoxMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); +begin + BlockLabel.Caption := 'Block: $' + IntToHex(Y div 32, 2); + AddressLabel.Caption := 'Offset: $' + IntToHex(TilesetStart + ((Y div 32) * 16), 2); +end; + +procedure TBlockEditorForm.BlockBoxMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + BlockStart := TilesetStart + ((Y div 32) * 16); + TileNumber := Y div 32; + LoadTile; + UpdateTile; +end; + +procedure TBlockEditorForm.TilePaletteMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); +begin + TileLabel.Caption := 'Tile: $' + IntToHex((X div 8) + ((Y div 8) * 8), 2); +end; + +procedure TBlockEditorForm.TilePaletteMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + //gets tile where cursor is + SelPic := (X div 8) + ((Y div 8) * 8); +end; + +procedure TBlockEditorForm.BlockEditBoxMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + if Button = mbLeft then + begin + //puts selected tile into block + BlockData[(X div 8) + ((Y div 8) * 4)] := SelPic; + UpdateTile; + end + else + begin + SelPic := BlockData[(X div 8) + ((Y div 8) * 4)]; + end; +end; + +procedure TBlockEditorForm.UpdateButtonClick(Sender: TObject); +begin + SaveTile; + //draws edited tile into tileset + BlockPics[TileNumber].Canvas.Draw(0, 0, BlockEditBox.Picture.Bitmap); + //update block palette + MapEditorForm.DrawBlocks(MapEditorForm.BlockPalette.Canvas); + MapEditorForm.DrawBlocks(BlockBox.Canvas); + MapEditorForm.DrawMap(MapEditorForm.MapBox.Canvas); + RomModified := True; +end; + +procedure TBlockEditorForm.BlockBoxPaint(Sender: TObject); +begin + MapEditorForm.DrawBlocks(BlockBox.Canvas); +end; + +procedure TBlockEditorForm.BlockEditBoxMouseMove(Sender: TObject; + Shift: TShiftState; X, Y: Integer); +begin + TileLabel.Caption := 'Tile: $' + IntToHex(BlockData[(X div 8) + ((Y div 8) * 4)], 2); +end; + +end. diff --git a/Map.pas b/Map.pas new file mode 100644 index 0000000..65273df --- /dev/null +++ b/Map.pas @@ -0,0 +1,128 @@ +unit Map; + +interface + +uses ComCtrls,SysUtils,Dialogs,Classes; + +type + +TConnectionData = packed record + MapNumber: Byte; + MapDataPointer: Word; + MapLocationRamPointer: Word; + WidthHeightVisiblePart: Byte; + YChangePoint: Byte; + XChangePoint: Byte; + Unknown: Byte; + UnknownPointer: Word; +end; + +//Header 1 +TMapHeader = packed record + TilesetNumber: Byte; + Height: Byte; + Width: Byte; + DataPointer: Word; + ObjectScriptPointers: Word; + LevelScriptPointer: Word; + ConnectionDataControl: Byte; + ConnectionData: array [$00..$03] of TConnectionData; + ObjectDataPointer: Word; + BorderBlock: Byte; +end; + +const +Ln = #13#10; + +//table needed for encoding area names +Table: array [$00..$FF] of string[4] = ( +{ 0 1 2 3 4 5 6 7 8 9 A B C D E F } +{0}'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{1}'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,' ' , +{2}'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{3}'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{4}'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,Ln , +{5}'#' ,Ln+Ln ,'HIRO','GARY','POKé',Ln ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{6}'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{7}'#' ,'#' ,'#' ,'#' ,'#' ,'…' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,' ' , +{8}'A' ,'B' ,'C' ,'D' ,'E' ,'F' ,'G' ,'H' ,'I' ,'J' ,'K' ,'L' ,'M' ,'N' ,'O' ,'P' , +{9}'Q' ,'R' ,'S' ,'T' ,'U' ,'V' ,'W' ,'X' ,'Y' ,'Z' ,'#' ,'#' ,':' ,'#' ,'#' ,'#' , +{A}'a' ,'b' ,'c' ,'d' ,'e' ,'f' ,'g' ,'h' ,'i' ,'j' ,'k' ,'l' ,'m' ,'n' ,'o' ,'p' , +{B}'q' ,'r' ,'s' ,'t' ,'u' ,'v' ,'w' ,'x' ,'y' ,'z' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{C}'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{D}'#' ,'''l' ,'''m' ,'''r' ,'''s' ,'''t' ,'''v' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{E}'''' ,'#' ,'#' ,'-' ,'#' ,'#' ,'?' ,'!' ,'.' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' ,'#' , +{F}'#' ,' ' ,'#' ,'#' ,',' ,'#' ,'0' ,'1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' +); + +function GBPtrToFilePos(Bank: Byte; Addr: Word): Integer; overload; +function GBBank(Position: Integer): Byte; +procedure ReadMapHeaderLocations; +function GetMapHeader(MapIndex: Byte): TMapHeader; + +var + AreaNames: TStringList; + BankLocations: array [$00..$F9] of Byte; + MapHeaderOffsets: array [$00..$F9] of Word; + +implementation + +uses MapEditor; + +//converts rombank and, address in that bank, into romfile offset +function GBPtrToFilePos(Bank: Byte; Addr: Word): Integer; overload; +begin + Result := (Bank * $4000) + (Addr xor $4000); +end; + +//gives gameboy rombank number ar specified file offset +function GBBank(Position: Integer): Byte; +begin + Result := (Position div $4000); +end; + +procedure ReadMapHeaderLocations; +begin + Rom.Position := $C23D; + Rom.Read(BankLocations, $F9); + Rom.Position := $01AE; + Rom.Read(MapHeaderOffsets, $F9 * sizeof(Word)); +end; + +function GetMapHeader(MapIndex: Byte): TMapHeader; +var + TempHeader: TMapHeader; +begin + Rom.Position := GBPtrToFilePos(BankLocations[MapIndex], MapHeaderOffsets[MapIndex]); + + Rom.Read(TempHeader.TilesetNumber, 1); + Rom.Read(TempHeader.Height, 1); + Rom.Read(TempHeader.Width, 1); + Rom.Read(TempHeader.DataPointer, 2); + Rom.Read(TempHeader.ObjectScriptPointers, 2); + Rom.Read(TempHeader.LevelScriptPointer, 2); + Rom.Read(TempHeader.ConnectionDataControl, 1); + + if (TempHeader.ConnectionDataControl and $08) = $08 then + Rom.Read(TempHeader.ConnectionData[0], SizeOf(TConnectionData)); + + if (TempHeader.ConnectionDataControl and $04) = $04 then + Rom.Read(TempHeader.ConnectionData[1], SizeOf(TConnectionData)); + + if (TempHeader.ConnectionDataControl and $02) = $02 then + Rom.Read(TempHeader.ConnectionData[2], SizeOf(TConnectionData)); + + if (TempHeader.ConnectionDataControl and $01) = $01 then + Rom.Read(TempHeader.ConnectionData[3], SizeOf(TConnectionData)); + + Rom.Read(TempHeader.ObjectDataPointer, 2); + + Rom.Position := GBPtrToFilePos(BankLocations[MapIndex], + TempHeader.ObjectDataPointer); + + Rom.Read(TempHeader.BorderBlock, 1); + + Result := TempHeader; +end; + +end. diff --git a/MapEditor.ddp b/MapEditor.ddp new file mode 100644 index 0000000000000000000000000000000000000000..4370276c196a7fa73d6f8917622cba1c4e033dee GIT binary patch literal 51 zcmZRVaB=ks@bJ`g@pN<#a`e>;@DB=c^Y`)e=VxGe;K0Pl$;KI)SCUzhlbT}4#=r!G E07ZHWvj6}9 literal 0 HcmV?d00001 diff --git a/MapEditor.dfm b/MapEditor.dfm new file mode 100644 index 0000000..b63f98a --- /dev/null +++ b/MapEditor.dfm @@ -0,0 +1,1475 @@ +object MapEditorForm: TMapEditorForm + Left = 193 + Top = 122 + Width = 655 + Height = 699 + Caption = 'RedMap' + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + Menu = MainMenu1 + OldCreateOrder = False + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 13 + object PageControl1: TPageControl + Left = 0 + Top = 33 + Width = 639 + Height = 588 + ActivePage = TabSheet1 + Align = alClient + TabOrder = 0 + object TabSheet1: TTabSheet + Caption = 'Map' + object MapScrollBox: TScrollBox + Left = 0 + Top = 0 + Width = 582 + Height = 560 + HorzScrollBar.Tracking = True + VertScrollBar.Tracking = True + Align = alClient + BorderStyle = bsNone + TabOrder = 0 + Visible = False + object MapBox: TPaintBox + Left = 0 + Top = 0 + Width = 129 + Height = 121 + Cursor = crDrag + OnMouseDown = MapBoxMouseDown + OnMouseMove = MapBoxMouseMove + OnMouseUp = MapBoxMouseUp + OnPaint = MapBoxPaint + end + object shpHighlight: TShape + Left = 0 + Top = 0 + Width = 32 + Height = 32 + Brush.Color = 33023 + Enabled = False + Pen.Mode = pmMask + Pen.Style = psClear + Pen.Width = 0 + end + end + object BlockPaletteScrollBox: TScrollBox + Left = 582 + Top = 0 + Width = 49 + Height = 560 + HorzScrollBar.Tracking = True + VertScrollBar.Tracking = True + Align = alRight + BevelInner = bvNone + BevelOuter = bvNone + BorderStyle = bsNone + TabOrder = 1 + Visible = False + object BlockPalette: TPaintBox + Left = 0 + Top = 0 + Width = 32 + Height = 105 + Cursor = crHandPoint + OnMouseDown = BlockPaletteMouseDown + OnMouseMove = BlockPaletteMouseMove + OnPaint = BlockPalettePaint + end + end + end + object TabSheet2: TTabSheet + Caption = 'Events' + ImageIndex = 1 + object NoEventsLabel: TLabel + Left = 16 + Top = 16 + Width = 170 + Height = 13 + Caption = 'Events for this map are not loaded.' + Visible = False + WordWrap = True + end + object EventScrollBox: TScrollBox + Left = 0 + Top = 0 + Width = 631 + Height = 560 + HorzScrollBar.Tracking = True + VertScrollBar.Tracking = True + Align = alClient + BorderStyle = bsNone + TabOrder = 0 + Visible = False + object SignpostImage: TImage + Left = 256 + Top = 128 + Width = 32 + Height = 32 + Visible = False + end + object PeopleImage: TImage + Left = 296 + Top = 128 + Width = 32 + Height = 32 + Visible = False + end + object WarpImage: TImage + Left = 216 + Top = 128 + Width = 32 + Height = 32 + Visible = False + end + object EventBox: TPaintBox + Left = 0 + Top = 0 + Width = 100 + Height = 105 + end + object TriggerImage: TImage + Left = 336 + Top = 128 + Width = 32 + Height = 32 + Visible = False + end + end + end + object TabSheet3: TTabSheet + Caption = 'Wild Pok'#233'mon' + ImageIndex = 2 + object NoWildPkmnLabel: TLabel + Left = 8 + Top = 8 + Width = 449 + Height = 26 + Caption = + 'It seems this map does not have wild Pok'#233'mon data associated to ' + + 'it. Some maps do not have wild Pok'#233'mon at all (e.g. indoor place' + + 's).' + WordWrap = True + end + object LandGroup1: TGroupBox + Left = 8 + Top = 40 + Width = 385 + Height = 249 + Caption = 'Land Pok'#233'mon' + TabOrder = 0 + object OffsetLabel1: TLabel + Left = 200 + Top = 176 + Width = 35 + Height = 13 + Caption = 'Offset:' + end + object LandOffset1: TLabel + Left = 240 + Top = 176 + Width = 18 + Height = 13 + Caption = '$00' + end + object LandPkmnBox: TListBox + Left = 16 + Top = 24 + Width = 105 + Height = 137 + Hint = 'Wild Pok'#233'mon on land' + Style = lbOwnerDrawFixed + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlack + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ItemHeight = 13 + Items.Strings = ( + '' + '' + '' + '' + '' + '' + '' + '' + '' + '') + ParentFont = False + TabOrder = 0 + OnClick = LandPkmnBoxClick + end + object LandLevelBox: TListBox + Left = 128 + Top = 24 + Width = 41 + Height = 137 + Enabled = False + ItemHeight = 13 + TabOrder = 1 + end + object LandPkmnGroup: TGroupBox + Left = 200 + Top = 24 + Width = 169 + Height = 49 + Caption = 'Pokemon' + TabOrder = 2 + object LandPkmnCombo: TComboBox + Left = 8 + Top = 20 + Width = 153 + Height = 21 + Style = csDropDownList + Enabled = False + ItemHeight = 13 + TabOrder = 0 + Items.Strings = ( + '00 Missingno' + '01 Rydon' + '02 Kangaskahn' + '03 Nidoran M' + '04 Clefairy' + '05 Spearow' + '06 Voltorb' + '07 Nidoking' + '08 Slowbro' + '09 Ivysaur' + '0A Eggecutor' + '0B Licktung' + '0C Exegute' + '0D Grimer' + '0E Gengar' + '0F Nidoran F' + '10 Nidoqueen' + '11 Cubone' + '12 Ryhorn' + '13 Lapras' + '14 Arcanine' + '15 Mew' + '16 Gyrados' + '17 Shellder' + '18 Tentacool' + '19 Gastly' + '1A Scyther' + '1B Staryu' + '1C Blastoice' + '1D Pinser' + '1E Tangala' + '1F **Bad Pokemon**' + '20 **Bad Pokemon**' + '21 Growlithe' + '22 Onix' + '23 Fearow' + '24 Pidgey' + '25 Slowpoke' + '26 Kadabra' + '27 Graveler' + '28 Chansey' + '29 Machoke' + '2A Mr. Mime' + '2B Hitmonlee' + '2C Hitmonchan' + '2D Arbok' + '2E Parasect' + '2F Psyduck' + '30 Drowzee' + '31 Golom' + '32 **Bad Pokemon**' + '33 Magmar' + '34 **Bad Pokemon**' + '35 Electabuzz' + '36 Magneton' + '37 Koffing' + '38 **Bad Pokemon**' + '39 Mankey' + '3A Seel' + '3B Digglett' + '3C Tarous' + '3D **Bad Pokemon**' + '3E **Bad Pokemon**' + '3F **Bad Pokemon**' + '40 FarFetche'#39'd' + '41 Venonat' + '42 Dragonite' + '43 **Bad Pokemon**' + '44 **Bad Pokemon**' + '45 **Bad Pokemon**' + '46 Doduo' + '47 Poliwag' + '48 Jynx' + '49 Moltres' + '4A Articuno' + '4B Zapdos' + '4C Ditto' + '4D Meowth' + '4E Krabby' + '4F **Bad Pokemon**' + '50 **Bad Pokemon**' + '51 **Bad Pokemon**' + '52 Vulpix' + '53 Ninetails' + '54 Pikachu' + '55 Raichu' + '56 **Bad Pokemon**' + '57 **Bad Pokemon**' + '58 Dratini' + '59 Dragonair' + '5A Kabuto' + '5B Kabutops' + '5C Horsea' + '5D Seadra' + '5E **Bad Pokemon**' + '5F **Bad Pokemon**' + '60 Sandshrew' + '61 Sandslash' + '62 Omanyte' + '63 Omaster' + '64 Jigglypuff' + '65 Wigglytuff' + '66 Eevee' + '67 Flareon' + '68 Jolteon' + '69 Vaporeon' + '6A Machop' + '6B Zubat' + '6C Ekans' + '6D Paras' + '6E Poliwhirl' + '6F Poliwrath' + '70 Weedle' + '71 Kakuna' + '72 Beedril' + '73 **Bad Pokemon**' + '74 Dodrio' + '75 Primeape' + '76 Dugtrio' + '77 Venomoth' + '78 Dewgong' + '79 **Bad Pokemon**' + '7A **Bad Pokemon**' + '7B Caterpie' + '7C Metapod' + '7D Butterfree' + '7E Machamp' + '7F **Bad Pokemon**' + '80 Golduck' + '81 Hypno' + '82 Golbat' + '83 Mewtwo' + '84 Snorlax' + '85 Magikarp' + '86 **Bad Pokemon**' + '87 **Bad Pokemon**' + '88 Muk' + '89 **Bad Pokemon**' + '8A Kingler' + '8B Cloyster' + '8C **Bad Pokemon**' + '8D Electrode' + '8E Clefable' + '8F Weezing' + '90 Persian' + '91 Marowak' + '92 **Bad Pokemon**' + '93 Haunter' + '94 Abra' + '95 Alakazzam' + '96 Pidgeotto' + '97 Pidgeot' + '98 Starmie' + '99 Bulbasaur' + '9A Venusaur' + '9B Tentacruel' + '9C **Bad Pokemon**' + '9D Goldeen' + '9E Seaking' + '9F **Bad Pokemon**' + 'A0 **Bad Pokemon**' + 'A1 **Bad Pokemon**' + 'A2 **Bad Pokemon**' + 'A3 Ponyta' + 'A4 Rapidash' + 'A5 Rattata' + 'A6 Ratticate' + 'A7 Nidorino' + 'A8 Nidorina' + 'A9 Geodude' + 'AA Porygon' + 'AB Areodactyl' + 'AC **Bad Pokemon**' + 'AD Magnemite' + 'AE **Bad Pokemon**' + 'AF **Bad Pokemon**' + 'B0 Charmander' + 'B1 Squirtle' + 'B2 Charmeleon' + 'B3 Wartortle' + 'B4 Charizard' + 'B5 **Bad Pokemon**' + 'B6 **Bad Pokemon**' + 'B7 **Bad Pokemon**' + 'B8 **Bad Pokemon**' + 'B9 Oddish' + 'BA Gloom' + 'BB Vileplume' + 'BC Bellsprout' + 'BD Weepinbell' + 'BE Victreebell') + end + end + object LandLevelGroup: TGroupBox + Left = 200 + Top = 80 + Width = 169 + Height = 49 + Caption = 'Level' + TabOrder = 3 + object LandPkmnLevel: TSpinEdit + Left = 8 + Top = 19 + Width = 153 + Height = 22 + Hint = 'Pok'#233'mon'#39's level' + Enabled = False + MaxValue = 255 + MinValue = 1 + TabOrder = 0 + Value = 1 + end + end + object LandReplaceBtn: TButton + Left = 200 + Top = 136 + Width = 75 + Height = 25 + Caption = 'Replace' + Enabled = False + TabOrder = 4 + OnClick = LandReplaceBtnClick + end + object LandRateGroup: TGroupBox + Left = 16 + Top = 168 + Width = 169 + Height = 65 + Caption = 'Encounter Rate' + TabOrder = 5 + object Less1: TLabel + Left = 8 + Top = 48 + Width = 21 + Height = 13 + Caption = 'Less' + end + object More1: TLabel + Left = 136 + Top = 48 + Width = 24 + Height = 13 + Caption = 'More' + end + object LandPercent: TLabel + Left = 57 + Top = 48 + Width = 56 + Height = 13 + Alignment = taCenter + AutoSize = False + Caption = '%' + end + object LandRateTrack: TTrackBar + Left = 8 + Top = 16 + Width = 153 + Height = 33 + Enabled = False + Max = 100 + Min = 1 + Frequency = 10 + Position = 1 + TabOrder = 0 + OnExit = LandRateTrackExit + end + end + end + object WaterGroup1: TGroupBox + Left = 8 + Top = 304 + Width = 385 + Height = 249 + Caption = 'Water Pok'#233'mon' + TabOrder = 1 + object OffsetLabel2: TLabel + Left = 200 + Top = 176 + Width = 35 + Height = 13 + Caption = 'Offset:' + end + object WaterOffset1: TLabel + Left = 240 + Top = 176 + Width = 18 + Height = 13 + Caption = '$00' + end + object WaterPkmnBox: TListBox + Left = 16 + Top = 24 + Width = 105 + Height = 137 + Hint = 'Wild Pok'#233'mon on land' + Style = lbOwnerDrawFixed + Enabled = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clBlack + Font.Height = -11 + Font.Name = 'MS Sans Serif' + Font.Style = [] + ItemHeight = 13 + Items.Strings = ( + '' + '' + '' + '' + '' + '' + '' + '' + '' + '') + ParentFont = False + TabOrder = 0 + OnClick = WaterPkmnBoxClick + end + object WaterLevelBox: TListBox + Left = 128 + Top = 24 + Width = 41 + Height = 137 + Enabled = False + ItemHeight = 13 + TabOrder = 1 + end + object WaterPkmnGroup: TGroupBox + Left = 200 + Top = 24 + Width = 169 + Height = 49 + Caption = 'Pokemon' + TabOrder = 2 + object WaterPkmnCombo: TComboBox + Left = 8 + Top = 20 + Width = 153 + Height = 21 + Style = csDropDownList + Enabled = False + ItemHeight = 13 + TabOrder = 0 + Items.Strings = ( + '00 Missingno' + '01 Rydon' + '02 Kangaskahn' + '03 Nidoran M' + '04 Clefairy' + '05 Spearow' + '06 Voltorb' + '07 Nidoking' + '08 Slowbro' + '09 Ivysaur' + '0A Eggecutor' + '0B Licktung' + '0C Exegute' + '0D Grimer' + '0E Gengar' + '0F Nidoran F' + '10 Nidoqueen' + '11 Cubone' + '12 Ryhorn' + '13 Lapras' + '14 Arcanine' + '15 Mew' + '16 Gyrados' + '17 Shellder' + '18 Tentacool' + '19 Gastly' + '1A Scyther' + '1B Staryu' + '1C Blastoice' + '1D Pinser' + '1E Tangala' + '1F **Bad Pokemon**' + '20 **Bad Pokemon**' + '21 Growlithe' + '22 Onix' + '23 Fearow' + '24 Pidgey' + '25 Slowpoke' + '26 Kadabra' + '27 Graveler' + '28 Chansey' + '29 Machoke' + '2A Mr. Mime' + '2B Hitmonlee' + '2C Hitmonchan' + '2D Arbok' + '2E Parasect' + '2F Psyduck' + '30 Drowzee' + '31 Golom' + '32 **Bad Pokemon**' + '33 Magmar' + '34 **Bad Pokemon**' + '35 Electabuzz' + '36 Magneton' + '37 Koffing' + '38 **Bad Pokemon**' + '39 Mankey' + '3A Seel' + '3B Digglett' + '3C Tarous' + '3D **Bad Pokemon**' + '3E **Bad Pokemon**' + '3F **Bad Pokemon**' + '40 FarFetche'#39'd' + '41 Venonat' + '42 Dragonite' + '43 **Bad Pokemon**' + '44 **Bad Pokemon**' + '45 **Bad Pokemon**' + '46 Doduo' + '47 Poliwag' + '48 Jynx' + '49 Moltres' + '4A Articuno' + '4B Zapdos' + '4C Ditto' + '4D Meowth' + '4E Krabby' + '4F **Bad Pokemon**' + '50 **Bad Pokemon**' + '51 **Bad Pokemon**' + '52 Vulpix' + '53 Ninetails' + '54 Pikachu' + '55 Raichu' + '56 **Bad Pokemon**' + '57 **Bad Pokemon**' + '58 Dratini' + '59 Dragonair' + '5A Kabuto' + '5B Kabutops' + '5C Horsea' + '5D Seadra' + '5E **Bad Pokemon**' + '5F **Bad Pokemon**' + '60 Sandshrew' + '61 Sandslash' + '62 Omanyte' + '63 Omaster' + '64 Jigglypuff' + '65 Wigglytuff' + '66 Eevee' + '67 Flareon' + '68 Jolteon' + '69 Vaporeon' + '6A Machop' + '6B Zubat' + '6C Ekans' + '6D Paras' + '6E Poliwhirl' + '6F Poliwrath' + '70 Weedle' + '71 Kakuna' + '72 Beedril' + '73 **Bad Pokemon**' + '74 Dodrio' + '75 Primeape' + '76 Dugtrio' + '77 Venomoth' + '78 Dewgong' + '79 **Bad Pokemon**' + '7A **Bad Pokemon**' + '7B Caterpie' + '7C Metapod' + '7D Butterfree' + '7E Machamp' + '7F **Bad Pokemon**' + '80 Golduck' + '81 Hypno' + '82 Golbat' + '83 Mewtwo' + '84 Snorlax' + '85 Magikarp' + '86 **Bad Pokemon**' + '87 **Bad Pokemon**' + '88 Muk' + '89 **Bad Pokemon**' + '8A Kingler' + '8B Cloyster' + '8C **Bad Pokemon**' + '8D Electrode' + '8E Clefable' + '8F Weezing' + '90 Persian' + '91 Marowak' + '92 **Bad Pokemon**' + '93 Haunter' + '94 Abra' + '95 Alakazzam' + '96 Pidgeotto' + '97 Pidgeot' + '98 Starmie' + '99 Bulbasaur' + '9A Venusaur' + '9B Tentacruel' + '9C **Bad Pokemon**' + '9D Goldeen' + '9E Seaking' + '9F **Bad Pokemon**' + 'A0 **Bad Pokemon**' + 'A1 **Bad Pokemon**' + 'A2 **Bad Pokemon**' + 'A3 Ponyta' + 'A4 Rapidash' + 'A5 Rattata' + 'A6 Ratticate' + 'A7 Nidorino' + 'A8 Nidorina' + 'A9 Geodude' + 'AA Porygon' + 'AB Areodactyl' + 'AC **Bad Pokemon**' + 'AD Magnemite' + 'AE **Bad Pokemon**' + 'AF **Bad Pokemon**' + 'B0 Charmander' + 'B1 Squirtle' + 'B2 Charmeleon' + 'B3 Wartortle' + 'B4 Charizard' + 'B5 **Bad Pokemon**' + 'B6 **Bad Pokemon**' + 'B7 **Bad Pokemon**' + 'B8 **Bad Pokemon**' + 'B9 Oddish' + 'BA Gloom' + 'BB Vileplume' + 'BC Bellsprout' + 'BD Weepinbell' + 'BE Victreebell') + end + end + object WaterLevelGroup: TGroupBox + Left = 200 + Top = 80 + Width = 169 + Height = 49 + Caption = 'Level' + TabOrder = 3 + object WaterPkmnLevel: TSpinEdit + Left = 8 + Top = 19 + Width = 153 + Height = 22 + Hint = 'Pok'#233'mon'#39's level' + Enabled = False + MaxValue = 255 + MinValue = 1 + TabOrder = 0 + Value = 1 + end + end + object WaterReplaceBtn: TButton + Left = 200 + Top = 136 + Width = 75 + Height = 25 + Caption = 'Replace' + Enabled = False + TabOrder = 4 + OnClick = WaterReplaceBtnClick + end + object WaterRateGroup: TGroupBox + Left = 16 + Top = 168 + Width = 169 + Height = 65 + Caption = 'Encounter Rate' + TabOrder = 5 + object Less2: TLabel + Left = 8 + Top = 48 + Width = 21 + Height = 13 + Caption = 'Less' + end + object More2: TLabel + Left = 136 + Top = 48 + Width = 24 + Height = 13 + Caption = 'More' + end + object WaterPercent: TLabel + Left = 57 + Top = 48 + Width = 56 + Height = 13 + Alignment = taCenter + AutoSize = False + Caption = '%' + end + object WaterRateTrack: TTrackBar + Left = 8 + Top = 16 + Width = 153 + Height = 33 + Enabled = False + Max = 100 + Min = 1 + Frequency = 10 + Position = 1 + TabOrder = 0 + OnExit = WaterRateTrackExit + end + end + end + end + object TabSheet4: TTabSheet + Caption = 'Headers' + ImageIndex = 3 + end + end + object StatusBar1: TStatusBar + Left = 0 + Top = 621 + Width = 639 + Height = 20 + Panels = < + item + Text = 'Ready.' + Width = 200 + end + item + Text = 'Start by opening a rom file from File->Open...' + Width = 50 + end> + end + object MapSelectPanel: TPanel + Left = 0 + Top = 0 + Width = 639 + Height = 33 + Align = alTop + BevelOuter = bvNone + TabOrder = 2 + Visible = False + object Label5: TLabel + Left = 8 + Top = 8 + Width = 56 + Height = 13 + Caption = 'Select Map:' + end + object MapSelectCombo: TComboBox + Left = 72 + Top = 4 + Width = 233 + Height = 21 + Style = csDropDownList + ItemHeight = 13 + TabOrder = 0 + OnChange = MapSelectComboChange + Items.Strings = ( + 'Pallet Town' + 'Viridian City' + 'Pewter City' + 'Cerulean City' + 'Lavender Town' + 'Vermilion City' + 'Celadon City' + 'Fuchsia City' + 'Cinnibar Island' + 'Indigo Plateau' + 'Saffron City' + '** Bad Map **' + 'Route 1' + 'Route 2' + 'Route 3' + 'Route 4' + 'Route 5' + 'Route 6' + 'Route 7' + 'Route 8' + 'Route 9' + 'Route 10' + 'Route 11' + 'Route 12' + 'Route 13' + 'Route 14' + 'Route 15' + 'Route 16' + 'Route 17' + 'Route 18' + 'Route 19' + 'Route 20' + 'Route 21' + 'Route 22' + 'Route 23' + 'Route 24' + 'Route 25' + 'Ash'#39's House F1' + 'Ash'#39's House F2' + 'Gary'#39's House' + 'Oak'#39's Lab' + 'Viridian Pok'#233'mon Center' + 'Viridian Mart' + 'Viridian School' + 'Viridian House' + 'Viridian Gym' + 'Digletts Cave (Route 2)' + 'Viridian Forest (Exit)' + 'Route 2 House' + 'Route 2 Gate' + 'Viridian Forest (Entrance)' + 'Viridian Forest' + 'Pewter City Museum F1' + 'Pewter City Museum F2' + 'Pewter City Gym' + 'Pewter City House' + 'Pewter City Mart' + 'Pewter City House' + 'Pewter City Pok'#233'mon Center' + 'Mt. Moon Cave (1)' + 'Mt. Moon Cave (2)' + 'Mt. Moon Cave (3)' + 'Cerulean House (Robbed)' + 'Cerulean House (2)' + 'Cerulean Pok'#233'mon Center' + 'Cerulean Gym' + 'Cerulean Bike Shop' + 'Cerulean Mart' + 'Mt. Moon Pok'#233'mon Center' + 'Cerulean House (Robbed) (Copy)' + 'Route 5 Gate' + 'Underground Tunnel Entrance (Route 5)' + 'Day Care Center' + 'Route 6 Gate' + 'Underground Tunnel Entrance (Route 6)' + 'Underground Tunnel Entrance (Route 6) (Copy)' + 'Route 7 Gate' + 'Underground Path Entrance (Route 7)' + 'Underground Path Entrance (Route 7) (Copy)' + 'Route 8 Gate' + 'Underground Path Entrance (Route 8)' + 'Rock Tunnel Pok'#233'mon Center' + 'Rock Tunnel (1)' + 'Power Plant' + 'Route 11 Gate' + 'Diglett'#39's Cave Entrance (Route 11)' + 'Route 11 Gate (Upstairs)' + 'Route 12 Gate' + 'Bill'#39's House' + 'Vermilion Pok'#233'mon Center' + 'Vermilion Pok'#233'mon Fan Club' + 'Vermilion Mart' + 'Vermilion Gym' + 'Vermilion House' + 'Vermilion Dock' + 'S.S. Anne (1)' + 'S.S. Anne (2)' + 'S.S. Anne (3)' + 'S.S. Anne (4)' + 'S.S. Anne (5)' + 'S.S. Anne (6)' + 'S.S. Anne (7)' + 'S.S. Anne (8)' + 'S.S. Anne (9)' + 'S.S. Anne (10)' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + 'Victory Road (1)' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + 'Elite Four Lance' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + 'Hall of Fame Room' + 'Underground Path (N/S)' + 'Elite Four Gary' + 'Underground Path (W/E)' + 'Celadon Mart (1)' + 'Celadon Mart (2)' + 'Celadon Mart (3)' + 'Celadon Mart (4)' + 'Celadon Mart (6)' + 'Celadon Mart Elevator' + 'Celadon Mansion (1)' + 'Celadon Mansion (2)' + 'Celadon Mansion (3)' + 'Celadon Mansion (4)' + 'Celadon Mansion (5)' + 'Celadon Pokecenter' + 'Celadon Gym' + 'Celadon Game Corner' + 'Celadon Mart (5)' + 'Celadon Prize Room' + 'Celadon Diner' + 'Celadon House (2)' + 'Celadon Hotel' + 'Lavender Pokecenter' + 'Pokemon Tower (1)' + 'Pokemon Tower (2)' + 'Pokemon Tower (3)' + 'Pokemon Tower (4)' + 'Pokemon Tower (5)' + 'Pokemon Tower (6)' + 'Pokemon Tower (7)' + 'Lavender House (1)' + 'Lavender Mart' + 'Lavender House (2)' + 'Fuchsia Mart' + 'Fuchsia House (1)' + 'Fuchsia Pokecenter' + 'Fuchsia House (2)' + 'Safari Zone Entrance' + 'Fuchsia Gym' + 'Fuchsia Meeting Room' + 'Seafoam Islands (2)' + 'Seafoam Islands (3)' + 'Seafoam Islands (4)' + 'Seafoam Islands (5)' + 'Vermilion House (2)' + 'Fuchsia House (3)' + 'Mansion (1)' + 'Cinnibar Gym' + 'Lab (1)' + 'Lab (2)' + 'Lab (3)' + 'Lab (4)' + 'Cinnibar Pokecenter' + 'Cinnibar Mart' + 'Cinnibar Mart (Copy)' + 'Indigo Plateau Lobby' + 'Copycat'#39's House F1 ' + 'Copycat'#39's House F2' + 'Fighting Dojo' + 'Saffron Gym' + 'Saffron House (1)' + 'Saffron Mart' + 'Silph Co (1)' + 'Saffron Pokecenter' + 'Saffron House (2)' + 'Route 15 Gate' + 'Route 15 Gate Upstairs' + 'Route 16 Gate Map' + 'Route 16 Gate Upstairs' + 'Route 16 House' + 'Route 12 House' + 'Route 18 Gate' + 'Route 18 Gate Upstairs' + 'Seafoam Islands (1)' + 'Route 22 Gate' + 'Victory Road' + 'Route 12 Gate Upstairs' + 'Vermilion House (3)' + 'Diglett'#39's Cave' + 'Victory Road (3)' + 'Rocket Hideout (1)' + 'Rocket Hideout (2)' + 'Rocket Hideout (3)' + 'Rocket Hideout (4)' + 'Rocket Hideout (Elevator)' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + 'Silph Co (2)' + 'Silph Co (3)' + 'Silph Co (4)' + 'Silph Co (5)' + 'Silph Co (6)' + 'Silph Co (7)' + 'Silph Co (8)' + 'Mansion (2)' + 'Mansion (3)' + 'Mansion (4)' + 'Safari Zone East' + 'Safari Zone North' + 'Safari Zone West' + 'Safari Zone Center' + 'Safari Zone Rest House (1)' + 'Safari Zone Secret House' + 'Safari Zone Rest House (2)' + 'Safari Zone Rest House (3)' + 'Safari Zone Rest House (4)' + 'Unknown Dungeon(2)' + 'Unknown Dungeon(3)' + 'Unknown Dungeon(1)' + 'Name Rater'#39's House' + 'Cerulean House (3)' + '** Bad Map **' + 'Rock Tunnel (2)' + 'Silph Co (9)' + 'Silph Co (10)' + 'Silph Co (11)' + 'Silph Co (Elevator)' + '** Bad Map **' + '** Bad Map **' + 'Battle Center' + 'Trade Center' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + 'Elite Four Loreli' + 'Elite Four Bruno' + 'Elite Four Agatha' + 'Surf House (Yellow)' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **' + '** Bad Map **') + end + end + object XPManifest1: TXPManifest + Left = 600 + Top = 584 + end + object MainMenu1: TMainMenu + Left = 568 + Top = 584 + object File1: TMenuItem + Caption = 'File' + object LoadRom1: TMenuItem + Caption = 'Open...' + Hint = 'Open a rom file to be edited.' + ShortCut = 16463 + OnClick = LoadRom1Click + end + object SaveRom1: TMenuItem + Caption = 'Save' + Enabled = False + Hint = 'Saves the currently opened rom to file.' + ShortCut = 16467 + OnClick = SaveRom1Click + end + object SaveRomAs1: TMenuItem + Caption = 'Save As...' + Enabled = False + Hint = 'Saves the currently opened rom to different file.' + end + object N1: TMenuItem + Caption = '-' + end + object LoadMap1: TMenuItem + Caption = 'Load Map...' + Hint = 'Loads map from file.' + end + object SaveMap1: TMenuItem + Caption = 'Save Map...' + Hint = 'Saves current map to file.' + end + object N2: TMenuItem + Caption = '-' + end + object Exit1: TMenuItem + Caption = 'Exit' + Hint = 'Bye-bye!' + OnClick = Exit1Click + end + end + object Edit1: TMenuItem + Caption = 'Edit' + object Undo1: TMenuItem + Caption = 'Undo' + ShortCut = 16474 + end + end + object Settings1: TMenuItem + Caption = 'Settings' + object Grid1: TMenuItem + Caption = 'Gridlines' + Hint = 'Show the gridlines in map editor, events and block palette.' + ShortCut = 16455 + OnClick = Grid1Click + end + object N4: TMenuItem + Caption = '-' + end + object Palette1: TMenuItem + Caption = 'Palette' + Hint = 'Change the color scheme GoldMap uses to display map.' + object Morning1: TMenuItem + Caption = 'Morning' + GroupIndex = 2 + RadioItem = True + end + object Day1: TMenuItem + Tag = 1 + Caption = 'Day' + Checked = True + GroupIndex = 2 + RadioItem = True + end + object Night1: TMenuItem + Tag = 2 + Caption = 'Night' + GroupIndex = 2 + RadioItem = True + end + object Darkness1: TMenuItem + Tag = 3 + Caption = 'Darkness' + GroupIndex = 2 + RadioItem = True + end + object Indoor1: TMenuItem + Tag = 4 + Caption = 'Indoor' + GroupIndex = 2 + RadioItem = True + end + end + end + object Tools: TMenuItem + Caption = 'Tools' + object BlockEditor1: TMenuItem + Caption = 'Block Editor...' + Enabled = False + Hint = 'Edit map building blocks.' + ShortCut = 16450 + OnClick = BlockEditor1Click + end + object ReconstructMap1: TMenuItem + Caption = 'Resize Map...' + Enabled = False + Hint = 'Change size of map, and relocate map data in rom.' + ShortCut = 16466 + end + object ReBuildEvents1: TMenuItem + Caption = 'Reconstruct Events...' + Enabled = False + Hint = 'Change number of events.' + ShortCut = 16453 + end + object N3: TMenuItem + Caption = '-' + end + object SaveMapPic1: TMenuItem + Caption = 'Save Picture of Map...' + Enabled = False + Hint = 'Save picture of map into file.' + ShortCut = 49229 + end + object SaveTilesetPic1: TMenuItem + Caption = 'Save Picture of Blocks...' + Enabled = False + Hint = 'Save picture of map building blocks into file.' + ShortCut = 49218 + end + object TryMap1: TMenuItem + Caption = 'Try Map...' + Enabled = False + Hint = + 'Allows you to manually specify map size and address to load it f' + + 'rom.' + ShortCut = 16468 + end + end + object Help1: TMenuItem + Caption = 'Help' + object About1: TMenuItem + Caption = 'About...' + Hint = 'About GoldMap.' + ShortCut = 112 + OnClick = About1Click + end + end + end + object SaveMapDialog: TSaveDialog + DefaultExt = 'map' + Filter = 'Maps (*.map)|*.map|All Files (*.*)|*.*' + Left = 536 + Top = 584 + end + object OpenRomDialog: TOpenDialog + Filter = 'GameBoy roms (*.gb),(*.gbc)|*.gb;*.gbc|Any file (*.*)|*.*' + Title = 'Select Pok'#233'mon Gold or Silver rom' + Left = 504 + Top = 552 + end + object SaveRomDialog: TSaveDialog + DefaultExt = 'gb' + Filter = 'GameBoy roms (*.GB),(*.GBC)|*.GB;*.GBC|All files (*.*)|*.*' + Title = 'Save rom' + Left = 536 + Top = 552 + end + object OpenMapDialog: TOpenDialog + DefaultExt = 'map' + Filter = 'Maps (*.map)|*.map|All Files (*.*)|*.*' + Left = 504 + Top = 584 + end + object ImageList1: TImageList + Left = 568 + Top = 552 + Bitmap = { + 494C010102000400040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 + 0000000000003600000028000000400000001000000001002000000000000010 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000007F7F7F007F7F + 7F007F7F7F007F7F7F007F7F7F007F7F7F007F7F7F007F7F7F007F7F7F007F7F + 7F007F7F7F007F7F7F007F7F7F007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000038383800383838003838 + 3800383838003838380038383800383838003838380038383800383838003838 + 38003838380038383800383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000007F7F7F007F7F7F007F7F7F007F7F7F007F7F7F007F7F7F007F7F + 7F007F7F7F000000000000000000000000000000000038383800D0E0F000D0E0 + F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0 + F000D0E0F000D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00007F7F7F000000000000000000000000000000000038383800D0E0F000F848 + 4800F8484800F8484800F8484800F8484800F8484800F8484800F8484800F848 + 4800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000078F8000078F8000078F8000078F8000078F8000078F8000000 + 00007F7F7F000000000000000000000000000000000038383800D0E0F000F848 + 4800F8807800F8807800F8807800F8807800F8807800F8807800F8807800F880 + 7800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000078F800003878000038780000387800003878000078F8000000 + 00007F7F7F000000000000000000000000000000000038383800D0E0F000F848 + 4800F8484800F8484800F8807800F8807800F8807800F8807800F8807800F880 + 7800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000078F800003878000078F8000078F800003878000078F8000000 + 00007F7F7F000000000000000000000000000000000038383800D0E0F000F848 + 4800F8484800F8484800F8484800F8807800F8807800F8807800F8807800F848 + 4800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000078F800003878000078F8000078F800003878000078F8000000 + 00007F7F7F000000000000000000000000000000000038383800D0E0F000F848 + 4800F8484800F8484800F8484800F8484800F8807800F8807800F8484800F848 + 4800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000078F800003878000038780000387800003878000078F8000000 + 00007F7F7F000000000000000000000000000000000038383800D0E0F000F848 + 4800F8807800F8807800F8484800F8484800F8484800F8484800F8484800F848 + 4800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000078F8000078F8000078F8000078F8000078F8000078F8000000 + 00007F7F7F000000000000000000000000000000000038383800D0E0F000F848 + 4800F8807800F8807800F8484800F8484800F8484800F8484800F8484800F848 + 4800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000038383800D0E0F000F848 + 4800F8484800F8484800F8484800F8484800F8484800F8484800F8484800F848 + 4800F8484800D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000038383800D0E0F000D0E0 + F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0F000D0E0 + F000D0E0F000D0E0F000383838007F7F7F000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000038383800383838003838 + 3800383838003838380038383800383838003838380038383800383838003838 + 3800383838003838380038383800000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000100000000100010000000000800000000000000000000000 + 000000000000000000000000FFFFFF000180FFFF000000000180C00000000000 + 3FFC800000000000380480000000000030048000000000003004800000000000 + 3004800000000000F007800000000000F0078000000000003004800000000000 + 3004800000000000300C8000000000003FFC8000000000003FFC800100000000 + 0180FFFF000000000180FFFF0000000000000000000000000000000000000000 + 000000000000} + end +end diff --git a/MapEditor.pas b/MapEditor.pas new file mode 100644 index 0000000..0e7cc65 --- /dev/null +++ b/MapEditor.pas @@ -0,0 +1,1151 @@ +unit MapEditor; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, ExtCtrls, Menus, XPMan, IniFiles, StdCtrls, Spin, ImgList, ComCtrls, + pngimage, Map, Tileset, About, Misc, BlockEditor; + +type + + TPointer = packed record + First: Byte; + Second: Byte; + end; + + TPokemon = packed record + Level: Byte; + Number: Byte; + end; + + TLandWildPkmn = packed record + Rate: Byte; + Pkmn: array [0..9] of TPokemon; + end; + + TWaterWildPkmn = packed record + Rate: Byte; + Pkmn: array [0..9] of TPokemon; + end; + + TMapEditorForm = class(TForm) + XPManifest1: TXPManifest; + MainMenu1: TMainMenu; + File1: TMenuItem; + LoadRom1: TMenuItem; + SaveRom1: TMenuItem; + SaveRomAs1: TMenuItem; + N1: TMenuItem; + LoadMap1: TMenuItem; + SaveMap1: TMenuItem; + N2: TMenuItem; + Exit1: TMenuItem; + Settings1: TMenuItem; + Grid1: TMenuItem; + N4: TMenuItem; + Palette1: TMenuItem; + Morning1: TMenuItem; + Day1: TMenuItem; + Night1: TMenuItem; + Darkness1: TMenuItem; + Indoor1: TMenuItem; + Tools: TMenuItem; + BlockEditor1: TMenuItem; + ReconstructMap1: TMenuItem; + ReBuildEvents1: TMenuItem; + N3: TMenuItem; + SaveMapPic1: TMenuItem; + SaveTilesetPic1: TMenuItem; + TryMap1: TMenuItem; + Help1: TMenuItem; + About1: TMenuItem; + SaveMapDialog: TSaveDialog; + OpenRomDialog: TOpenDialog; + SaveRomDialog: TSaveDialog; + OpenMapDialog: TOpenDialog; + PageControl1: TPageControl; + TabSheet1: TTabSheet; + MapScrollBox: TScrollBox; + MapBox: TPaintBox; + BlockPaletteScrollBox: TScrollBox; + BlockPalette: TPaintBox; + TabSheet2: TTabSheet; + NoEventsLabel: TLabel; + EventScrollBox: TScrollBox; + SignpostImage: TImage; + PeopleImage: TImage; + WarpImage: TImage; + EventBox: TPaintBox; + TriggerImage: TImage; + TabSheet3: TTabSheet; + NoWildPkmnLabel: TLabel; + LandGroup1: TGroupBox; + LandPkmnLevel: TSpinEdit; + LandPkmnBox: TListBox; + LandPkmnCombo: TComboBox; + StatusBar1: TStatusBar; + ImageList1: TImageList; + MapSelectPanel: TPanel; + MapSelectCombo: TComboBox; + Label5: TLabel; + shpHighlight: TShape; + TabSheet4: TTabSheet; + Edit1: TMenuItem; + Undo1: TMenuItem; + LandLevelBox: TListBox; + LandPkmnGroup: TGroupBox; + LandLevelGroup: TGroupBox; + LandReplaceBtn: TButton; + WaterGroup1: TGroupBox; + WaterPkmnBox: TListBox; + WaterLevelBox: TListBox; + WaterPkmnGroup: TGroupBox; + WaterPkmnCombo: TComboBox; + WaterLevelGroup: TGroupBox; + WaterPkmnLevel: TSpinEdit; + WaterReplaceBtn: TButton; + LandRateTrack: TTrackBar; + LandRateGroup: TGroupBox; + Less1: TLabel; + More1: TLabel; + LandPercent: TLabel; + WaterRateGroup: TGroupBox; + Less2: TLabel; + More2: TLabel; + WaterPercent: TLabel; + WaterRateTrack: TTrackBar; + OffsetLabel1: TLabel; + LandOffset1: TLabel; + OffsetLabel2: TLabel; + WaterOffset1: TLabel; + procedure BlockEditor1Click(Sender: TObject); + procedure Grid1Click(Sender: TObject); + procedure About1Click(Sender: TObject); + procedure BlockPaletteMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure BlockPaletteMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure MapBoxMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure MapBoxMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); + procedure MapBoxMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); + procedure MapSelectComboChange(Sender: TObject); + procedure MapBoxPaint(Sender: TObject); + procedure BlockPalettePaint(Sender: TObject); + procedure TilesetComboDrawItem(Control: TWinControl; Index: Integer; + Rect: TRect; State: TOwnerDrawState); + procedure SpinEdit1Change(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure LoadRom1Click(Sender: TObject); + + + //saves currently open map, event and pokemon data to rom (in memory) and writes to file + procedure SaveRom(FileName: string); + + //loads specified map, tileset for map, map's events and pokemon + procedure LoadMap(MapIndex: byte); + //loads specified tileset + procedure LoadTileset(TilesetNumber: Byte); + //loads wild pokemon data for specified map + procedure LoadPokemon(MapIndex: Byte); + + //saves currently loaded map, map's events and pokemon + procedure SaveMap; + //draws tileset blocks from MapData into Canvas + procedure DrawMap(Canvas: TCanvas); + //draws the tileset blocks on Canvas + procedure DrawBlocks(Canvas: TCanvas); + //refreshes the wild pokemon data controls in Wild Pokemon tab + procedure UpdatePokemon; + procedure SavePokemon; + + function IsOutsideOfMapBounds(X, Y: Integer): Boolean; + procedure Exit1Click(Sender: TObject); + procedure SaveRom1Click(Sender: TObject); + procedure LandReplaceBtnClick(Sender: TObject); + procedure WaterReplaceBtnClick(Sender: TObject); + procedure LandPkmnBoxClick(Sender: TObject); + procedure WaterPkmnBoxClick(Sender: TObject); + procedure WaterRateTrackExit(Sender: TObject); + procedure LandRateTrackExit(Sender: TObject); + + private + { Private declarations } + public + { Public declarations } + end; + +var + MapEditorForm: TMapEditorForm; + LoadedTileset: Byte = 0; + LoadedMap: string = ''; + LoadedMapBank: Byte; + LoadedMapNum: Byte; + SelBlock, SelPic, MapStart, TilesetStart, PokemonStart, Blocks: Integer; + LoadedMapHeader: TMapHeader; + Rom: TMemoryStream = nil; + MapData: array of Byte; + BlockPics: array [0..255] of TBitmap; + Painting,DraggingEvent: Boolean; + Tiles: TBitmap; + MapModified: boolean; + RomModified: boolean; + DragOldX,DragOldY: Integer; + TilesetCache: array [0..23] of TBitmap; + ConnectionData: array [$00..$03] of TConnectionData; + ConnectedMapHeaders: array [$00..$03] of TMapHeader; + TopMapData: array of Byte; + BottomMapData: array of Byte; + LeftMapData: array of Byte; + RightMapData: array of Byte; + Pointer: TPointer; + LandWildPkmn: TLandWildPkmn; + WaterWildPkmn: TWaterWildPkmn; + Location: string; + +implementation + +{$R *.dfm} + +procedure TMapEditorForm.FormCreate(Sender: TObject); +begin + ControlStyle := ControlStyle + [csOpaque]; + MapScrollBox.ControlStyle := MapScrollBox.ControlStyle + [csOpaque]; + MapBox.ControlStyle := MapBox.ControlStyle + [csOpaque]; + + // Create the tileset graphic + Tiles := TBitmap.Create; + Tiles.Width := 16*16; + Tiles.Height := 16*6; + Tiles.PixelFormat := pf24bit; + + // Import for drawing grid. + MapBox.Canvas.Brush.Style := bsClear; + EventBox.Canvas.Brush.Style := bsClear; + BlockPalette.Canvas.Brush.Style := bsClear; +end; + +procedure TMapEditorForm.Grid1Click(Sender: TObject); +begin + //if grid is checked then it will be hidden + if Grid1.Checked then + Grid1.Checked := False + else + //if grid is unchecked then it will be shown + Grid1.Checked := True; + //PokemonIni.WriteBool('Settings','Grid',Grid1.Checked); + //show the grid if needed + if MapStart > 0 then + begin + DrawMap(MapBox.Canvas); + //DrawEvents(MainForm.EventBox.Canvas); + DrawBlocks(BlockPalette.Canvas); + end; +end; + +procedure TMapEditorForm.LoadRom1Click(Sender: TObject); +var + I: Integer; +begin + if OpenRomDialog.Execute then + begin + // Check if memory stream is null. + if Rom = nil then + Rom := TMemoryStream.Create; + + // Load TMemoryStream from file. + Rom.LoadFromFile(OpenRomDialog.FileName); + + ReadMapPallets; + + // Load up tileset combos. + for I := 0 to 23 do + begin + TilesetCache[I] := TBitmap.Create; + TilesetCache[I].Width := 128; + TilesetCache[I].Height := 48; + TilesetCache[I].PixelFormat := pf24bit; + ReadTilesetGraphics(GetTilesetHeader(I), TilesetCache[I]); + end; + + MapModified := False; + RomModified := False; + BlockEditor1.Enabled := False; + ReBuildEvents1.Enabled := False; + ReconstructMap1.Enabled := False; + SaveRom1.Enabled := True; + SaveRomAs1.Enabled := True; + //ReadAreaNames; + //ScanMapHeaders; + ReadMapHeaderLocations; + MapSelectPanel.Show; + StatusBar1.Panels[1].Text := 'ROM Loaded...'; + //LoadMap(0); + MapSelectCombo.ItemIndex := 0; + MapSelectComboChange(Sender); + end; +end; + +procedure TMapEditorForm.SpinEdit1Change(Sender: TObject); +begin + //ReadTilesetGraphics(GetTilesetHeader(SpinEdit1.Value), Tiles); + //TilePalette.Picture.Graphic := Tiles; +end; + +procedure TMapEditorForm.TilesetComboDrawItem(Control: TWinControl; + Index: Integer; Rect: TRect; State: TOwnerDrawState); +begin + with TComboBox(Control).Canvas do + begin + FillRect(Rect); + TextOut(Rect.Left,Rect.Top,'Tileset ' + IntToStr(Index) + ':'); + Draw((Rect.Right - Rect.Left) div 2 - 64, Rect.Top + 13, TilesetCache[Index]); + end; +end; + +procedure TMapEditorForm.LoadTileset(TilesetNumber: Byte); +label LoadingDone; +var + X, Y, Block, TileX, TileY: Integer; + TileNumber: Byte; + Temp: TBitmap; + TilesetHdr: TTilesetHeader; +begin + //if the tileset needed is already loaded, just exit + //if LoadedTileset = TilesetNumber then Exit; + + TilesetHdr := GetTilesetHeader(TilesetNumber); + TilesetStart := GBPtrToFilePos(TilesetHdr.BankNumber,TilesetHdr.TilesetArrangementPointer); + + if (TilesetStart = 0) or (GBPtrToFilePos(TilesetHdr.BankNumber,TilesetHdr.TilesetGraphicsPointer) = 0) then + begin + MessageDlg('Tileset information in rom seem to be corrupted. Loading will be cancelled.',mtError,[mbOK],0); + Abort; + end; + + Temp := TBitmap.Create; + Temp.Width := 16*16; + Temp.Height := 16*6; + Temp.PixelFormat := pf24bit; + + //Temp.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Tileset' + IntToStr(TilesetNumber) + '.dib'); + ReadTilesetGraphics(GetTilesetHeader(TilesetNumber),Temp); + Tiles.Canvas.StretchDraw(Tiles.Canvas.ClipRect,Temp); + + //start loading + StatusBar1.Panels[0].Text := 'Loading Tileset ' + IntToStr(TilesetNumber) + ' please wait...'; + + //start reading the block data from rom & rendering the tiles + Rom.Position := TilesetStart; + Blocks := 255; + for Block := 0 to 255 do + begin + for Y := 0 to 3 do + for X := 0 to 3 do + begin + Rom.Read(TileNumber,1); + //create bitmap for block if not already existing + if BlockPics[Block] = nil then + begin + BlockPics[Block] := TBitmap.Create; + BlockPics[Block].Width := 32; + BlockPics[Block].Height := 32; + BlockPics[Block].PixelFormat := pf24bit; + end; + //calculate x and y coordinate where to copy tile from, the tileset picture has 16 tiles per line + TileY := TileNumber div 16; + TileX := TileNumber mod 16; + //draw tile to block picture + BlockPics[Block].Canvas.CopyRect(Rect(X*8,Y*8,X*8+8,Y*8+8),Tiles.Canvas,Rect(TileX*8,TileY*8,TileX*8+8,TileY*8+8)); + end; + end; + + BlockPalette.Height := 32 * Blocks; + BlockPaletteScrollBox.Show; + SelBlock := 1; + LoadedTileset := TilesetNumber; + + //updates blocks because tileset is changed + DrawBlocks(BlockPalette.Canvas); + + //enable editing blocks + BlockEditor1.Enabled := True; + StatusBar1.Panels[0].Text := 'Tileset ' + inttostr(TilesetNumber) + ' loaded.'; +end; + +procedure TMapEditorForm.About1Click(Sender: TObject); +begin + with TAboutDialog.Create(nil) do + begin + ShowModal; + Free; + end; +end; + +procedure TMapEditorForm.BlockEditor1Click(Sender: TObject); +begin + with TBlockEditorForm.Create(nil) do + begin + ShowModal; + Free; + end; +end; + +procedure TMapEditorForm.BlockPaletteMouseDown(Sender: TObject; + Button: TMouseButton; Shift: TShiftState; X, Y: Integer); +begin + SelBlock := (Y div 32); +end; + +procedure TMapEditorForm.BlockPaletteMouseMove(Sender: TObject; + Shift: TShiftState; X, Y: Integer); +begin + StatusBar1.Panels[0].Text := 'Block: $' + IntToHex(Y div 32 , 2) + ' Offset: $' + IntToHex(TilesetStart + ((Y div 32) * 16),0); +end; + +procedure TMapEditorForm.BlockPalettePaint(Sender: TObject); +begin + DrawBlocks(BlockPalette.Canvas); +end; + +procedure TMapEditorForm.DrawBlocks(Canvas: TCanvas); +var +I: Integer; +begin + Canvas.Brush.Style := bsClear; + //go through the block pictures and draw then on BlockPalette + for I := 0 to Blocks -1 do + begin + Canvas.Draw(0, I * 32, BlockPics[I]); + if Grid1.Checked then + Canvas.Rectangle(0, I * 32, 32 + 32, I * 32 + 32); + end; + //allow saving tileset picture + SaveTilesetPic1.Enabled := True; +end; + +procedure TMapEditorForm.DrawMap(Canvas: TCanvas); +var + X, Y: Integer; + MaxX, MaxY: Integer; + StartTileConnect, StartWriteConnect: Integer; + StartHeightWidthDifference: Integer; + StartX, StartY, EndX, EndY: Integer; + +begin + Canvas.Brush.Style := bsClear; + + MaxX := Canvas.ClipRect.Right div 32; + MaxY := Canvas.ClipRect.Bottom div 32; + + if MaxX >= LoadedMapHeader.Width then MaxX := LoadedMapHeader.Width-1; + if MaxY >= LoadedMapHeader.Height then MaxY := LoadedMapHeader.Height-1; + + for X := Canvas.ClipRect.Left div 32 to MaxX + 6 do + for Y := Canvas.ClipRect.Top div 32 to MaxY + 6 do + begin + if (X >= 3) and (Y >= 3) and (X <= MaxX + 3) and (Y <= MaxY + 3) then + begin + if (MapData[(Y-3) * LoadedMapHeader.Width + (X-3)] <= Blocks) then + Canvas.Draw(X * 32, Y * 32, BlockPics[MapData[(Y-3) * LoadedMapHeader.Width + (X-3)]]) + else + begin + // Invalid blocks detected + Canvas.Brush.Style := bsSolid; + Canvas.Rectangle(X * 32, Y * 32, X * 32 + 32, Y * 32 + 32); + Canvas.Brush.Style := bsClear; + end; + end + else + begin + Canvas.Draw(X * 32, Y * 32, BlockPics[LoadedMapHeader.BorderBlock]); + + // Top + if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[0].MapDataPointer - $4000) - (ConnectedMapHeaders[0].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[0].MapLocationRamPointer - $C6E8; + StartX := StartWriteConnect; + StartY := 0; + EndX := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart - 1) + StartWriteConnect; + EndY := StartY + 3; + + if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then + begin + StartHeightWidthDifference := ConnectedMapHeaders[0].Width - LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart; + Canvas.Draw(X * 32, Y * 32, BlockPics[TopMapData[StartTileConnect + (Y * StartHeightWidthDifference) + (Y * LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart + (X - StartWriteConnect))]]); + end; + end; + + // Bottom + if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[1].MapDataPointer - $4000) - (ConnectedMapHeaders[1].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[1].MapLocationRamPointer - $C6E8; + StartX := StartWriteConnect - ((LoadedMapHeader.Width + 6) * (LoadedMapHeader.Height + 3)); + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := StartX + (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart - 1); + EndY := StartY + 3; + + if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then + begin + StartHeightWidthDifference := ConnectedMapHeaders[1].Width - LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart; + Canvas.Draw(X * 32, Y * 32, BlockPics[BottomMapData[StartTileConnect + ((Y - StartY) * StartHeightWidthDifference) + ((Y - StartY) * LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart + (X - StartX))]]); + end; + end; + + // Left + if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[2].MapDataPointer - $4000) - (ConnectedMapHeaders[2].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[2].MapLocationRamPointer - $C6E8; + StartX := 0; + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := (StartX + 3) - 1; + EndY := StartY + LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart; + + if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then + begin + StartHeightWidthDifference := ConnectedMapHeaders[2].Width - LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart; + Canvas.Draw(X * 32, Y * 32, BlockPics[LeftMapData[StartTileConnect + ((Y - StartY) * StartHeightWidthDifference) + ((Y - StartY) * LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart + (X - StartX))]]); + end; + end; + + // Right + if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[3].MapDataPointer - $4000) - (ConnectedMapHeaders[3].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[3].MapLocationRamPointer - $C6E8; + + StartX := LoadedMapHeader.Width+3; + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := (StartX + 3) - 1; + EndY := StartY + LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart; + + if (X >= StartX) and (Y >= StartY) and (X <= EndX) and (Y < EndY) then + begin + StartHeightWidthDifference := ConnectedMapHeaders[3].Width - LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart; + Canvas.Draw(X * 32, Y * 32, BlockPics[RightMapData[StartTileConnect + ((Y - StartY) * StartHeightWidthDifference) + ((Y - StartY) * LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart + (X - StartX))]]); + end; + end; + + end; + if Grid1.Checked then + Canvas.Rectangle(X * 32, Y * 32, X * 32 + 32, Y * 32 + 32); + end; +end; + +procedure TMapEditorForm.LoadMap(MapIndex: byte); +var + TempMapHeader: TMapHeader; + TempMapStart: Integer; + TempMapIndex: Byte; +begin + + //first check if we need to save previously loaded map + if MapModified then + case MessageDlg('Save changes?',mtConfirmation,mbYesNoCancel,0) of + mrYes: SaveMap; + mrCancel: Abort; + end; + + LoadedMapHeader := GetMapHeader(MapIndex); + + if (LoadedMapHeader.Width * LoadedMapHeader.Height = 0) then + begin + MessageDlg('There seems be error in map header. Map will not be loaded.',mtWarning,[mbOK],0); + Abort; + end; + + DebugString('LoadMap', IntToStr(Map.BankLocations[MapIndex])); + + // load palettes + if (MapIndex >= 0) and (MapIndex <= 10) then + begin + Palette[0] := WordToColor(RawMapPalettes[MapIndex+1][0]); + Palette[1] := WordToColor(RawMapPalettes[MapIndex+1][1]); + Palette[2] := WordToColor(RawMapPalettes[MapIndex+1][2]); + Palette[3] := WordToColor(RawMapPalettes[MapIndex+1][3]); + end + else + begin + // default + Palette[0] := WordToColor(RawMapPalettes[0][0]); + Palette[1] := WordToColor(RawMapPalettes[0][1]); + Palette[2] := WordToColor(RawMapPalettes[0][2]); + Palette[3] := WordToColor(RawMapPalettes[0][3]); + end; + + // Load the tileset + LoadTileset(LoadedMapHeader.TilesetNumber); + + // Set the pointer to the map data + MapStart := GBPtrToFilePos(Map.BankLocations[MapIndex], LoadedMapHeader.DataPointer); + + // Make sure ROM is big enough + if Rom.Size - Rom.Position < LoadedMapHeader.Width * LoadedMapHeader.Height then + begin + MessageDlg('Map is too big to be read from file.', mtWarning, [mbOK], 0); + Abort; + end; + + // Resize the map, and read the map data. + SetLength(MapData, LoadedMapHeader.Width * LoadedMapHeader.Height); + //read map data to array + Rom.Position := MapStart; + Rom.Read(MapData[0], LoadedMapHeader.Width * LoadedMapHeader.Height); + + // Load Top connection data + if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then + begin + TempMapIndex := LoadedMapHeader.ConnectionData[0].MapNumber; + TempMapHeader := GetMapHeader(TempMapIndex); + TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex], + TempMapHeader.DataPointer); + ConnectedMapHeaders[0] := TempMapHeader; + SetLength(TopMapData, TempMapHeader.Width * TempMapHeader.Height); + Rom.Position := TempMapStart; + Rom.Read(TopMapData[0], TempMapHeader.Width * TempMapHeader.Height); + end; + + // Load Bottom connection data + if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then + begin + TempMapIndex := LoadedMapHeader.ConnectionData[1].MapNumber; + TempMapHeader := GetMapHeader(TempMapIndex); + TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex], + TempMapHeader.DataPointer); + ConnectedMapHeaders[1] := TempMapHeader; + SetLength(BottomMapData, TempMapHeader.Width * TempMapHeader.Height); + Rom.Position := TempMapStart; + Rom.Read(BottomMapData[0], TempMapHeader.Width * TempMapHeader.Height); + end; + + // Load Left connection data + if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then + begin + TempMapIndex := LoadedMapHeader.ConnectionData[2].MapNumber; + TempMapHeader := GetMapHeader(TempMapIndex); + TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex], + TempMapHeader.DataPointer); + ConnectedMapHeaders[2] := TempMapHeader; + SetLength(LeftMapData, TempMapHeader.Width * TempMapHeader.Height); + Rom.Position := TempMapStart; + Rom.Read(LeftMapData[0], TempMapHeader.Width * TempMapHeader.Height); + end; + + // Load Right connection data + if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then + begin + TempMapIndex := LoadedMapHeader.ConnectionData[3].MapNumber; + TempMapHeader := GetMapHeader(TempMapIndex); + TempMapStart := GBPtrToFilePos(Map.BankLocations[TempMapIndex], + TempMapHeader.DataPointer); + ConnectedMapHeaders[3] := TempMapHeader; + SetLength(RightMapData, TempMapHeader.Width * TempMapHeader.Height); + Rom.Position := TempMapStart; + Rom.Read(RightMapData[0], TempMapHeader.Width * TempMapHeader.Height); + end; + + //give MapBox right size + MapBox.Height := LoadedMapHeader.Height * 32 + (6 * 32); //Pad with 6 Blocks + MapBox.Width := LoadedMapHeader.Width * 32 + (6 * 32); //Pad with 6 Blocks + + //Show map + MapScrollBox.Hide; + MapScrollBox.Show; + MapScrollBox.ScrollInView(MapBox); + MapBox.Refresh; + + //TODO: Load events and pokemon + LoadedMapBank := Map.BankLocations[MapIndex]; + LoadedMapNum := MapIndex; + + MapModified := False; + SaveMapPic1.Enabled := True; + + LoadPokemon(MapIndex); + //hide event properties + //WarpForm.Hide; + //SignpostForm.Hide; + //PeopleForm.Hide; +end; + +procedure TMapEditorForm.LoadPokemon(MapIndex: Byte); +var + First: string; + Second: string; +begin + PokemonStart := 0; + LandWildPkmn.Rate := $00; + WaterWildPkmn.Rate := $00; + LandPkmnBox.Clear; + WaterPkmnBox.Clear; + + Rom.Position := $CEEB + (MapIndex * 2); + Rom.Read(Pointer,SizeOf(Pointer)); + + First := IntToStr(Pointer.Second + $80); + Second := IntToStr(Pointer.First); + Location := IntToHex(StrToInt(First),2) + IntToHex(StrToInt(Second),2); + Rom.Position := StrToInt('$' + Location); + Rom.Read(LandWildPkmn,SizeOf(TLandWildPkmn)); + LandOffset1.Caption := '$' + Location; + if (LandWildPkmn.Rate <> $00) then + begin + PokemonStart := StrToInt('$' + Location); + Rom.Position := StrToInt('$' + Location) + SizeOf(TLandWildPkmn); + Rom.Read(WaterWildPkmn,SizeOf(TWaterWildPkmn)); + WaterOffset1.Caption := '$' + IntToHex(StrToInt('$' + Location) + SizeOf(TLandWildPkmn),4); + end + else + begin + WaterOffset1.Caption := '$' + IntToHex(StrToInt('$' + Location) + $01,4); + Rom.Position := StrToInt('$' + Location) + $01; + Rom.Read(WaterWildPkmn,SizeOf(TWaterWildPkmn)); + if WaterWildPkmn.Rate <> $00 then + begin + PokemonStart := StrToInt('$' + Location) + $01; + end; + end; + + if (LandWildPkmn.Rate = $00) and (WaterWildPkmn.Rate = $00) then + begin + NoWildPkmnLabel.Show; + Exit; + end; + if LandWildPkmn.Rate <> $00 then + begin + LandPkmnBox.Enabled := True; + LandPkmnCombo.Enabled := True; + LandPkmnLevel.Enabled := True; + LandRateTrack.Enabled := True; + LandReplaceBtn.Enabled := True; + end + else + begin + LandPkmnBox.Enabled := False; + LandPkmnCombo.Enabled := False; + LandPkmnLevel.Enabled := False; + LandRateTrack.Enabled := False; + LandReplaceBtn.Enabled := False; + end; + if WaterWildPkmn.Rate <> $00 then + begin + WaterPkmnBox.Enabled := True; + WaterPkmnCombo.Enabled := True; + WaterPkmnLevel.Enabled := True; + WaterRateTrack.Enabled := True; + WaterReplaceBtn.Enabled := True; + end + else + begin + WaterPkmnBox.Enabled := False; + WaterPkmnCombo.Enabled := False; + WaterPkmnLevel.Enabled := False; + WaterRateTrack.Enabled := False; + WaterReplaceBtn.Enabled := False; + end; + NoWildPkmnLabel.Hide; + LandRateTrack.Position := LandWildPkmn.Rate; + LandPercent.Caption := IntToStr(LandWildPkmn.Rate) + '%'; + WaterRateTrack.Position := WaterWildPkmn.Rate; + WaterPercent.Caption := IntToStr(WaterWildPkmn.Rate) + '%'; + UpdatePokemon; +end; + +procedure TMapEditorForm.UpdatePokemon; +var + I: Integer; +begin + LandPkmnBox.Clear; + WaterPkmnBox.Clear; + LandLevelBox.Clear; + WaterLevelBox.Clear; + if LandWildPkmn.Rate <> $00 then + begin + for I := 0 to 9 do + begin + LandPkmnBox.AddItem(LandPkmnCombo.Items[LandWildPkmn.Pkmn[I].Number],LandPkmnBox); + LandLevelBox.AddItem(IntToStr(LandWildPkmn.Pkmn[I].Level),LandLevelBox); + end; + end; + if WaterWildPkmn.Rate <> $00 then + begin + for I := 0 to 9 do + begin + WaterPkmnBox.AddItem(WaterPkmnCombo.Items[WaterWildPkmn.Pkmn[I].Number],WaterPkmnBox); + WaterLevelBox.AddItem(IntToStr(WaterWildPkmn.Pkmn[I].Level),WaterLevelBox); + end; + end; +end; + +procedure TMapEditorForm.MapBoxMouseDown(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +var + StartTileConnect, StartWriteConnect: Integer; + StartX, StartY, EndX, EndY: Integer; + BlockX, BlockY: Integer; +begin + + BlockX := X div 32; + BlockY := Y div 32; + + if IsOutsideOfMapBounds(X, Y) = false then + begin + //change block if mouse button is left + if Button = mbLeft then + begin + MapModified := True; + MapData[SelPic] := SelBlock; + MapBox.Canvas.Draw((X div 32) * 32, (Y div 32) * 32, BlockPics[SelBlock]); + //if gid is sellected, add it + if Grid1.Checked then + MapBox.Canvas.Rectangle(X div 32 * 32, Y div 32 * 32, + X div 32 * 32 + 32, Y div 32 * 32 + 32); + //enable painting for OnMouseMove + Painting := True; + end + else + begin + //other buttons will select the block at cursor + if (MapData[SelPic] <= Blocks) then + begin + BlockPaletteScrollBox.VertScrollBar.Position := 32 * MapData[SelPic]; + SelBlock := MapData[SelPic]; + end; + end; + end + else + begin + // check if we are over a top connection + if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[0].MapDataPointer - $4000) - (ConnectedMapHeaders[0].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[0].MapLocationRamPointer - $C6E8; + StartX := StartWriteConnect; + StartY := 0; + EndX := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart - 1) + StartWriteConnect; + EndY := StartY + 3; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[0].MapNumber; + MapSelectComboChange(Sender); + end; + end; + + // check if we are over a bottom connection + if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[1].MapDataPointer - $4000) - (ConnectedMapHeaders[1].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[1].MapLocationRamPointer - $C6E8; + StartX := StartWriteConnect - ((LoadedMapHeader.Width + 6) * (LoadedMapHeader.Height + 3)); + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := StartX + (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart - 1); + EndY := StartY + 3; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[1].MapNumber; + MapSelectComboChange(Sender); + end; + end; + + // Left + if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[2].MapDataPointer - $4000) - (ConnectedMapHeaders[2].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[2].MapLocationRamPointer - $C6E8; + StartX := 0; + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := (StartX + 3) - 1; + EndY := StartY + LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[2].MapNumber; + MapSelectComboChange(Sender); + end; + end; + + // Right + if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[3].MapDataPointer - $4000) - (ConnectedMapHeaders[3].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[3].MapLocationRamPointer - $C6E8; + StartX := LoadedMapHeader.Width+3; + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := (StartX + 3) - 1; + EndY := StartY + LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + MapSelectCombo.ItemIndex := LoadedMapHeader.ConnectionData[3].MapNumber; + MapSelectComboChange(Sender); + end; + end; + end; +end; + +procedure TMapEditorForm.MapBoxMouseMove(Sender: TObject; Shift: TShiftState; X, + Y: Integer); +var + StartTileConnect, StartWriteConnect: Integer; + StartX, StartY, EndX, EndY: Integer; + BlockX, BlockY: Integer; +begin + + BlockX := X div 32; + BlockY := Y div 32; + + //Get block number where cursor is + SelPic := ((Y div 32)-3) * LoadedMapHeader.Width + ((X div 32)-3); + + //don't do anything with wrong coordinates + if (X < 0) or (Y < 0) or (SelPic >= (LoadedMapHeader.Width+3) * (LoadedMapHeader.Height+3)) then Exit; + + shpHighlight.Width := 32+1; + shpHighlight.Height := 32+1; + shpHighlight.Top := MapBox.Top + ((Y div 32) * 32); + shpHighlight.Left := MapBox.Left + (X div 32) * 32; + + if IsOutsideOfMapBounds(X, Y) = True then + begin + shpHighlight.Brush.Color := $80FF; + StatusBar1.Panels[0].Text := 'Border Tile (Read Only)'; + MapBox.Cursor := crDrag; + + // check if we are over a top connection + if (LoadedMapHeader.ConnectionDataControl and $08) = $08 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[0].MapDataPointer - $4000) - (ConnectedMapHeaders[0].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[0].MapLocationRamPointer - $C6E8; + StartX := StartWriteConnect; + StartY := 0; + EndX := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart - 1) + StartWriteConnect; + EndY := StartY + 3; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + shpHighlight.Left := (StartX*32)-MapBox.Canvas.ClipRect.Left; + shpHighlight.Top := (StartY*32)-MapBox.Canvas.ClipRect.Top; + shpHighlight.Width := (LoadedMapHeader.ConnectionData[0].WidthHeightVisiblePart*32)+1; + shpHighlight.Height := (3*32)+1; + StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[0].MapNumber); + MapBox.Cursor := crHandPoint; + end; + end; + + // check if we are over a bottom connection + if (LoadedMapHeader.ConnectionDataControl and $04) = $04 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[1].MapDataPointer - $4000) - (ConnectedMapHeaders[1].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[1].MapLocationRamPointer - $C6E8; + StartX := StartWriteConnect - ((LoadedMapHeader.Width + 6) * (LoadedMapHeader.Height + 3)); + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := StartX + (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart - 1); + EndY := StartY + 3; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + shpHighlight.Left := (StartX * 32) - MapBox.Canvas.ClipRect.Left; + shpHighlight.Top := (StartY * 32) - MapBox.Canvas.ClipRect.Top; + shpHighlight.Width := (LoadedMapHeader.ConnectionData[1].WidthHeightVisiblePart * 32)+1; + shpHighlight.Height := (3*32)+1; + StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[1].MapNumber); + MapBox.Cursor := crHandPoint; + end; + end; + + // Left + if (LoadedMapHeader.ConnectionDataControl and $02) = $02 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[2].MapDataPointer - $4000) - (ConnectedMapHeaders[2].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[2].MapLocationRamPointer - $C6E8; + StartX := 0; + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := (StartX + 3) - 1; + EndY := StartY + LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + shpHighlight.Left := (StartX * 32) - MapBox.Canvas.ClipRect.Left; + shpHighlight.Top := (StartY * 32) - MapBox.Canvas.ClipRect.Top; + shpHighlight.Width := (3*32)+1; + shpHighlight.Height := (LoadedMapHeader.ConnectionData[2].WidthHeightVisiblePart * 32)+1; + StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[2].MapNumber); + MapBox.Cursor := crHandPoint; + end; + end; + + // Right + if (LoadedMapHeader.ConnectionDataControl and $01) = $01 then + begin + StartTileConnect := (LoadedMapHeader.ConnectionData[3].MapDataPointer - $4000) - (ConnectedMapHeaders[3].DataPointer - $4000); + StartWriteConnect := LoadedMapHeader.ConnectionData[3].MapLocationRamPointer - $C6E8; + StartX := LoadedMapHeader.Width+3; + StartY := StartWriteConnect div (LoadedMapHeader.Width + 6); + EndX := (StartX + 3) - 1; + EndY := StartY + LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart; + if (BlockX >= StartX) and (BlockY >= StartY) and (BlockX <= EndX) and (BlockY < EndY) then + begin + shpHighlight.Left := (StartX * 32) - MapBox.Canvas.ClipRect.Left; + shpHighlight.Top := (StartY * 32) - MapBox.Canvas.ClipRect.Top; + shpHighlight.Width := (3*32)+1; + shpHighlight.Height := (LoadedMapHeader.ConnectionData[3].WidthHeightVisiblePart * 32)+1; + StatusBar1.Panels[0].Text := 'Connected Map #: ' + IntToStr(LoadedMapHeader.ConnectionData[3].MapNumber); + MapBox.Cursor := crHandPoint; + end; + end; + end + else + begin + StatusBar1.Panels[0].Text := 'X: ' + IntToStr((X div 32)-3) + + ' Y: ' + IntToStr((Y div 32)-3) + + ' Block: $' + IntToHex(MapData[SelPic], 2) + + ' Offset: $' + IntToHex(MapStart + SelPic, 2); + shpHighlight.Brush.Color := clLime; + MapBox.Cursor := crDrag; + end; + + //If mouse left button is pressed block is changed + if Painting then + begin + MapData[SelPic] := SelBlock; + MapBox.Canvas.Draw(X div 32 * 32,Y div 32 * 32,BlockPics[SelBlock]); + //if grid is selected, add it + if Grid1.Checked then + MapBox.Canvas.Rectangle(X div 32 * 32, Y div 32 * 32, + X div 32 * 32 + 32, Y div 32 * 32 + 32); + end; +end; + +procedure TMapEditorForm.MapBoxMouseUp(Sender: TObject; Button: TMouseButton; + Shift: TShiftState; X, Y: Integer); +begin + Painting := False; +end; + +procedure TMapEditorForm.MapBoxPaint(Sender: TObject); +begin + DrawMap(MapBox.Canvas); +end; + +procedure TMapEditorForm.MapSelectComboChange(Sender: TObject); +begin + LoadMap(MapSelectCombo.ItemIndex); + //Tab := PageControl1.ActivePageIndex; + //PageControl1.ActivePageIndex := Tab; + //MapBoxPaint(nil); + //MapBox.Invalidate; + //MapScrollBox.Refresh; +end; + +function TMapEditorForm.IsOutsideOfMapBounds(X, Y: Integer): Boolean; +begin + if ((Y div 32) - 3 < 0) or ((X div 32) - 3 < 0) + or ((X div 32) - 3 >= LoadedMapHeader.Width) or ((Y div 32) - 3 >= LoadedMapHeader.Height) then + Result := True + else + Result := False; +end; + +procedure TMapEditorForm.Exit1Click(Sender: TObject); +begin + Close; +end; + +procedure TMapEditorForm.SaveRom1Click(Sender: TObject); +begin + SaveRom(OpenRomDialog.FileName); +end; + +procedure TMapEditorForm.SaveRom(FileName: string); +begin + if MapStart > 0 then + SaveMap; + //if (EventsAddr>0) then + // SaveEvents; + if PokemonStart > 0 then + SavePokemon; + Rom.SaveToFile(FileName); + RomModified := False; +end; + +procedure TMapEditorForm.SaveMap; +begin + //write map data + Rom.Position := MapStart; + Rom.Write(MapData[0],LoadedMapHeader.Width * LoadedMapHeader.Height); + //save other stuff + //SaveEvents; + //SavePokemon; + MapModified := False; + RomModified := True; +end; + +procedure TMapEditorForm.SavePokemon; +begin + if PokemonStart = 0 then + Exit; + + if LandWildPkmn.Rate <> $00 then + begin + Rom.Position := PokemonStart; + Rom.Write(LandWildPkmn,SizeOf(TLandWildPkmn)); + end; + if WaterWildPkmn.Rate <> $00 then + begin + if LandWildPkmn.Rate = $00 then + begin + Rom.Position := PokemonStart; + Rom.Write(WaterWildPkmn,SizeOf(TWaterWildPkmn)); + end + else + begin + Rom.Position := PokemonStart + SizeOf(TLandWildPkmn); + Rom.Write(WaterWildPkmn,SizeOf(TWaterWildPkmn)); + end; + end; +end; + +procedure TMapEditorForm.LandReplaceBtnClick(Sender: TObject); +begin + LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Number := LandPkmnCombo.ItemIndex; + LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Level := LandPkmnLevel.Value; + UpdatePokemon; + MapModified := True; +end; + +procedure TMapEditorForm.WaterReplaceBtnClick(Sender: TObject); +begin + WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Number := WaterPkmnCombo.ItemIndex; + WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Level := WaterPkmnLevel.Value; + UpdatePokemon; + MapModified := True; +end; + +procedure TMapEditorForm.LandPkmnBoxClick(Sender: TObject); +begin + LandPkmnCombo.ItemIndex := LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Number; + LandPkmnLevel.Value := LandWildPkmn.Pkmn[LandPkmnBox.ItemIndex].Level; +end; + +procedure TMapEditorForm.WaterPkmnBoxClick(Sender: TObject); +begin + WaterPkmnCombo.ItemIndex := WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Number; + WaterPkmnLevel.Value := WaterWildPkmn.Pkmn[WaterPkmnBox.ItemIndex].Level; +end; + +procedure TMapEditorForm.LandRateTrackExit(Sender: TObject); +begin + LandWildPkmn.Rate := LandRateTrack.Position; + LandPercent.Caption := IntToStr(LandRateTrack.Position) + '%'; + MapModified := True; +end; + +procedure TMapEditorForm.WaterRateTrackExit(Sender: TObject); +begin + WaterWildPkmn.Rate := WaterRateTrack.Position; + WaterPercent.Caption := IntToStr(WaterRateTrack.Position) + '%'; + MapModified := True; +end; + +end. diff --git a/Misc.pas b/Misc.pas new file mode 100644 index 0000000..343ab34 --- /dev/null +++ b/Misc.pas @@ -0,0 +1,30 @@ +unit Misc; + +interface + +uses Windows, Sysutils; + +procedure DebugString(aCaption, aText: string); + +implementation + + // GetFormatDT - Output = formated DateTime String +function GetFormatDT(aDateTime: TDateTime): string; +begin + Result := FormatDateTime('dd.mm.yy hh:nn:ss zzz', aDateTime); +end; + +// GetFormatT - Output = formated Time String +function GetFormatT(aDateTime: TDateTime): string; +begin + Result := FormatDateTime('hh:nn:ss zzz', aDateTime) +end; + +procedure DebugString(aCaption, aText: string); +begin + OutputDebugString(PChar(Format('[%s][%s] %s', + [aCaption, GetFormatDT(Now()), + aText]))); +end; + +end. diff --git a/Pokémap.ico b/Pokémap.ico new file mode 100644 index 0000000000000000000000000000000000000000..6527f4e7af1e48892413ed6f26991df991dd5941 GIT binary patch literal 1080 zcmc&yF>b>!45WhsE(#R%59+DNFWMLME!i|iTeSI0{!Kc1vp3~P>WnmFQJ{>E)R8nL zpCZ!9L55)vvtuXnjyR6NzYii`$Q_Zh%m{Sy1TQkX4;S4`WDz`)a|C!SWu9k5D^!1^ zR$Br1S;`zuPa;6kQ@IDr=ylslnGEELQL2lY*B{ z;1i%u85+|5Tqh20dXes$l~OK9K63W?cY{zrkKokR>V8M9f&J8ZO= + + + + + + + + + + + RedMap.dpr + + + 7.0 + + + 8 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + True + True + WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; + + False + + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + True + False + False + False + True + True + True + True + True + True + + + + 0 + 0 + False + 1 + False + False + False + 16384 + 1048576 + 4194304 + + + + + + + + + vcl;rtl;vclx;dbrtl;vcldb;VclSmp;xmlrtl;vclie;inet;inetdbbde;inetdbxpress;PNGLib;madBasic_;madDisAsm_;madExcept_ + + + False + + + + + + False + + + True + False + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1033 + 1252 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + diff --git a/RedMap.dof b/RedMap.dof new file mode 100644 index 0000000..9fedde4 --- /dev/null +++ b/RedMap.dof @@ -0,0 +1,132 @@ +[FileVersion] +Version=7.0 +[Compiler] +A=8 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=0 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +NamespacePrefix= +SymbolDeprecated=1 +SymbolLibrary=1 +SymbolPlatform=1 +UnitLibrary=1 +UnitPlatform=1 +UnitDeprecated=1 +HResultCompat=1 +HidingMember=1 +HiddenVirtual=1 +Garbage=1 +BoundsError=1 +ZeroNilCompat=1 +StringConstTruncated=1 +ForLoopVarVarPar=1 +TypedConstVarPar=1 +AsgToTypedConst=1 +CaseLabelRange=1 +ForVariable=1 +ConstructingAbstract=1 +ComparisonFalse=1 +ComparisonTrue=1 +ComparingSignedUnsigned=1 +CombiningSignedUnsigned=1 +UnsupportedConstruct=1 +FileOpen=1 +FileOpenUnitSrc=1 +BadGlobalSymbol=1 +DuplicateConstructorDestructor=1 +InvalidDirective=1 +PackageNoLink=1 +PackageThreadVar=1 +ImplicitImport=1 +HPPEMITIgnored=1 +NoRetVal=1 +UseBeforeDef=1 +ForLoopVarUndef=1 +UnitNameMismatch=1 +NoCFGFileFound=1 +MessageDirective=1 +ImplicitVariants=1 +UnicodeToLocale=1 +LocaleToUnicode=1 +ImagebaseMultiple=1 +SuspiciousTypecast=1 +PrivatePropAccessor=1 +UnsafeType=0 +UnsafeCode=0 +UnsafeCast=0 +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages= +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +Launcher= +UseLauncher=0 +DebugCWD= +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1033 +CodePage=1252 +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= diff --git a/RedMap.dpr b/RedMap.dpr new file mode 100644 index 0000000..808e7bf --- /dev/null +++ b/RedMap.dpr @@ -0,0 +1,20 @@ +program RedMap; + +uses + Forms, + MapEditor in 'MapEditor.pas' {MapEditorForm}, + Tileset in 'Tileset.pas', + Map in 'Map.pas', + About in 'About.pas' {AboutDialog}, + Misc in 'Misc.pas', + BlockEditor in 'BlockEditor.pas' {BlockEditorForm}; + +{$R *.res} + +begin + Application.Initialize; + Application.Title := 'RedMap'; + Application.CreateForm(TMapEditorForm, MapEditorForm); + Application.CreateForm(TAboutDialog, AboutDialog); + Application.Run; +end. diff --git a/RedMap.res b/RedMap.res new file mode 100644 index 0000000000000000000000000000000000000000..a931a4b03e1c8be3aa294b35add92361fa1f0fd8 GIT binary patch literal 1220 zcmc&!u~Ne@3{?tufd%Ie$T4-~4}fE00Dh&L$9k)`{8Ij=jMzik*ogo+?D856mnuungMvJuR0va09nQ3ItW0pG5?xx>t2`c$?9kur*Jj;E z5Xfa8d#pVJ>|^pYtay*jF_q9mIOv%fXt=-YBet8=ev+PgnsYv2@scyo`U1lKngwUy zHSVMI4CZqVbBu#cwa$b4Ih{E8e&v`~Am^NzZ*^mAVZC0xAbE{P=Fi9@*7svv&mlBU zpXXa1mBvrme*PtAD(fea8$#>1%aRD?VSh-3@p+j-h4Hdap~Cq*h2l`o+G>^KJ||J` y-?2Qwz5fq9;Lt~)lskEs7kQHp;8i|hDeHHkuVI6i(%Gxff1^hF-kH8BeInn*XLP{; literal 0 HcmV?d00001 diff --git a/Tileset.pas b/Tileset.pas new file mode 100644 index 0000000..7a08980 --- /dev/null +++ b/Tileset.pas @@ -0,0 +1,93 @@ +unit Tileset; + +interface + +uses Map, Classes, Dialogs, SysUtils, Graphics; + +type + TTilesetHeader = packed record + BankNumber: Byte; + TilesetArrangementPointer: Word; + TilesetGraphicsPointer: Word; + UnknownData: array [0..6] of Byte; + end; + +var + //Palette: array [0..3] of TColor = (clWhite,clLtGray,clDkGray,clBlack); + //Palette: array [0..3] of TColor = ($F8E8F8, $A8E058, $A0D0F8, $181010); + Palette: array [0..3] of TColor = ($F8E8F8, $58E0A8, $F8D0A0, $101018); + RawMapPalettes: array [0..12, 0..3] of Word; + +const Zero: Byte = 0; + +function GetTilesetHeader(TilesetNumber: Byte): TTilesetHeader; +function WordToColor(Value: Word): TColor; +procedure ReadTilesetGraphics(TilesetHeader: TTilesetHeader; Bmp: TBitmap); +procedure ReadMapPallets; + +implementation + +uses MapEditor; + +function GetTilesetHeader(TilesetNumber: Byte): TTilesetHeader; +begin + Rom.Position := $C7BE + ((TilesetNumber) * SizeOf(TTilesetHeader)); + Rom.Read(Result, SizeOf(TTilesetHeader)); +end; + +function WordToColor(Value: Word): TColor; +var + R,G,B: Byte; +begin + R := Round((((Value shr 00) and 31) / 31) * 255); + G := Round((((Value shr 05) and 31) / 31) * 255); + B := Round((((Value shr 10) and 31) / 31) * 255); + Result := R or (G shl 8) or (B shl 16); +end; + +//reads tile from Stream into Bmp and uses colors from Pal +procedure ReadTile(Stream: TStream; Bmp: TBitmap); +var + X,Y: Integer; + Data1,Data2: Byte; +begin + for Y := 0 to 7 do + begin + Stream.Read(Data1,1); + Stream.Read(Data2,1); + for X := 0 to 7 do + Bmp.Canvas.Pixels[X,Y] := Palette[((Data1 shr (7-X)) and 1) or (((Data2 shr (7-X)) and 1) shl 1)]; + end; +end; + +//reads tileset at specific address into Bmp +procedure ReadTilesetGraphics(TilesetHeader: TTilesetHeader; Bmp: TBitmap); +var + Tile: TBitmap; + TileCnt: Byte; + I: Integer; + +begin + + Tile := TBitmap.Create; + Tile.PixelFormat := pf24bit; + Tile.Width := 8; + Tile.Height := 8; + Rom.Position := GBPtrToFilePos(TilesetHeader.BankNumber, TilesetHeader.TilesetGraphicsPointer); + TileCnt := 0; + for I := 1 to 16 * 6 do + begin + ReadTile(Rom,Tile); + Bmp.Canvas.Draw((TileCnt mod 16) * 8, (TileCnt div 16) * 8, Tile); + Inc(TileCnt); + end; +end; + +procedure ReadMapPallets; +begin + Rom.Position := $72660; + Rom.Read(RawMapPalettes, 8*12); + +end; + +end. diff --git a/event-object.png b/event-object.png new file mode 100644 index 0000000000000000000000000000000000000000..b88b08961921e14a82e0af2ddbcada48d193b160 GIT binary patch literal 1352 zcmV-O1-JT%P)WdLhsAT=Opb!c>HATls8HXt%GIyEsmF)|=4FfuSOl*-+W00007bV*G` z2i61y6Eq5sas;3N000SaNLh0L01FZT01FZU(%pXi00004XF*Lt006O%3;baP000D^ zNklA%AKtt_g{|xw*?Zx#!$-PxDuL zK9YOy_vd`y`M&Rb-#Lo!;-Rta9d76n&7?zmD@L(mf?*YQHi=`;4oRg5 z1fx-kW_;SwsTQDb8-LS%Z@QPd2!?kSMHG0oC&5UaW8f?baAq5R_K+I>yLevBU5{0ihwA zhhj=(-0K)3%2+&Lrd@HRm6TOWCwdAC)VM}V5|*2&n)p`ZIRY?Jn+&_T_G}edP(z}X z$rs%SGxq@7)5Hih59^Wj<-!N#ux1zJB*9veO*Vwdka!p4Q+Uwxg-R}|^5kTa3(AGE z2B-#zJ4jY8@~K855?&jt)AQr=7=C{k=auugvR`;)j)CTvM)5ucTrr-0i!I z8_Esb-fVcXL<>2PTux$J`!e;lXo zB%{UKg0so9I52nsQ(sR}o>TfM9-irQ)7ag=8^`tIIC%3Q9)0$R@;vE(0_R6g9M%tG z-{d|%pXVnJn!ai(grLylt(mObb?$mH+#kECBKJu*CeKZBw=$mS?@@$*3qu?PzcRjp z_M7c%LckK1_JS>qTM(a%p?%WJtfi5nPj3uFI8vH&#ntPkqtfsNI z5sOzBp}ta)No4T!i>H+C@H!Ckg)BP=n-r)C)jSWpwYLH8&6_YbFoxMbeucyBK=)ub zJSRLVdBMv$0Ez~yzJ=a(Lf0p!_vwG;l&{g@k=qqtq)?xJ}2kQ>iFd4{FICDixU zW9R5jxV~>f;=2UW;VhJIE_RM>?Qp`jrva%}2c9=x<}D5)KQXNt`@NBYdMn12Zl=hpik}N$yROO zV10)bBHoN_B~C82Hl}L%bc4^Xb6eI|iJUL8EI$!JxHu3Hw@ayhFUGqVPqBOu`3O}p zLtst9%EG0Sjh*=_d9M!UnSh4?>loi^cof56yLc3NnO5_chBW;K{S_=#Xp$BZ2L?^V zZ?GJ{tfwnEyBKwYp_O|elE16P0x8Q4PrfCx&1&8w%x5uPU3gdMJ+UCcl=F*8Ap9SK z50e}z--z`hAR1ZfW?gJP5$Lh}aUg@gf-iZ8k{OD9*TP$h#>W4{u0qE7{$(`)0000< KMNUMnLSTYjoPA^f literal 0 HcmV?d00001