SpritePatternViewer.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.awt.*;
16: import java.awt.event.*;
17: import java.awt.font.*;
18: import java.awt.geom.*;
19: import java.awt.image.*;
20: import java.lang.*;
21: import java.util.*;
22: import javax.swing.*;
23: import javax.swing.event.*;
24:
25: public class SpritePatternViewer {
26:
27: public static final boolean SPV_ON = true;
28:
29:
30: static final String SPV_RULER_NAME = "Dialog";
31: static final int SPV_RULER_STYLE = Font.PLAIN;
32: static final int SPV_RULER_SIZE = 18;
33: static final Font SPV_RULER_FONT = new Font (SPV_RULER_NAME, SPV_RULER_STYLE, SPV_RULER_SIZE);
34: static final int SPV_RULER_WIDTH = SPV_RULER_SIZE * 3;
35: static final int SPV_RULER_HEIGHT = SPV_RULER_SIZE;
36: static final int SPV_CELL_WIDTH = 36;
37: static final int SPV_CELL_HEIGHT = 36;
38: static final int SPV_LATTICE_WIDTH = 2;
39: static final int SPV_LATTICE_HEIGHT = 2;
40: static final int SPV_BACKGROUND_RGB = 0xff555555;
41: static final int SPV_BLOCK_DOT_RGB = 0xffffffff;
42: static final int SPV_GRAY_LINE_RGB = 0xffaaaaaa;
43: static final int SPV_RULER_RGB = 0xffffffff;
44: static final int SPV_LATTICE_RGB = 0xffaaaaaa;
45:
46:
47: static int spvImageWidth;
48: static int spvImageHeight;
49: static BufferedImage spvBufferedImage;
50:
51:
52: static int[] spvBitmap;
53:
54:
55: static ScrollCanvas spvCanvas;
56:
57:
58:
59:
60:
61:
62:
63:
64:
65: static int spvBankNumber;
66: static JComboBox<String> spvBankComboBox;
67: static int spvCellOffset;
68: static int spvCellLength;
69: static int spvCols;
70: static int spvRows;
71: static int spvWidth;
72: static int spvHeight;
73:
74:
75: static final int[] spvLastSizeArray = new int[4096];
76: static final int[] spvSizeArray = new int[4096];
77: static final int SPV_DEFAULT_SIZE = 1;
78: static int spvSizeNumber;
79: static JComboBox<String> spvSizeComboBox;
80:
81:
82: static final int[] spvLastBlockArray = new int[4 * 4096];
83: static final int[] spvBlockArray = new int[4 * 4096];
84: static final int SPV_DEFAULT_BLOCK = 1;
85: static int spvBlockNumber;
86: static JComboBox<String> spvBlockComboBox;
87:
88:
89: static final int[] spvLastFlipArray = new int[4 * 4096];
90: static final int[] spvFlipArray = new int[4 * 4096];
91: static final int SPV_DEFAULT_FLIP = 0;
92: static int spvFlipNumber;
93: static JComboBox<String> spvFlipComboBox;
94:
95:
96: static JComboBox<String> spvScaleComboBox;
97:
98:
99: static JTextField spvTextField;
100: static boolean spvTextLocked;
101:
102:
103: static JFrame spvFrame;
104:
105:
106: static JPopupMenu spvPopupMenu;
107: static int spvOffsetToCopy;
108: static int spvLengthToCopy;
109:
110:
111: public static final int SPV_INTERVAL = 10;
112: public static int spvTimer;
113:
114:
115:
116: public static void spvInit () {
117:
118:
119: spvImageWidth = spvColToX (64) - SPV_LATTICE_WIDTH;
120: spvImageHeight = spvRowToY (64) - SPV_LATTICE_HEIGHT;
121:
122:
123: spvSetBankNumber (0);
124:
125:
126: spvSizeNumber = -1;
127: Arrays.fill (spvLastSizeArray, SPV_DEFAULT_SIZE);
128:
129:
130: spvBlockNumber = -1;
131: Arrays.fill (spvLastBlockArray, SPV_DEFAULT_BLOCK);
132:
133:
134: spvFlipNumber = -1;
135: Arrays.fill (spvLastFlipArray, SPV_DEFAULT_FLIP);
136:
137:
138: spvSetStoppedOff ();
139:
140:
141: spvFrame = null;
142:
143:
144: spvTimer = 0;
145:
146: }
147:
148:
149:
150: static void spvSetBankNumber (int number) {
151: spvBankNumber = number;
152: spvCellOffset = (spvBankNumber < 16 ? 256 * spvBankNumber :
153: spvBankNumber < 20 ? 1024 * (spvBankNumber - 16) :
154: 0);
155: spvCellLength = (spvBankNumber < 16 ? 256 :
156: spvBankNumber < 20 ? 1024 :
157: 4096);
158: spvCols =
159: spvRows = (spvBankNumber < 16 ? 16 :
160: spvBankNumber < 20 ? 32 :
161: 64);
162: spvWidth = spvColToX (spvCols) - SPV_LATTICE_WIDTH;
163: spvHeight = spvRowToY (spvRows) - SPV_LATTICE_HEIGHT;
164: if (spvCanvas != null) {
165: spvDrawRuler ();
166: spvCanvas.setImage (spvWidth, spvHeight);
167: }
168: }
169:
170:
171:
172: static int spvColToX (int col) {
173: return SPV_RULER_WIDTH + (SPV_CELL_WIDTH * 8 + SPV_LATTICE_WIDTH) * (col >> 3) + SPV_CELL_WIDTH * (col & 7);
174: }
175:
176:
177:
178: static int spvXToCol (int x) {
179: x -= SPV_RULER_WIDTH;
180: if (x < 0 || (SPV_CELL_WIDTH * 8 + SPV_LATTICE_WIDTH) * (spvCols >> 3) <= x) {
181: return -1;
182: }
183: int q = x / (SPV_CELL_WIDTH * 8 + SPV_LATTICE_WIDTH);
184: x -= (SPV_CELL_WIDTH * 8 + SPV_LATTICE_WIDTH) * q;
185: if (SPV_CELL_WIDTH * 8 <= x) {
186: return -1;
187: }
188: return 8 * q + x / SPV_CELL_WIDTH;
189: }
190:
191:
192:
193: static int spvRowToY (int row) {
194: return SPV_RULER_HEIGHT + (SPV_CELL_HEIGHT * 8 + SPV_LATTICE_HEIGHT) * (row >> 3) + SPV_CELL_HEIGHT * (row & 7);
195: }
196:
197:
198:
199: static int spvYToRow (int y) {
200: y -= SPV_RULER_HEIGHT;
201: if (y < 0 || (SPV_CELL_HEIGHT * 8 + SPV_LATTICE_HEIGHT) * (spvRows >> 3) <= y) {
202: return -1;
203: }
204: int q = y / (SPV_CELL_HEIGHT * 8 + SPV_LATTICE_HEIGHT);
205: y -= (SPV_CELL_HEIGHT * 8 + SPV_LATTICE_HEIGHT) * q;
206: if (SPV_CELL_HEIGHT * 8 <= y) {
207: return -1;
208: }
209: return 8 * q + y / SPV_CELL_HEIGHT;
210: }
211:
212:
213:
214: public static void spvStart () {
215: if (RestorableFrame.rfmGetOpened (Settings.SGS_SPV_FRAME_KEY)) {
216: spvOpen ();
217: }
218: }
219:
220:
221:
222: public static void spvOpen () {
223: if (spvFrame == null) {
224: spvMakeFrame ();
225: } else {
226: spvUpdateFrame ();
227: }
228: XEiJ.dbgVisibleMask |= XEiJ.DBG_SPV_VISIBLE_MASK;
229: XEiJ.pnlExitFullScreen (false);
230: spvFrame.setVisible (true);
231: }
232:
233:
234:
235:
236: static void spvMakeFrame () {
237:
238:
239: spvBufferedImage = new BufferedImage (spvImageWidth, spvImageHeight, BufferedImage.TYPE_INT_ARGB);
240: spvDrawRuler ();
241:
242:
243: spvBitmap = ((DataBufferInt) spvBufferedImage.getRaster ().getDataBuffer ()).getData ();
244:
245:
246: spvCanvas = new ScrollCanvas (spvBufferedImage, spvWidth, spvHeight);
247: spvCanvas.setMatColor (new Color (SPV_BACKGROUND_RGB));
248:
249:
250: ActionListener listener = new ActionListener () {
251: @Override public void actionPerformed (ActionEvent ae) {
252: Object source = ae.getSource ();
253: String command = ae.getActionCommand ();
254: switch (command) {
255: case "Bank":
256: spvSetBankNumber (spvBankComboBox.getSelectedIndex ());
257: if (XEiJ.mpuTask == null) {
258: spvUpdateFrame ();
259: }
260: break;
261: case "Size":
262: spvSizeNumber = spvSizeComboBox.getSelectedIndex () - 1;
263: if (XEiJ.mpuTask == null) {
264: spvUpdateFrame ();
265: }
266: break;
267: case "Block":
268: spvBlockNumber = spvBlockComboBox.getSelectedIndex () - 1;
269: if (XEiJ.mpuTask == null) {
270: spvUpdateFrame ();
271: }
272: break;
273: case "Flip":
274: spvFlipNumber = spvFlipComboBox.getSelectedIndex () - 1;
275: if (XEiJ.mpuTask == null) {
276: spvUpdateFrame ();
277: }
278: break;
279: case "Stop":
280: spvStoppedRequest = (((JCheckBox) source).isSelected ());
281: if (XEiJ.mpuTask == null) {
282: spvUpdateFrame ();
283: }
284: break;
285: case "Scale":
286: spvCanvas.setScaleShift (spvScaleComboBox.getSelectedIndex () - 4);
287: break;
288: case "Copy as hexadecimal":
289: spvCopyPattern ();
290: break;
291: default:
292: System.out.println ("unknown action command " + command);
293: }
294: }
295: };
296:
297:
298: spvTextField = new JTextField ();
299: spvTextField.setEditable (false);
300: spvTextField.setHorizontalAlignment (JTextField.CENTER);
301:
302:
303: spvFrame = Multilingual.mlnTitle (
304: ComponentFactory.createRestorableSubFrame (
305: Settings.SGS_SPV_FRAME_KEY,
306: "Sprite Pattern Viewer",
307: null,
308: ComponentFactory.createBorderPanel (
309: 0, 0,
310:
311: spvCanvas,
312:
313: ComponentFactory.createVerticalBox (
314:
315: ComponentFactory.createHorizontalBox (
316: Box.createHorizontalGlue (),
317:
318: Multilingual.mlnText (
319: ComponentFactory.createLabel ("Bank "),
320: "ja", "バンク "),
321: spvBankComboBox = ComponentFactory.createComboBox (
322: spvBankNumber,
323: "Bank",
324: listener,
325: "0", "1", "2", "3", "4", "5", "6", "7", "8",
326: "9", "10", "11", "12", "13", "14", "15",
327: "0-3", "4-7", "8-11", "12-15", "0-15"),
328:
329: Multilingual.mlnText (
330: ComponentFactory.createLabel (" Size "),
331: "ja", " サイズ "),
332: spvSizeComboBox = ComponentFactory.createComboBox (
333: spvSizeNumber + 1,
334: "Size",
335: listener,
336: 4,
337: Multilingual.mlnJapanese ? "自動" : "Auto",
338: "8x8", "16x16"),
339:
340: Multilingual.mlnText (
341: ComponentFactory.createLabel (" Block "),
342: "ja", " ブロック "),
343: spvBlockComboBox = ComponentFactory.createComboBox (
344: spvBlockNumber + 1,
345: "Block",
346: listener,
347: 4,
348: Multilingual.mlnJapanese ? "自動" : "Auto",
349: "0", "1", "2", "3", "4", "5", "6", "7", "8",
350: "9", "10", "11", "12", "13", "14", "15"),
351:
352: Multilingual.mlnText (
353: ComponentFactory.createLabel (" Flip "),
354: "ja", " 反転 "),
355: spvFlipComboBox = ComponentFactory.createComboBox (
356: spvFlipNumber + 1,
357: "Flip",
358: listener,
359: 4,
360: Multilingual.mlnJapanese ? "自動" : "Auto",
361: Multilingual.mlnJapanese ? "なし" : "-",
362: Multilingual.mlnJapanese ? "左右" : "H",
363: Multilingual.mlnJapanese ? "上下" : "V",
364: Multilingual.mlnJapanese ? "上下左右" : "H&V"),
365:
366: Box.createHorizontalGlue ()
367: ),
368:
369: ComponentFactory.createHorizontalBox (
370: Box.createHorizontalStrut (10),
371:
372: spvTextField,
373:
374: Box.createHorizontalStrut (10),
375: Multilingual.mlnText (
376: ComponentFactory.createCheckBox (spvStoppedRequest, "Stop", listener),
377: "ja", "停止"),
378:
379: Box.createHorizontalStrut (10),
380:
381: Multilingual.mlnText (
382: ComponentFactory.createLabel (" Scale "),
383: "ja", " 倍率 "),
384: spvScaleComboBox = ComponentFactory.createComboBox (
385: spvCanvas.getScaleShift () + 4,
386: "Scale",
387: listener,
388: "1/8", "1/4", "1/2", "1", "2", "4", "8", "16", "32"),
389:
390: Box.createHorizontalStrut (10)
391: )
392: )
393: )
394: ),
395: "ja", "スプライトパターンビュア");
396:
397:
398: spvCanvas.addScaleShiftListener (new ScrollCanvas.ScaleShiftListener () {
399: @Override public void scaleShiftChanged (int scaleShift) {
400: spvScaleComboBox.setSelectedIndex (scaleShift + 4);
401: }
402: });
403:
404:
405: ComponentFactory.addListener (
406: spvFrame,
407: new WindowAdapter () {
408: @Override public void windowClosing (WindowEvent we) {
409: XEiJ.dbgVisibleMask &= ~XEiJ.DBG_SPV_VISIBLE_MASK;
410: }
411: });
412:
413:
414: spvPopupMenu = ComponentFactory.createPopupMenu (
415: Multilingual.mlnText (
416: ComponentFactory.createMenuItem ("Copy as hexadecimal", 'C', listener),
417: "ja", "16進数でコピー")
418: );
419:
420:
421: MouseAdapter ma = new MouseAdapter () {
422: @Override public void mouseClicked (MouseEvent me) {
423: spvTextLocked = !spvTextLocked;
424: }
425: @Override public void mouseMoved (MouseEvent me) {
426: if (!spvTextLocked) {
427: MouseEvent2D me2D = (MouseEvent2D) me;
428: int x = (int) me2D.getX2D ();
429: int y = (int) me2D.getY2D ();
430: String s = spvGetPixel (x, y);
431: spvTextField.setText (s == null ? "" : s);
432: }
433: }
434: @Override public void mousePressed (MouseEvent me) {
435: spvShowPopup (me);
436: }
437: @Override public void mouseReleased (MouseEvent me) {
438: spvShowPopup (me);
439: }
440: };
441: spvCanvas.addMouseListener (ma);
442: spvCanvas.addMouseMotionListener (ma);
443:
444: }
445:
446:
447:
448: static void spvDrawRuler () {
449: Graphics2D g2 = spvBufferedImage.createGraphics ();
450:
451: g2.setColor (new Color (SPV_BACKGROUND_RGB));
452: g2.fillRect (0, 0, spvWidth, spvHeight);
453:
454: g2.setColor (new Color (SPV_LATTICE_RGB));
455: g2.fillRect (SPV_RULER_WIDTH,
456: SPV_RULER_HEIGHT,
457: spvWidth - SPV_RULER_WIDTH,
458: spvHeight - SPV_RULER_HEIGHT);
459:
460: g2.setColor (new Color (SPV_RULER_RGB));
461: g2.setFont (SPV_RULER_FONT);
462: FontRenderContext frc = g2.getFontRenderContext ();
463: for (int col = 0; col < spvCols; col++) {
464: String s = String.format ("%d", col);
465: TextLayout tl = new TextLayout (s, SPV_RULER_FONT, frc);
466: Rectangle2D r = tl.getBounds ();
467: int rx = (int) Math.round (r.getX ());
468: int ry = (int) Math.round (r.getY ());
469: int rw = (int) Math.round (r.getWidth ());
470: int rh = (int) Math.round (r.getHeight ());
471: int bx = spvColToX (col) + SPV_CELL_WIDTH / 2;
472: int by = spvRowToY (0) - SPV_RULER_SIZE / 12;
473: g2.drawString (s, bx - rx - rw / 2, by - ry - rh);
474: }
475: for (int row = 0; row < spvRows; row++) {
476: String s = String.format ("%d", spvCellOffset + spvCols * row);
477: TextLayout tl = new TextLayout (s, SPV_RULER_FONT, frc);
478: Rectangle2D r = tl.getBounds ();
479: int rx = (int) Math.round (r.getX ());
480: int ry = (int) Math.round (r.getY ());
481: int rw = (int) Math.round (r.getWidth ());
482: int rh = (int) Math.round (r.getHeight ());
483: int bx = spvColToX (0) - SPV_RULER_SIZE / 6;
484: int by = spvRowToY (row) + SPV_CELL_HEIGHT / 2;
485: g2.drawString (s, bx - rx - rw, by - ry - rh / 2);
486: }
487: }
488:
489:
490:
491: static void spvShowPopup (MouseEvent me) {
492: if (me.isPopupTrigger ()) {
493: MouseEvent2D me2D = (MouseEvent2D) me;
494: int x = (int) me2D.getX2D ();
495: int y = (int) me2D.getY2D ();
496: if (spvGetPatternToCopy (x, y)) {
497: Point p = spvCanvas.getPopupPoint (me2D);
498: spvPopupMenu.show (spvCanvas, p.x, p.y);
499: }
500: }
501: }
502:
503:
504:
505:
506: static boolean spvGetPatternToCopy (int x, int y) {
507: int cCol = spvXToCol (x);
508: int cRow = spvYToRow (y);
509: if (0 <= cCol && 0 <= cRow) {
510: x -= spvColToX (cCol);
511: y -= spvRowToY (cRow);
512: int n = (spvCellOffset + cCol + spvCols * cRow) << 2;
513: int size = spvSizeArray[n >> 2];
514: if (size < 0) {
515: size = spvLastSizeArray[n >> 2];
516: }
517: if (size == 0) {
518: int qCol = x / (SPV_CELL_WIDTH / 2);
519: int qRow = y / (SPV_CELL_HEIGHT / 2);
520: x -= (SPV_CELL_WIDTH / 2) * qCol;
521: y -= (SPV_CELL_HEIGHT / 2) * qRow;
522: n += qRow + 2 * qCol;
523: spvOffsetToCopy = n << 3;
524: spvLengthToCopy = 1 << 3;
525: return true;
526: } else {
527: spvOffsetToCopy = n << 3;
528: spvLengthToCopy = 4 << 3;
529: return true;
530: }
531: }
532: spvOffsetToCopy = 0;
533: spvLengthToCopy = 0;
534: return false;
535: }
536:
537:
538:
539: static void spvCopyPattern () {
540: if (spvLengthToCopy != 0) {
541: StringBuilder sb = new StringBuilder ();
542: for (int i = 0; i < spvLengthToCopy; i++) {
543: sb.append (String.format ("%08X\n", spvPat[spvOffsetToCopy + i]));
544: }
545: XEiJ.clpCopy (sb.toString ());
546: }
547: }
548:
549:
550:
551: static String spvGetPixel (int x, int y) {
552: int cCol = spvXToCol (x);
553: int cRow = spvYToRow (y);
554: if (0 <= cCol && 0 <= cRow) {
555: x -= spvColToX (cCol);
556: y -= spvRowToY (cRow);
557: int n = (spvCellOffset + cCol + spvCols * cRow) << 2;
558: int size = spvSizeArray[n >> 2];
559: if (size < 0) {
560: size = spvLastSizeArray[n >> 2];
561: }
562: if (size == 0) {
563: int qCol = x / (SPV_CELL_WIDTH / 2);
564: int qRow = y / (SPV_CELL_HEIGHT / 2);
565: x -= (SPV_CELL_WIDTH / 2) * qCol;
566: y -= (SPV_CELL_HEIGHT / 2) * qRow;
567: n += qRow + 2 * qCol;
568: x -= 1;
569: y -= 1;
570: if (0 <= x && x < 2 * 8 &&
571: 0 <= y && y < 2 * 8) {
572: x >>= 1;
573: y >>= 1;
574: int pb = spvBlockArray[n];
575: if (pb < 0) {
576: pb = spvLastBlockArray[n];
577: }
578: int vh = spvFlipArray[n];
579: if (vh < 0) {
580: vh = spvLastFlipArray[n];
581: }
582: int v = vh >> 1;
583: int h = vh & 1;
584: if (h != 0) {
585: x ^= 7;
586: }
587: if (v != 0) {
588: y ^= 7;
589: }
590: int pc = (spvPat[(n << 3) + y] >> ((7 - x) << 2)) & 15;
591: int p = pb << 4 | pc;
592: int c = spvPal16TS[p];
593: return String.format ("8x8 n=%d x=%d y=%d p=0x%02X c=0x%04X(%d,%d,%d,%d)",
594: n, x, y, p, c,
595: c >> 11, (c >> 6) & 31, (c >> 1) & 31, c & 1);
596: }
597: } else {
598: x -= 2;
599: y -= 2;
600: if (0 <= x && x < 2 * 16 &&
601: 0 <= y && y < 2 * 16) {
602: x >>= 1;
603: y >>= 1;
604: int pb = spvBlockArray[n];
605: if (pb < 0) {
606: pb = spvLastBlockArray[n];
607: }
608: int vh = spvFlipArray[n];
609: if (vh < 0) {
610: vh = spvLastFlipArray[n];
611: }
612: int v = vh >> 1;
613: int h = vh & 1;
614: if ((vh & 1) != 0) {
615: x ^= 15;
616: }
617: if ((vh & 2) != 0) {
618: y ^= 15;
619: }
620: int pc = (spvPat[(n << 3) + y + ((x & 8) << 1)] >> ((7 - (x & 7)) << 2)) & 15;
621: int p = pb << 4 | pc;
622: int c = spvPal16TS[p];
623: return String.format ("16x16 n=%d x=%d y=%d p=0x%02X c=0x%04X(%d,%d,%d,%d)",
624: n >> 2, x, y, p, c,
625: c >> 11, (c >> 6) & 31, (c >> 1) & 31, c & 1);
626: }
627: }
628: }
629: return null;
630: }
631:
632:
633:
634: static void spvUpdateFrame () {
635: if (spvFrame == null) {
636: return;
637: }
638:
639:
640: if (spvStopped != spvStoppedRequest) {
641: if (spvStoppedRequest) {
642: spvSetStoppedOn ();
643: } else {
644: spvSetStoppedOff ();
645: }
646: }
647:
648:
649: for (int i = 0; i < 256; i++) {
650: spvPal32TS[i] = spvPalTbl[spvPal16TS[i]];
651: }
652:
653:
654: Arrays.fill (spvSizeArray, spvSizeNumber);
655: Arrays.fill (spvBlockArray, spvBlockNumber);
656: Arrays.fill (spvFlipArray, spvFlipNumber);
657:
658: if (spvSizeNumber < 0 ||
659: spvBlockNumber < 0 ||
660: spvFlipNumber < 0) {
661:
662: for (int sn = 0; sn < SpriteScreen.sprNumberOfSprites; sn++) {
663: if ((256 <= sn && sn < 256 + 8) ||
664: spvPrw[sn] == 0) {
665: continue;
666: }
667: int n = spvNum[sn] << 2;
668: if (spvSizeArray[n >> 2] < 0) {
669: spvSizeArray[n >> 2] =
670: spvLastSizeArray[n >> 2] = 1;
671: }
672: int pb = spvCol[sn] >> 4;
673: int vh = ((spvV[sn] ? 2 : 0) |
674: (spvH[sn] ? 1 : 0));
675: for (int k = 0; k < 4; k++) {
676: if (spvBlockArray[n + k] < 0) {
677: spvBlockArray[n + k] =
678: spvLastBlockArray[n + k] = pb;
679: }
680: if (spvFlipArray[n + k] < 0) {
681: spvFlipArray[n + k] =
682: spvLastFlipArray[n + k] = vh;
683: }
684: }
685: }
686:
687: int tm = 0;
688: if ((SpriteScreen.sprReg4BgCtrlPort & 1) != 0) {
689: tm |= 1 << ((SpriteScreen.sprReg4BgCtrlPort >> 1) & 3);
690: }
691: if (((SpriteScreen.sprReg8ResoPort & 3) == 0 ||
692: SpriteScreen.spr512bg1) &&
693: (SpriteScreen.sprReg4BgCtrlPort & 8) != 0) {
694: tm |= 1 << ((SpriteScreen.sprReg4BgCtrlPort >> 4) & 3);
695: }
696: if ((SpriteScreen.sprReg8ResoPort & 3) == 0) {
697: for (int tp = 0; tp < 4; tp++) {
698: if ((tm & (1 << tp)) == 0) {
699: continue;
700: }
701: int o = 4096 * tp;
702: for (int i = 0; i < 4096; i++) {
703: int n = spvTNum[o + i] >> 3;
704: if (spvSizeArray[n >> 2] < 0) {
705: spvSizeArray[n >> 2] =
706: spvLastSizeArray[n >> 2] = 0;
707: }
708: int pb = spvTCol[o + i] >> 4;
709: int vh = ((spvTV[o + i] ? 2 : 0) |
710: (spvTH[o + i] ? 1 : 0));
711: if (spvBlockArray[n] < 0) {
712: spvBlockArray[n] =
713: spvLastBlockArray[n] = pb;
714: }
715: if (spvFlipArray[n] < 0) {
716: spvFlipArray[n] =
717: spvLastFlipArray[n] = vh;
718: }
719: }
720: }
721: } else {
722: for (int tp = 0; tp < 4; tp++) {
723: if ((tm & (1 << tp)) == 0) {
724: continue;
725: }
726: int o = 4096 * tp;
727: for (int i = 0; i < 4096; i++) {
728: int n = spvTNum[o + i] >> 1;
729: if (spvSizeArray[n >> 2] < 0) {
730: spvSizeArray[n >> 2] =
731: spvLastSizeArray[n >> 2] = 1;
732: }
733: int pb = spvTCol[o + i] >> 4;
734: int vh = ((spvTV[o + i] ? 2 : 0) |
735: (spvTH[o + i] ? 1 : 0));
736: for (int k = 0; k < 4; k++) {
737: if (spvBlockArray[n + k] < 0) {
738: spvBlockArray[n + k] =
739: spvLastBlockArray[n + k] = pb;
740: }
741: if (spvFlipArray[n + k] < 0) {
742: spvFlipArray[n + k] =
743: spvLastFlipArray[n + k] = vh;
744: }
745: }
746: }
747: }
748: }
749:
750: for (int n = 0; n < 4096; n++) {
751: if (spvSizeArray[n] < 0) {
752: spvSizeArray[n] = spvLastSizeArray[n];
753: }
754: }
755: for (int n = 0; n < 4 * 4096; n++) {
756: if (spvBlockArray[n] < 0) {
757: spvBlockArray[n] = spvLastBlockArray[n];
758: }
759: if (spvFlipArray[n] < 0) {
760: spvFlipArray[n] = spvLastFlipArray[n];
761: }
762: }
763: }
764:
765:
766: int a = 32 * spvCellOffset;
767: for (int cRow = 0; cRow < spvRows; cRow++) {
768: int cY = spvRowToY (cRow);
769: for (int cCol = 0; cCol < spvCols; cCol++) {
770: int cX = spvColToX (cCol);
771: int cIndex = cX + spvImageWidth * cY;
772:
773:
774: int i = cIndex;
775: for (int v = 0; v < SPV_CELL_HEIGHT; v++) {
776: for (int h = 0; h < SPV_CELL_WIDTH; h++) {
777: spvBitmap[i + h] = SPV_BACKGROUND_RGB;
778: }
779: i += spvImageWidth;
780: }
781: int n = (spvCellOffset + cCol + spvCols * cRow) << 2;
782: if (spvSizeArray[n >> 2] == 0) {
783: for (int qCol = 0; qCol < 2; qCol++) {
784: int qX = cX + SPV_CELL_WIDTH / 2 * qCol;
785: for (int qRow = 0; qRow < 2; qRow++) {
786: int qY = cY + SPV_CELL_HEIGHT / 2 * qRow;
787: int qIndex = qX + spvImageWidth * qY;
788: int pb = spvBlockArray[n];
789: int vh = spvFlipArray[n];
790: int hMask = (vh & 1) != 0 ? 7 : 0;
791: int vMask = (vh & 2) != 0 ? 15 : 0;
792:
793: i = qIndex + (hMask == 0 ? 0 + spvImageWidth * 1 :
794: 1 + 2 * 8 + spvImageWidth * 1);
795: for (int v = 0; v <= 15; v++) {
796: int vm = v ^ vMask;
797: if (vm == pb) {
798: spvBitmap[i] = SPV_BLOCK_DOT_RGB;
799: } else if (vm < 8) {
800: spvBitmap[i] = SPV_GRAY_LINE_RGB;
801: }
802: i += spvImageWidth * 1;
803: }
804:
805: pb <<= 4;
806: vMask >>= 1;
807: i = qIndex + 1 + spvImageWidth * 1;
808: for (int v = 0; v <= 7; v++) {
809: int vm = v ^ vMask;
810: int d = spvPat[a + vm];
811: for (int h = 7; 0 <= h; h--) {
812: int hm = h ^ hMask;
813: spvBitmap[i] =
814: spvBitmap[i + 1] =
815: spvBitmap[i + spvImageWidth] =
816: spvBitmap[i + spvImageWidth + 1] = spvPal32TS[pb + ((d >> (hm << 2)) & 15)];
817: i += 2;
818: }
819: i += spvImageWidth * 2 - 2 * 8;
820: }
821: a += 8;
822: n++;
823: }
824: }
825: } else {
826: int pb = spvBlockArray[n];
827: int vh = spvFlipArray[n];
828: int hMask = (vh & 1) != 0 ? 15 : 0;
829: int vMask = (vh & 2) != 0 ? 15 : 0;
830:
831: i = cIndex + (hMask == 0 ? 0 + spvImageWidth * 2 :
832: 2 + 2 * 16 + spvImageWidth * 2);
833: for (int v = 0; v <= 15; v++) {
834: int vm = v ^ vMask;
835: if (vm == pb) {
836: spvBitmap[i] =
837: spvBitmap[i + 1] =
838: spvBitmap[i + spvImageWidth] =
839: spvBitmap[i + spvImageWidth + 1] = SPV_BLOCK_DOT_RGB;
840: } else if (vm < 8) {
841: spvBitmap[i] =
842: spvBitmap[i + 1] =
843: spvBitmap[i + spvImageWidth] =
844: spvBitmap[i + spvImageWidth + 1] = SPV_GRAY_LINE_RGB;
845: }
846: i += spvImageWidth * 2;
847: }
848:
849: pb <<= 4;
850: i = cIndex + 2 + spvImageWidth * 2;
851: for (int v = 0; v <= 15; v++) {
852: int vm = v ^ vMask;
853: long d = ((long) spvPat[a + vm] << 32 |
854: (long) spvPat[a + vm + 16] & 0xffffffffL);
855: for (int h = 15; 0 <= h; h--) {
856: int hm = h ^ hMask;
857: spvBitmap[i] =
858: spvBitmap[i + 1] =
859: spvBitmap[i + spvImageWidth] =
860: spvBitmap[i + spvImageWidth + 1] = spvPal32TS[pb + ((int) (d >> (hm << 2)) & 15)];
861: i += 2;
862: }
863: i += spvImageWidth * 2 - 2 * 16;
864: }
865: a += 32;
866: }
867: }
868: }
869: spvCanvas.repaint ();
870:
871: }
872:
873:
874: static boolean spvStopped;
875: static boolean spvStoppedRequest;
876:
877: static final short[] spvCopiedNum = new short[SpriteScreen.SPR_COUNT];
878: static final short[] spvCopiedCol = new short[SpriteScreen.SPR_COUNT];
879: static final byte[] spvCopiedPrw = new byte[SpriteScreen.SPR_COUNT];
880: static final boolean[] spvCopiedH = new boolean[SpriteScreen.SPR_COUNT];
881: static final boolean[] spvCopiedV = new boolean[SpriteScreen.SPR_COUNT];
882: static final int[] spvCopiedPat = new int[32 * 4096];
883: static final short[] spvCopiedTNum = new short[4096 * 4];
884: static final short[] spvCopiedTCol = new short[4096 * 4];
885: static final boolean[] spvCopiedTH = new boolean[4096 * 4];
886: static final boolean[] spvCopiedTV = new boolean[4096 * 4];
887: static final int[] spvCopiedPalTbl = new int[65536];
888: static final int[] spvCopiedPal16TS = new int[256];
889:
890: static short[] spvNum;
891: static short[] spvCol;
892: static byte[] spvPrw;
893: static boolean[] spvH;
894: static boolean[] spvV;
895: static int[] spvPat;
896: static short[] spvTNum;
897: static short[] spvTCol;
898: static boolean[] spvTH;
899: static boolean[] spvTV;
900: static int[] spvPalTbl;
901: static int[] spvPal16TS;
902:
903: static final int[] spvPal32TS = new int[256];
904:
905: static void spvSetStoppedOn () {
906: spvStopped = true;
907: spvStoppedRequest = true;
908: System.arraycopy (SpriteScreen.sprNumPort, 0, spvCopiedNum, 0, SpriteScreen.SPR_COUNT);
909: System.arraycopy (SpriteScreen.sprColPort, 0, spvCopiedCol, 0, SpriteScreen.SPR_COUNT);
910: System.arraycopy (SpriteScreen.sprPrw, 0, spvCopiedPrw, 0, SpriteScreen.SPR_COUNT);
911: System.arraycopy (SpriteScreen.sprH, 0, spvCopiedH, 0, SpriteScreen.SPR_COUNT);
912: System.arraycopy (SpriteScreen.sprV, 0, spvCopiedV, 0, SpriteScreen.SPR_COUNT);
913: System.arraycopy (SpriteScreen.sprPatPort, 0, spvCopiedPat, 0, 32 * 4096);
914: System.arraycopy (SpriteScreen.sprTNum, 0, spvCopiedTNum, 0, 4096 * 4);
915: System.arraycopy (SpriteScreen.sprTColPort, 0, spvCopiedTCol, 0, 4096 * 4);
916: System.arraycopy (SpriteScreen.sprTH, 0, spvCopiedTH, 0, 4096 * 4);
917: System.arraycopy (SpriteScreen.sprTV, 0, spvCopiedTV, 0, 4096 * 4);
918: System.arraycopy (VideoController.vcnPalBase[VideoController.VCN_CONTRAST_SCALE * 15], 0, spvCopiedPalTbl, 0, 65536);
919: System.arraycopy (VideoController.vcnPal16TS, 0, spvCopiedPal16TS, 0, 256);
920: spvNum = spvCopiedNum;
921: spvCol = spvCopiedCol;
922: spvPrw = spvCopiedPrw;
923: spvH = spvCopiedH;
924: spvV = spvCopiedV;
925: spvPat = spvCopiedPat;
926: spvTNum = spvCopiedTNum;
927: spvTCol = spvCopiedTCol;
928: spvTH = spvCopiedTH;
929: spvTV = spvCopiedTV;
930: spvPalTbl = spvCopiedPalTbl;
931: spvPal16TS = spvCopiedPal16TS;
932: }
933:
934: static void spvSetStoppedOff () {
935: spvStopped = false;
936: spvStoppedRequest = false;
937: spvNum = SpriteScreen.sprNumPort;
938: spvCol = SpriteScreen.sprColPort;
939: spvPrw = SpriteScreen.sprPrw;
940: spvH = SpriteScreen.sprH;
941: spvV = SpriteScreen.sprV;
942: spvPat = SpriteScreen.sprPatPort;
943: spvTNum = SpriteScreen.sprTNum;
944: spvTCol = SpriteScreen.sprTColPort;
945: spvTH = SpriteScreen.sprTH;
946: spvTV = SpriteScreen.sprTV;
947: spvPalTbl = VideoController.vcnPalBase[VideoController.VCN_CONTRAST_SCALE * 15];
948: spvPal16TS = VideoController.vcnPal16TS;
949: }
950:
951: }