import com.ms.wfc.io.*; import com.ms.wfc.core.*; import com.ms.wfc.app.*; import com.ms.wfc.ui.*; import com.ms.wfc.util.*; import java.util.Vector; import com.ms.lang.*; import com.ms.*; public class BTDEdit extends Form { String btdFileName = ""; int dragging = -1; static final int MULTI = 24; ScreenArea screenA; Vector VLS = new Vector(); int mapIndex; String mapName; File bio; boolean lastLeft = false; String usBriefing,geBriefing; Time lastClick; Point mouseDownAt = new Point(-1,-1); Point startDrag = new Point(-1,-1); public static void main (String[] args) throws Exception { BTDEdit mainW = new BTDEdit(); mainW.setVisible(true); mainW.setWindowState(FormWindowState.MAXIMIZED); try {Application.run(mainW);} catch (Exception e) { //System.out.println(e); } } public BTDEdit() { formInit(); this.setWindowState(FormWindowState.MAXIMIZED); } public void formInit() { MenuItem FileMenuOpen = new MenuItem("Open image..."); FileMenuOpen.addOnClick(new EventHandler(this.FileMenuOpenBgm_click)); MenuItem FileMenuOpenData = new MenuItem("Open BTD..."); FileMenuOpenData.addOnClick(new EventHandler(this.FileMenuOpenBtd_click)); MenuItem FileMenuSaveData = new MenuItem("Save BTD..."); FileMenuSaveData.addOnClick(new EventHandler(this.FileMenuSaveBtd_click)); MenuItem FileMenuExit = new MenuItem("Exit"); FileMenuExit.addOnClick(new EventHandler(this.exitApp)); MenuItem EditMenuEditData = new MenuItem("Edit map data..."); EditMenuEditData.addOnClick(new EventHandler(this.EditMenuEditData_click)); MenuItem FileMenu = new MenuItem("File",null,new MenuItem[]{FileMenuOpen,FileMenuOpenData,FileMenuSaveData,FileMenuExit}); MenuItem EditMenu = new MenuItem("Edit",null,new MenuItem[]{EditMenuEditData}); MainMenu myMenu = new MainMenu(new MenuItem[]{FileMenu,EditMenu}); this.setMenu(myMenu); } public void exitApp(Object sender, Event e) { this.close(); } public void EditMenuEditData_click(Object sender, Event e) { MapDataDialog mD = new MapDataDialog(mapIndex,geBriefing,usBriefing); mD.showDialog(this); } public void FileMenuOpenBgm_click(Object sender, Event e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.setInitialDir(""); ofd.setDefaultExt("bgm"); ofd.setFilter("BGM files (*.bgm)|*.bgm"); ofd.setFilterIndex(1); String inFileName; ofd.setTitle("Load BGM file.."); int dlgResult = ofd.showDialog(); if (dlgResult == DialogResult.OK) { inFileName = ofd.getFileName(); Bitmap theMap = loadBgm(inFileName); if ( screenA != null ) { this.remove(screenA); screenA.dispose(); } VLS = new Vector(); screenA = new ScreenArea(theMap); this.add(screenA); this.setAutoScroll(true); screenA.addOnMouseUp(new MouseEventHandler(mouseUp)); screenA.addOnMouseDown(new MouseEventHandler(mouseDown)); screenA.addOnDoubleClick(new EventHandler(doubleClick)); screenA.addOnMouseMove(new MouseEventHandler(mouseMove)); screenA.repaint(); this.getForm().setText(inFileName); } else return; } public void FileMenuSaveBtd_click(Object sender, Event e) { SaveFileDialog ofd = new SaveFileDialog(); ofd.setDefaultExt("btd"); ofd.setFilter("Btd files (*.btd)|*.btd"); ofd.setFilterIndex(1); String inFileName; ofd.setTitle("Save BTD file"); int dlgResult = ofd.showDialog(); if (dlgResult == DialogResult.OK) { inFileName = ofd.getFileName(); saveBTD(inFileName); } else return; } public void FileMenuOpenBtd_click(Object sender, Event e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.setInitialDir(""); ofd.setDefaultExt("btd"); ofd.setFilter("BTD files (*.btd)|*.btd"); ofd.setFilterIndex(1); String inFileName; ofd.setTitle("Load BTD file.."); int dlgResult = ofd.showDialog(); if (dlgResult == DialogResult.OK) { inFileName = ofd.getFileName(); loadBTD(inFileName); btdFileName = inFileName; } else return; } public void doubleClick(Object sender, Event e) { if ( lastLeft == false ) return; Point aPoint = mouseDownAt; mouseDownAt = new Point(-1,-1); int index; if ( ( index = isVL(aPoint) ) == -1 && VLS.size() < 17 ) { VL aVL = new VL(new Point(aPoint.x/screenA.drawnMegaSizes.x,aPoint.y/screenA.drawnMegaSizes.y),50,"None",0xCC); VLS.addElement(aVL); screenA.repaint(); } } public void mouseMove(Object sender, MouseEvent e) { if ( (e.button != MouseButton.LEFT ) ) return; Point aPoint = new Point(e.x/screenA.drawnMegaSizes.x,e.y/screenA.drawnMegaSizes.y); if ( dragging != -1 && (e.button == MouseButton.LEFT ) ) { VL aVL = (VL)(VLS.elementAt(dragging)); if ( isVL(new Point(e.x,e.y)) == -1 ) aVL.location = aPoint; screenA.repaint(); } } public void mouseDown(Object sender, MouseEvent e) { if ( (e.button != MouseButton.LEFT ) ) { lastLeft = false; return; } else { lastLeft = true; } System.out.println("*"); mouseDownAt = new Point(e.x,e.y); int index; if ( ( index = isVL(mouseDownAt) ) != -1 ) { dragging = index; startDrag = new Point(e.x/screenA.drawnMegaSizes.x,e.y/screenA.drawnMegaSizes.y); } } public void mouseUp(Object sender, MouseEvent e) { if ( (e.button != MouseButton.LEFT ) ) { lastLeft = false; return; } else { lastLeft = true; } Point aPoint = new Point(e.x,e.y); Point endDrag = new Point(e.x/screenA.drawnMegaSizes.x,e.y/screenA.drawnMegaSizes.y); dragging = -1; if ( endDrag.equals(startDrag) == false ) return; int index=isVL(aPoint); if ( index != -1 ) { VLDialog newD = new VLDialog((VL)(VLS.elementAt(index))); newD.showDialog(this); } } public Bitmap loadBgm(String fileName) { Bitmap toReturn; File tgaFile = File.openRead(fileName); tgaFile.setPosition(8); int width = tgaFile.readInt(); int height = tgaFile.readInt(); tgaFile.setPosition(16); short[] data = new short[width*height]; tgaFile.readShorts(data,0,data.length); //int i=0; MemoryStream bmp = new MemoryStream(); bmp.write(0x42); bmp.write(0x4d); int dataSize = width*height*2; bmp.writeInt(0x36+dataSize); while ( dataSize % 4 != 0 ) dataSize++; bmp.writeInt(0); bmp.writeInt(0x36); bmp.writeInt(0x28); bmp.writeInt(width); bmp.writeInt(height); bmp.writeShort((short)1); bmp.writeShort((short)16); bmp.writeInt(0); bmp.writeInt(dataSize); bmp.writeInt(0);bmp.writeInt(0); bmp.writeInt(0);bmp.writeInt(0); short[] data2 = new short[width*height]; int runner = 0; for ( int i = (height-1) ; i > -1 ; i -- ) { for ( int j = 0 ; j < width ; j++ ) { data2[runner] = data[i*width+j]; runner++; } } bmp.writeShorts(data2); bmp.setPosition(0); toReturn = new Bitmap(bmp); tgaFile.close(); bmp.close(); return(toReturn); } public int isVL(Point screenPoint) { for ( int i = 0 ; i < VLS.size() ; i++ ) { VL aVL = (VL)(VLS.elementAt(i)); Point aPoint = new Point(screenPoint.x/screenA.drawnMegaSizes.x,screenPoint.y/screenA.drawnMegaSizes.y); if ( aPoint.equals(aVL.location) ) { return(i); } } return(-1); } public void saveBTD(String fileName) { bio = File.create(fileName); bio.setLength(8718); byte[] clear = new byte[8718]; bio.writeBytes(clear); bio.setPosition(0); bio.writeInt(19990326); bio.write(mapIndex); for ( int i = 0 ; i < VLS.size() ; i++ ) { bio.setPosition(5+i*32); VL aVL = (VL)(VLS.elementAt(i)); bio.write(aVL.location.x); bio.write(aVL.location.y); bio.write(0);bio.write(0); bio.write(aVL.type); bio.write(0);bio.write(0);bio.write(0); bio.writeStringCharsAnsi(aVL.name.trim()); bio.setPosition(5+i*32+29); bio.write(aVL.exitsTo); } bio.setPosition(517); bio.writeStringCharsAnsi(mapName); bio.setPosition(526); bio.writeStringCharsAnsi(usBriefing); bio.setPosition(4622); bio.writeStringCharsAnsi(geBriefing); bio.close(); } public void loadBTD(String fileName) { VLS = new Vector(); bio = File.openRead(fileName); bio.setPosition(4); mapIndex = bio.read(); bio.setPosition(5); for ( int i = 0 ; i < 16 ; i++ ) { byte[] chunk = bio.readBytes(32); VL aVL = new VL(chunk); if ( aVL.type != 0 ) { VLS.addElement(aVL); } } bio.setPosition(517); mapName = bio.readStringCharsAnsi(8); bio.setPosition(526); usBriefing = bio.readStringCharsAnsi(4096); bio.setPosition(4622); geBriefing = bio.readStringCharsAnsi(4096); bio.close(); screenA.repaint(); } private class MapDataDialog extends Form { public Button okB,cancelB; public Edit usEdit,geEdit,nameEdit; public ComboBox indexCombo; public Point thisSize = new Point(400,400); public void clicked(Object sender, Event e) { //System.out.println(((Button)sender).getText()); String commandText = ((Button)sender).getText(); if ( commandText.equals(okB.getText()) ) { geBriefing = geEdit.getText(); usBriefing = usEdit.getText(); mapIndex = indexCombo.getSelectedIndex(); mapName = nameEdit.getText(); this.close(); } if ( commandText.equals(cancelB.getText()) ) { this.close(); } } public MapDataDialog (int mapIndex,String geBriefing,String usBriefing) { okB = new Button(); okB.setText("OK"); okB.setLocation(200,340); okB.addOnClick(new EventHandler(this.clicked)); cancelB = new Button(); cancelB.setText("Cancel"); cancelB.setLocation(300,340); cancelB.addOnClick(new EventHandler(this.clicked)); this.setSize(thisSize); this.add(okB); this.add(cancelB); GroupBox usBox,geBox,indexBox; usBox = new GroupBox(); usBox.setSize(380,120); usBox.setLocation(10,80); usBox.setText("US Briefing"); geBox = new GroupBox(); geBox.setSize(380,120); geBox.setLocation(10,200); geBox.setText("German Briefing"); indexBox = new GroupBox(); indexBox.setSize(380,50); indexBox.setLocation(10,10); indexBox.setText("Map index"); usEdit = new Edit(); usEdit.setMultiline(true); usEdit.setScrollBars(ScrollBars.VERTICAL); usEdit.setSize(360,80); usEdit.setLocation(10,20); usEdit.setAcceptsReturn(false); usEdit.setMaxLength(4096); usEdit.setText(usBriefing); geEdit = new Edit(); geEdit.setMultiline(true); geEdit.setScrollBars(ScrollBars.VERTICAL); geEdit.setSize(360,80); geEdit.setLocation(10,20); geEdit.setAcceptsReturn(false); geEdit.setMaxLength(4096); geEdit.setText(geBriefing); nameEdit = new Edit(); nameEdit.setMultiline(false); nameEdit.setSize(100,20); nameEdit.setLocation(100,20); nameEdit.setAcceptsReturn(false); nameEdit.setMaxLength(8); nameEdit.setText(mapName); indexCombo = new ComboBox(); for ( int i = 0 ; i < 44 ; i ++ ) { indexCombo.addItem(Integer.toString(i)); } indexCombo.setSize(50,20); indexCombo.setLocation(10,20); indexCombo.setSelectedIndex(mapIndex); usBox.add(usEdit); geBox.add(geEdit); indexBox.add(indexCombo); indexBox.add(nameEdit); this.add(usBox); this.add(geBox); this.add(indexBox); this.setShowInTaskbar(false); this.setStartPosition(FormStartPosition.CENTER_SCREEN); } public Point getMaxTrackSize() { return(thisSize); } public Point getMinTrackSize() { return(thisSize); } } private class VLDialog extends Form { public Button OKB,cancelB,deleteB; public RadioButton typeOne,typeTwo,typeThree; public RadioButton typeNone,typeExitOne,typeExitTwo; public GroupBox typeButtonBox,otherBox; public Edit VLName; public ComboBox mapList; int index; Point thisSize = new Point(300,260); public VLDialog(VL aVL) { this.setSize(thisSize); EventHandler handle = new EventHandler(aStateChange); index = VLS.indexOf(aVL); typeOne = new RadioButton(); typeOne.setText("50 pts"); typeOne.setLocation(5,20); if ( aVL.type == 50 ) typeOne.setChecked(true); typeOne.setSize(80,19); typeTwo = new RadioButton(); typeTwo.setText("100 pts"); typeTwo.setLocation(5,40); typeTwo.setSize(80,19); if ( aVL.type == 100 ) typeTwo.setChecked(true); typeThree = new RadioButton(); typeThree.setText("200 pts"); typeThree.setLocation(5,60); typeThree.setSize(80,19); if ( aVL.type == 200 ) typeThree.setChecked(true); typeButtonBox = new GroupBox(); typeButtonBox.add(typeOne); typeButtonBox.add(typeTwo); typeButtonBox.add(typeThree); typeButtonBox.setText("VL Value"); typeButtonBox.setLocation(10,10); typeButtonBox.setSize(100,120); this.add(typeButtonBox); typeNone = new RadioButton(); typeNone.setText("Regular VL"); typeNone.setLocation(5,20); typeNone.setSize(80,19); if ( aVL.exitsTo == 0xCC ) typeNone.setChecked(true); typeExitOne = new RadioButton(); typeExitOne.setText("\"Entry\" VL"); typeExitOne.setLocation(5,40); typeExitOne.setSize(80,19); if ( aVL.exitsTo == 0xFE ) typeExitOne.setChecked(true); typeExitTwo = new RadioButton(); typeExitTwo.setText("Exit VL"); typeExitTwo.setLocation(5,60); typeExitTwo.setSize(80,19); if ( aVL.exitsTo > -1 && aVL.exitsTo < 44 ) typeExitTwo.setChecked(true); typeExitTwo.addOnCheckedChanged(handle); otherBox = new GroupBox(); otherBox.add(typeNone); otherBox.add(typeExitOne); otherBox.add(typeExitTwo); mapList = new ComboBox(); for ( int i = 0 ; i < 44 ; i++ ) { mapList.addItem(Integer.toString(i)); } mapList.setStyle(ComboBoxStyle.DROPDOWNLIST); mapList.setLocation(5,80); mapList.setSize(80,19); otherBox.add(mapList); mapList.setSelectedIndex(0); if ( typeExitTwo.getChecked() ) { mapList.setSelectedIndex(aVL.exitsTo); } else { mapList.setEnabled(false); } otherBox.setText("VL Type"); otherBox.setLocation(120,10); otherBox.setSize(100,120); this.add(otherBox); OKB = new Button(); OKB.setText("OK"); OKB.addOnClick(new EventHandler(buttonClicked)); OKB.setLocation(10,200); cancelB = new Button(); cancelB.setText("Cancel"); cancelB.addOnClick(new EventHandler(buttonClicked)); cancelB.setLocation(110,200); deleteB = new Button(); deleteB.setText("Delete"); deleteB.addOnClick(new EventHandler(buttonClicked)); deleteB.setLocation(210,200); this.add(OKB); this.add(cancelB); this.add(deleteB); GroupBox nameBox = new GroupBox(); nameBox.setText("VL Name"); nameBox.setLocation(10,140); nameBox.setSize(210,50); VLName = new Edit(); VLName.addOnTextChanged(handle); VLName.setMaxLength(20); VLName.setText(aVL.name); VLName.setLocation(10,20); VLName.setSize(190,20); nameBox.add(VLName); this.add(nameBox); this.setShowInTaskbar(false); this.setStartPosition(FormStartPosition.CENTER_SCREEN); } public Point getMaxTrackSize() { return(thisSize); } public Point getMinTrackSize() { return(thisSize); } public void aStateChange(Object sender,Event e) { if ( sender.equals(typeExitTwo) ) { mapList.setEnabled(typeExitTwo.getChecked()); } } public void buttonClicked(Object sender,Event e) { //System.out.println(((Button)sender).getText()); String commandText = ((Button)sender).getText(); if ( commandText.equals(deleteB.getText()) ) { VLS.removeElementAt(index); this.close(); } if ( commandText.equals(cancelB.getText()) ) { this.close(); } if ( commandText.equals(OKB.getText()) ) { VL aVL = (VL)(VLS.elementAt(index)); aVL.name = VLName.getText(); if ( typeOne.getChecked() ) aVL.type = 50; if ( typeTwo.getChecked() ) aVL.type = 100; if ( typeThree.getChecked() ) aVL.type = 200; if ( typeNone.getChecked() ) aVL.exitsTo = 0xCC; if ( typeExitOne.getChecked() ) aVL.exitsTo = 0xFE; if ( typeExitTwo.getChecked() ) aVL.exitsTo = mapList.getSelectedIndex(); this.close(); } } } private class VL { public int type; public Point location; public String name; public int exitsTo; public VL() { } public VL(Point aLocation,int aType,String aName,int anExitsTo ) { type = aType; location = aLocation; name = aName; exitsTo = anExitsTo; } public VL(byte[] chunk) { location = new Point(chunk[0]&0xff,chunk[1]&0xff); type = chunk[4] & 0xff; //System.out.println(Integer.toHexString(type)); exitsTo = chunk[29]&0xff; String aName = ""; for ( int i = 0 ; i < 20 ; i++ ) { aName = aName + (new Character((char)(chunk[i+8]&0xff)).toString()); } name = aName; } } private class ScreenArea extends Control { public Graphics thisG,offG; Bitmap baseBitmap,offBitmap; Point actualSize; Point drawnSize; Point megaTiles; Point drawnMegaSizes; public ScreenArea() { } public ScreenArea(Bitmap theMap) { Point mapSize = theMap.getSize(); actualSize = mapSize; megaTiles = new Point(actualSize.x/120,actualSize.y/120); Rectangle area = SystemInformation.getVirtualScreen(); int areaW = (area.width)-100; int areaH = (area.height)-100; double ratio = (double)mapSize.x / (double)mapSize.y; Point scaledSize; //System.out.println(ratio); scaledSize = new Point(areaW,(int)(areaW/ratio)); while ( scaledSize.x > areaW || scaledSize.y > areaH ) { scaledSize = new Point(scaledSize.x-1,(int)((scaledSize.x-1)/ratio)); } //System.out.println(scaledSize); //scaledSize = new Point(scaledSize.x - (scaledSize.x % MULTI ),scaledSize.y - (scaledSize.y % MULTI ) ); drawnMegaSizes = new Point(scaledSize.x/megaTiles.x,scaledSize.y/megaTiles.y); drawnMegaSizes = new Point(2*(drawnMegaSizes.x/2),2*(drawnMegaSizes.y/2)); scaledSize = new Point(drawnMegaSizes.x*megaTiles.x,drawnMegaSizes.y*megaTiles.y); //drawnMegaSizes = new Point(scaledSize.x/megaTiles.x,scaledSize.y/megaTiles.y); //System.out.println(scaledSize); baseBitmap = new Bitmap(scaledSize.x,scaledSize.y); offBitmap = new Bitmap(scaledSize.x,scaledSize.y); Graphics tempG = baseBitmap.getGraphics(); this.setSize(scaledSize.x,scaledSize.y); tempG.drawImage(theMap,new Rectangle(0,0,scaledSize.x,scaledSize.y),true); thisG = this.createGraphics(); offG = offBitmap.getGraphics(); //offBitmap.setTransparent(true); //offBitmap.setTransparentColor(Color.WHITE); drawnSize = scaledSize; } public void repaint() { this.redraw(this,null); } protected void onPaint(PaintEvent e) { redraw(this,e); //thisG.drawImage(offBitmap,0,0); } public void redraw(Object sender,PaintEvent e) { offG.drawImage(baseBitmap,0,0); for ( int i = 0 ; i < megaTiles.x ; i++ ) { Point start = new Point(i*drawnMegaSizes.x,0); Point end = new Point(i*drawnMegaSizes.x,drawnSize.y); offG.drawLine(start,end); } for ( int i = 0 ; i < megaTiles.y ; i++ ) { Point start = new Point(0,i*drawnMegaSizes.y); Point end = new Point(drawnSize.x,i*drawnMegaSizes.y); offG.drawLine(start,end); } for ( int i = 0 ; i < VLS.size() ; i++ ) { VL aVL = (VL)(VLS.elementAt(i)); Point loc = aVL.location; loc = new Point(loc.x*drawnMegaSizes.x,loc.y*drawnMegaSizes.y); offG.setOpaque(false); int offset = drawnMegaSizes.x/10; offG.setFont(new Font(Font.DEFAULT_GUI,(float)(drawnMegaSizes.y/2),FontSize.PIXELS)); offG.setBrush(new Brush(Color.WHITE,BrushStyle.HOLLOW)); offG.setTextSpace(2); if ( aVL.exitsTo > -1 && aVL.exitsTo < 44 ) { offG.setPen(new Pen(Color.GREEN,PenStyle.SOLID,2)); offG.setBackColor(Color.GREEN); offG.setOpaque(true); offG.drawString((Integer.toString(aVL.exitsTo)),loc.x+1,loc.y+drawnMegaSizes.y/2); offG.setOpaque(false); } if ( aVL.exitsTo == 0xFE ) { offG.setPen(new Pen(Color.GREEN,PenStyle.SOLID,2)); offG.setBackColor(Color.GREEN); offG.setOpaque(true); offG.drawString("E",loc.x+1,loc.y+offset*5); offG.setOpaque(false); } offG.setPen(new Pen(Color.CYAN,PenStyle.SOLID,2)); offG.setBackColor(Color.CYAN); offG.drawRect(loc.x,loc.y,drawnMegaSizes.x,drawnMegaSizes.y); offG.setOpaque(true); offG.setTextColor(Color.BLACK); offG.setPen(new Pen(Color.BLACK,PenStyle.SOLID,1)); if ( aVL.type == 50 ) { offG.drawString("1",loc.x+1,loc.y+1); } if ( aVL.type == 100 ) { offG.drawString("2",loc.x+1,loc.y+1); } if ( aVL.type == 200 ) { offG.drawString("3",loc.x+1,loc.y+1); } } thisG = this.createGraphics(); thisG.drawImage(offBitmap,0,0); } } }