4 #include "MainWindow.h"
5 #include "EditArea.fdh"
7 #define SWAP(A, B) { A ^= B; B ^= A; A ^= B; }
8 static int zoomstops
[] = { 2, 4, 8, 16, 32, -1 };
10 BEGIN_EVENT_TABLE(EditArea
, wxPanel
)
12 EVT_PAINT(EditArea::OnPaint
)
13 EVT_ERASE_BACKGROUND(EditArea::OnErase
)
14 EVT_TIMER(100, EditArea::OnTimer
)
16 EVT_LEFT_DOWN(EditArea::OnMouseDown
)
17 EVT_LEFT_UP(EditArea::OnMouseUp
)
18 EVT_RIGHT_DOWN(EditArea::OnMouseDown
)
19 EVT_RIGHT_UP(EditArea::OnMouseUp
)
20 EVT_MOTION(EditArea::OnMouseMove
)
21 EVT_MOUSEWHEEL(EditArea::OnMouseWheel
)
26 void c------------------------------() {}
29 EditArea::EditArea(wxWindow
*parent
, wxWindowID id
, const wxPoint
&pos
, const wxSize
&size
)
30 : wxPanel(parent
, id
, pos
, size
)
32 fTimer
= new wxTimer(this, 100);
42 fDrag
.dragging
= false;
43 fShift
.mode
= SM_NO_SHIFT
;
53 void c------------------------------() {}
56 bool EditArea::SetBackground(const char *filename
)
59 fBackground
= new wxImage
;
61 if (!fBackground
->LoadFile(wxString(PrefixPath(filename
), wxConvUTF8
)))
63 stat("SetBackground: failed to load file '%s'", filename
);
70 void EditArea::SetZoom(int factor
)
72 if (factor
< 1) factor
= 1;
73 if (factor
> 32) factor
= 32 ;
82 void EditArea::NextZoomStop(int dir
)
85 for(curstop
=0;zoomstops
[curstop
] != -1;curstop
++)
86 if (zoomstops
[curstop
] == fZoom
) break;
88 curstop
+= (dir
> 0) ? 1 : -1;
90 if (zoomstops
[curstop
] == -1) curstop
--;
91 if (curstop
< 0) curstop
= 0;
93 fZoom
= zoomstops
[curstop
];
96 void EditArea::NextOffsStop()
106 void c------------------------------() {}
109 void EditArea::OnTimer(wxTimerEvent
&event
)
111 if (gd
.curmode
!= EM_VIEW
)
116 else fBlinkState
= 1;
119 void EditArea::OnPaint(wxPaintEvent
&event
)
125 void EditArea::Draw(wxDC
*dc
)
127 if (!fZoomedSprite
|| !fZoomedSpriteSettings
.equ(GetZoomedSpriteSettings()))
129 if (CreateZoomedSprite())
133 // create a backbuffer
134 wxBitmap
bbbmp(GetSize().GetWidth(), GetSize().GetHeight());
135 wxMemoryDC
bbdc(bbbmp
);
138 bbdc
.SetBrush(*wxLIGHT_GREY_BRUSH
);
139 bbdc
.SetPen(*wxTRANSPARENT_PEN
);
140 bbdc
.DrawRectangle(0, 0, bbbmp
.GetWidth(), bbbmp
.GetHeight());
142 // draw sprite onto backbuffer
143 bbdc
.DrawBitmap(wxBitmap(*fZoomedSprite
), fOffset
*fZoom
, fOffset
*fZoom
);
146 bbdc
.SetPen(fBlinkState
? *wxRED_PEN
: *wxBLACK_PEN
);
147 bbdc
.SetBrush(*wxTRANSPARENT_BRUSH
);
149 if (fShift
.mode
!= SM_NO_SHIFT
)
152 else if (fDrag
.dragging
)
154 DrawRect(&bbdc
, &fDrag
.draggedrect
);
156 else if (gd
.curmode
== EM_VIEW
)
158 SIFSprite
*sprite
= CurSprite();
159 SIFDir
*dir
= CurDir();
161 bbdc
.SetPen(*wxCYAN_PEN
);
162 DrawRect(&bbdc
, &sprite
->solidbox
);
164 bbdc
.SetPen(*wxRED_PEN
);
165 DrawRect(&bbdc
, &sprite
->bbox
);
166 DrawPoints(&bbdc
, &sprite
->block_l
.point
[0], sprite
->block_l
.count
);
167 DrawPoints(&bbdc
, &sprite
->block_r
.point
[0], sprite
->block_r
.count
);
168 DrawPoints(&bbdc
, &sprite
->block_u
.point
[0], sprite
->block_u
.count
);
169 DrawPoints(&bbdc
, &sprite
->block_d
.point
[0], sprite
->block_d
.count
);
171 bbdc
.SetPen(*wxGREEN_PEN
);
172 if (!dir
->actionpoint
.equ(0, 0)) DrawPoints(&bbdc
, &dir
->actionpoint
, 1);
173 if (!dir
->actionpoint2
.equ(0, 0)) DrawPoints(&bbdc
, &dir
->actionpoint2
, 1);
175 bbdc
.SetPen(*wxLIGHT_GREY_PEN
);
176 if (!sprite
->spawn_point
.equ(0, 0)) DrawPoints(&bbdc
, &sprite
->spawn_point
, 1);
178 bbdc
.SetPen(*wxCYAN_PEN
);
179 if (!dir
->drawpoint
.equ(0, 0)) DrawPoints(&bbdc
, &dir
->drawpoint
, 1);
183 SIFRect
*bbox
= GetCurrentBBox();
184 if (bbox
) DrawRect(&bbdc
, bbox
);
187 SIFPoint
*points
= GetCurrentPointList(&npoints
);
190 if (gd
.curmode
== EM_ACTIONPT
|| gd
.curmode
== EM_ACTIONPT2
)
192 bbdc
.SetPen(fBlinkState
? *wxGREEN_PEN
: *wxBLACK_PEN
);
195 DrawPoints(&bbdc
, points
, npoints
);
199 // blit contents of the backbuffer to the screen
200 dc
->Blit(0, 0, bbdc
.GetSize().GetWidth(), bbdc
.GetSize().GetHeight(), &bbdc
, 0, 0);
202 // draw coordinates when dragging
208 DrawGuideText(dc
, stprintf("%d x %d", \
209 CurSprite()->w
, CurSprite()->h
));
212 case SM_SHEET_OFFSET
:
213 DrawGuideText(dc
, stprintf("[%d, %d]", \
214 CurDir()->sheet_offset
.x
, CurDir()->sheet_offset
.y
));
218 DrawGuideText(dc
, stprintf("+[%d, %d]", \
219 fShift
.totaldx
, fShift
.totaldy
));
225 // prevent horrific flicker under Windows--keep it from
226 // trying to erase the background every time we paint.
227 void EditArea::OnErase(wxEraseEvent
&event
)
231 void EditArea::DrawRect(wxDC
*dc
, SIFRect
*rect
)
233 int x
= (fOffset
* fZoom
) + (rect
->x1
* fZoom
);
234 int y
= (fOffset
* fZoom
) + (rect
->y1
* fZoom
);
235 int w
= ((rect
->x2
- rect
->x1
) + 1) * fZoom
;
236 int h
= ((rect
->y2
- rect
->y1
) + 1) * fZoom
;
238 dc
->DrawRectangle(x
, y
, w
, h
);
241 void EditArea::DrawPoints(wxDC
*dc
, SIFPoint
*point
, int count
)
243 for(int i
=0;i
<count
;i
++)
245 int x
= (fOffset
* fZoom
) + (point
[i
].x
* fZoom
);
246 int y
= (fOffset
* fZoom
) + (point
[i
].y
* fZoom
);
248 dc
->DrawRectangle(x
, y
, fZoom
, fZoom
);
249 dc
->DrawLine(x
, y
, x
+(fZoom
-1), y
+(fZoom
-1));
253 void EditArea::DrawGuideText(wxDC
*dc
, const char *str
)
258 dc
->SetFont(wxFont(14, wxFONTFAMILY_MODERN
, wxFONTSTYLE_NORMAL
, wxFONTWEIGHT_NORMAL
));
259 dc
->SetTextForeground(wxColour(0, 0, 0));
260 dc
->SetTextBackground(wxColour(255, 255, 255));
261 dc
->SetBackgroundMode(wxSOLID
);
263 wxString
wxstr(str
, wxConvUTF8
);
264 dc
->GetTextExtent(wxstr
, &tew
, &teh
);
266 x
= (fOffset
* fZoom
) + ((CurSprite()->w
* fZoom
) / 2) - (tew
/ 2);
267 y
= (fOffset
* fZoom
) + (CurSprite()->h
* fZoom
) + 8;
269 dc
->DrawText(wxstr
, x
, y
);
273 void c------------------------------() {}
276 // converts from e.g. mouse coords on the window to sprite coords on the (zoomed) sprite
277 void EditArea::PixelToSpriteCoords(int x
, int y
, int *x_inout
, int *y_inout
)
279 x
-= (fOffset
* fZoom
);
280 y
-= (fOffset
* fZoom
);
281 if (x
< 0) x
-= fZoom
;
282 if (y
< 0) y
-= fZoom
;
286 if (x_inout
) *x_inout
= x
;
287 if (y_inout
) *y_inout
= y
;
290 // converts from sprite coords to actual window coordinates relative to the editarea
291 // returns the upper-left corner of the enlarged pixel.
292 void EditArea::SpriteToPixelCoords(int x
, int y
, int *x_inout
, int *y_inout
)
296 x
+= (fOffset
* fZoom
);
297 y
+= (fOffset
* fZoom
);
299 if (x_inout
) *x_inout
= x
;
300 if (y_inout
) *y_inout
= y
;
304 void c------------------------------() {}
307 // returns a pointer the bbox which is currently being edited, based on the edit mode, or NULL.
308 SIFRect
*EditArea::GetCurrentBBox()
312 case EM_BBOX
: return &CurSprite()->bbox
;
313 case EM_SOLIDBOX
: return &CurSprite()->solidbox
;
314 case EM_PFBOX
: return &CurDir()->pf_bbox
;
320 // returns a pointer to the first point in the pointlist (or single point in some modes)
321 // which is currently being edited, and the number of points, based on the edit mode, or NULL.
322 SIFPoint
*EditArea::GetCurrentPointList(int *count_out
, SIFPointList
**outerstruct
)
325 SIFPointList
*dummy2
;
326 if (!count_out
) count_out
= &dummy1
;
327 if (!outerstruct
) outerstruct
= &dummy2
;
334 *outerstruct
= &CurSprite()->block_l
;
338 *outerstruct
= &CurSprite()->block_r
;
342 *outerstruct
= &CurSprite()->block_u
;
346 *outerstruct
= &CurSprite()->block_d
;
349 case EM_SPAWNPT
: *count_out
= 1; return &CurSprite()->spawn_point
;
351 case EM_ACTIONPT
: *count_out
= 1; return &CurDir()->actionpoint
;
352 case EM_ACTIONPT2
: *count_out
= 1; return &CurDir()->actionpoint2
;
353 case EM_DRAWPT
: *count_out
= 1; return &CurDir()->drawpoint
;
356 if (outerstruct
&& *outerstruct
)
358 *count_out
= (*outerstruct
)->count
;
359 return &((*outerstruct
)->point
[0]);
366 void c------------------------------() {}
369 void EditArea::OnMouseDown(wxMouseEvent
&event
)
371 fShift
.buttondown
= event
.m_leftDown
;
372 if (fShift
.mode
) return;
375 PixelToSpriteCoords(event
.m_x
, event
.m_y
, &x
, &y
);
377 int button
= event
.m_leftDown
? LEFT
: RIGHT
;
379 // begin drag if allowed
380 SIFRect
*bbox
= GetCurrentBBox();
383 HandleBeginDrag(event
, button
);
385 else // else maybe they're trying to add/remove a point
387 HandlePointEdit(x
, y
, button
);
392 void EditArea::OnMouseMove(wxMouseEvent
&event
)
396 HandleShiftMode(event
.m_x
, event
.m_y
);
402 OfferAppropriateDragCursor(event
.m_x
, event
.m_y
);
406 SetCursorForDragMode(fDrag
.mode
);
407 if (!fDrag
.mouse_moved
)
409 if (event
.m_x
!= fDrag
.orig_px
|| event
.m_y
!= fDrag
.orig_py
)
411 fDrag
.mouse_moved
= true;
416 PixelToSpriteCoords(event
.m_x
, event
.m_y
, &x
, &y
);
418 if (x
== fDrag
.lastx
&& y
== fDrag
.lasty
)
421 // update the displayed bbox as they drag
422 if (fDrag
.mode
== DM_CREATE_NEW
)
423 DragUpdateNewBBox(x
, y
);
425 DragUpdateAdjustedBBox(x
, y
);
435 void EditArea::OnMouseUp(wxMouseEvent
&event
)
437 fShift
.buttondown
= event
.m_leftDown
;
438 if (fShift
.mode
) return;
442 // apply the new bbox
443 if (fDrag
.mouse_moved
)
445 SIFRect
*bbox
= GetCurrentBBox();
448 *bbox
= fDrag
.draggedrect
;
450 if (mainwin
->fLinkBBoxCheckbox
->GetValue() && \
451 gd
.curmode
== EM_BBOX
)
453 CurSprite()->solidbox
= fDrag
.draggedrect
;
458 fDrag
.dragging
= false;
459 SetCursor(*wxSTANDARD_CURSOR
);
463 void EditArea::OnMouseWheel(wxMouseEvent
&event
)
465 int amt
= event
.m_wheelRotation
/ event
.m_wheelDelta
;
466 if (amt
== 0) return;
469 mainwin
->UpdateDisplay();
473 void c------------------------------() {}
476 void EditArea::DragUpdateNewBBox(int x
, int y
)
479 rect
.x1
= fDrag
.anchor_x
;
480 rect
.y1
= fDrag
.anchor_y
;
484 if (rect
.x1
> rect
.x2
) SWAP(rect
.x1
, rect
.x2
);
485 if (rect
.y1
> rect
.y2
) SWAP(rect
.y1
, rect
.y2
);
487 fDrag
.draggedrect
= rect
;
490 void EditArea::DragUpdateAdjustedBBox(int x
, int y
)
492 // get distance from anchor
493 int distx
= (x
- fDrag
.anchor_x
);
494 int disty
= (y
- fDrag
.anchor_y
);
496 SIFRect rect
= fDrag
.origrect
;
498 if (fDrag
.mode
& DM_ADJUST_X1
) rect
.x1
+= distx
;
499 if (fDrag
.mode
& DM_ADJUST_X2
) rect
.x2
+= distx
;
500 if (fDrag
.mode
& DM_ADJUST_Y1
) rect
.y1
+= disty
;
501 if (fDrag
.mode
& DM_ADJUST_Y2
) rect
.y2
+= disty
;
503 fDrag
.draggedrect
= rect
;
507 // returns which drag mode would be used if you pressed the left button
508 // right now at (unzoomed) pixel position x, y.
509 int EditArea::SelectDragMode(int px
, int py
)
514 if (!(bbox
= GetCurrentBBox()))
515 return DM_CREATE_NEW
; // not in bbox-edit mode, so always use standard cursor
522 // zoom the bbox's coords to get it's real, zoomed, coords on the screen
523 SpriteToPixelCoords(x1
, y1
, &x1
, &y1
);
524 SpriteToPixelCoords(x2
, y2
, &x2
, &y2
);
525 x2
+= (fZoom
- 1); // get lower-left corner
526 y2
+= (fZoom
- 1); // instead of upper-left
528 // find out whether we are closest to the left, right, top or bottom edge of the bbox.
535 if (py
>= y1
&& py
<= y2
)
537 if ((nc
= abs(px
- x1
)) < xclosest
) { xclosest
= nc
; xwinner
= DM_ADJUST_X1
; }
538 if ((nc
= abs(px
- x2
)) < xclosest
) { xclosest
= nc
; xwinner
= DM_ADJUST_X2
; }
541 if (px
>= x1
&& px
<= x2
)
543 if ((nc
= abs(py
- y1
)) < yclosest
) { yclosest
= nc
; ywinner
= DM_ADJUST_Y1
; }
544 if ((nc
= abs(py
- y2
)) < yclosest
) { yclosest
= nc
; ywinner
= DM_ADJUST_Y2
; }
547 // check if we're close enough to count
550 int result
= 0; // equivalent to DM_CREATE_NEW
551 if (xclosest
<= CLOSE_DIST
) result
|= xwinner
;
552 if (yclosest
<= CLOSE_DIST
) result
|= ywinner
;
555 if (result
== 0 && px
>= x1
&& px
<= x2
&& py
>= y1
&& py
<= y2
)
556 result
= (DM_ADJUST_X1
| DM_ADJUST_X2
| DM_ADJUST_Y1
| DM_ADJUST_Y2
);
561 // called from OnMouseMove, if they are close to one of the sides of
562 // the bbox it sets the mouse cursor to a sizing cursor to offer to drag that side.
563 void EditArea::OfferAppropriateDragCursor(int px
, int py
)
565 int dm
= DM_CREATE_NEW
;
568 dm
= SelectDragMode(px
, py
);
570 SetCursorForDragMode(dm
);
573 // sets the cursor to that used when doing or offering the given drag mode
574 void EditArea::SetCursorForDragMode(int mode
)
579 case DM_ADJUST_X2
: SetCursor(wxCursor(wxCURSOR_SIZEWE
)); return;
582 case DM_ADJUST_Y2
: SetCursor(wxCursor(wxCURSOR_SIZENS
)); return;
584 case DM_ADJUST_X1
| DM_ADJUST_Y1
:
585 case DM_ADJUST_X2
| DM_ADJUST_Y2
:
586 SetCursor(wxCursor(wxCURSOR_SIZENWSE
));
589 case DM_ADJUST_X2
| DM_ADJUST_Y1
:
590 case DM_ADJUST_X1
| DM_ADJUST_Y2
:
591 SetCursor(wxCursor(wxCURSOR_SIZENESW
));
594 case DM_ADJUST_X1
| DM_ADJUST_X2
| DM_ADJUST_Y1
| DM_ADJUST_Y2
:
596 // don't OFFER it, only set it if we're doing it now via right mouse button
599 SetCursor(wxCursor(wxCURSOR_SIZING
));
606 SetCursor(*wxSTANDARD_CURSOR
);
610 void c------------------------------() {}
613 void EditArea::HandleBeginDrag(wxMouseEvent
&event
, int button
)
617 SIFRect
*bbox
= GetCurrentBBox();
620 PixelToSpriteCoords(event
.m_x
, event
.m_y
, &x
, &y
);
622 fDrag
.mode
= SelectDragMode(event
.m_x
, event
.m_y
);
623 if (fDrag
.mode
== (DM_ADJUST_X1
| DM_ADJUST_Y1
| DM_ADJUST_X2
| DM_ADJUST_Y2
))
626 fDrag
.mode
= DM_CREATE_NEW
;
629 fDrag
.origrect
= *bbox
;
632 fDrag
.dragging
= true;
634 fDrag
.orig_px
= event
.m_x
;
635 fDrag
.orig_py
= event
.m_y
;
636 fDrag
.mouse_moved
= false;
644 void EditArea::HandlePointEdit(int x
, int y
, int button
)
650 stat("HandlePointEdit mouse click at %d,%d btn %d", x
, y
, button
);
652 point
= GetCurrentPointList(&npoints
, &list
);
656 { // dealing with a list, such as blockl/r/u/d
658 // delete any point currently at this position
659 // for RIGHT this is the action requested
660 // for LEFT it prevents adding more than one block point in the same spot
661 SIFPointList newlist
;
663 for(int i
=0;i
<npoints
;i
++)
665 if (list
->point
[i
].x
!= x
|| list
->point
[i
].y
!= y
)
667 newlist
.point
[newlist
.count
].x
= list
->point
[i
].x
;
668 newlist
.point
[newlist
.count
].y
= list
->point
[i
].y
;
676 if (list
->count
< SIF_MAX_BLOCK_POINTS
)
678 list
->point
[list
->count
].x
= x
;
679 list
->point
[list
->count
].y
= y
;
686 { // dealing with a single point, such as spawn_point
687 if (button
== RIGHT
) return;
693 mainwin
->UpdateTitle();
697 void c------------------------------() {}
700 void EditArea::UpdateCtrlShiftStates()
702 int oldShiftMode
= fShift
.mode
;
703 fShift
.mode
= SM_NO_SHIFT
;
707 fShift
.mode
= (!gd
.shift
) ? SM_SHEET_OFFSET
: SM_OFFSET_ALL
;
711 fShift
.mode
= SM_SIZE
;
714 UpdateShiftStatusText();
716 if (fShift
.mode
!= oldShiftMode
)
720 fDrag
.dragging
= false;
721 fShift
.havefirst
= false;
722 fShift
.buttondown
= false;
723 fShift
.totaldx
= fShift
.totaldy
= 0;
725 fShift
.expand_bbox
= CurSprite()->bbox
.equ(0, 0, CurSprite()->w
-1, CurSprite()->h
-1);
726 fShift
.expand_solidbox
= CurSprite()->solidbox
.equ(0, 0, CurSprite()->w
-1, CurSprite()->h
-1);
728 SetCursor(wxCursor(wxCURSOR_SIZING
));
732 SetCursor(*wxSTANDARD_CURSOR
);
739 void EditArea::HandleShiftMode(int px
, int py
)
741 SetCursor(wxCursor(wxCURSOR_SIZING
));
743 if (!fShift
.buttondown
)
745 fShift
.havefirst
= false;
749 if (!fShift
.havefirst
)
753 fShift
.totaldx
= fShift
.totaldy
= 0;
754 fShift
.havefirst
= true;
755 stat("HandleShiftMode(%d, %d): Took first.", px
, py
);
759 const int SENSITIVITY
= 2;
760 int deltax
= (px
- fShift
.lastpx
) / SENSITIVITY
;
761 int deltay
= (py
- fShift
.lastpy
) / SENSITIVITY
;
763 SpriteRecord
*sprite
= CurSprite();
764 SIFDir
*dir
= CurDir();
773 if (sprite
->w
< 1) sprite
->w
= 1;
774 if (sprite
->w
> 255) sprite
->w
= 255;
778 case SM_SHEET_OFFSET
:
780 dir
->sheet_offset
.x
+= deltax
;
781 if (dir
->sheet_offset
.x
< 0) dir
->sheet_offset
.x
= 0;
787 OffsetAllFrames(deltax
, 0);
802 if (sprite
->h
< 1) sprite
->h
= 1;
803 if (sprite
->h
> 255) sprite
->h
= 255;
807 case SM_SHEET_OFFSET
:
809 dir
->sheet_offset
.y
+= deltay
;
810 if (dir
->sheet_offset
.y
< 0) dir
->sheet_offset
.y
= 0;
816 OffsetAllFrames(0, deltay
);
824 if (deltax
|| deltay
)
826 if (fShift
.mode
== SM_SIZE
)
828 if (fShift
.expand_bbox
)
829 CurSprite()->bbox
.set(0, 0, CurSprite()->w
-1, CurSprite()->h
-1);
831 if (fShift
.expand_solidbox
)
832 CurSprite()->solidbox
.set(0, 0, CurSprite()->w
-1, CurSprite()->h
-1);
835 fShift
.totaldx
+= deltax
;
836 fShift
.totaldy
+= deltay
;
838 mainwin
->UpdateDisplay();
839 UpdateShiftStatusText();
843 void EditArea::UpdateShiftStatusText()
845 char *status
= "Press CTRL=Sheet Offset, Shift=Size, CTRL+Shift=Offset All";
849 case SM_SHEET_OFFSET
:
850 status
= stprintf("Adjusting sheet offset: [%d, %d]",
851 CurDir()->sheet_offset
.x
, CurDir()->sheet_offset
.y
);
855 status
= "Adjusting sheet offset of ALL frames in current sprite...drag!";
859 status
= stprintf("Sizing current sprite: %dx%d",
860 CurSprite()->w
, CurSprite()->h
);
864 mainwin
->SetStatusText(wxString(status
, wxConvUTF8
));
868 void EditArea::OffsetAllFrames(int dx
, int dy
)
870 SpriteRecord
*sprite
= CurSprite();
871 int nframes
= CurFrameCount();
873 for(int i
=0;i
<nframes
;i
++)
875 sprite
->frame
[i
].dir
[gd
.curdir
].sheet_offset
.x
+= dx
;
876 sprite
->frame
[i
].dir
[gd
.curdir
].sheet_offset
.y
+= dy
;
881 void c------------------------------() {}
884 bool EditArea::CreateZoomedSprite()
886 delete fZoomedSprite
;
887 fZoomedSprite
= NULL
;
889 // cut out a wximage from the spritesheet containing just the sprite we are interested in
890 wxImage
*sprite
= sheetmgr
.GetSprite(gd
.cursprite
, gd
.curframe
, gd
.curdir
);
893 staterr("CreateZoomedSprite: failed to GetSprite()");
897 // add alpha to the sprite by setting all black pixels to transparent
898 int alphasize
= (sprite
->GetWidth() * sprite
->GetHeight());
899 uint8_t *alpha
= (uint8_t *)malloc(alphasize
);
900 uint8_t *data
= sprite
->GetData();
902 for(i
=j
=0;i
<alphasize
;i
++)
904 if (data
[j
] == 0 && data
[j
+1] == 0 && data
[j
+2] == 0)
916 sprite
->SetAlpha(alpha
);
918 // zoom the sprite to the desired size
919 int zoomw
= CurSprite()->w
* fZoom
;
920 int zoomh
= CurSprite()->h
* fZoom
;
921 sprite
->Rescale(zoomw
, zoomh
);
923 // create a temporary offscreen memory DC of the appropriate size
924 wxBitmap
membmp(zoomw
, zoomh
);
925 wxMemoryDC
memdc(membmp
);
927 // blit the background and sprite into the memory DC
928 FillBackground(&memdc
);
929 memdc
.DrawBitmap(wxBitmap(*sprite
), 0, 0);
931 // obtain the image from the bitmap associated with the memory DC
932 fZoomedSprite
= new wxImage(membmp
.ConvertToImage());
934 fZoomedSpriteSettings
= GetZoomedSpriteSettings();
939 ZoomedSpriteSettings
EditArea::GetZoomedSpriteSettings()
941 ZoomedSpriteSettings set
;
944 set
.sheet_x
= CurDir()->sheet_offset
.x
;
945 set
.sheet_y
= CurDir()->sheet_offset
.y
;
946 set
.sheetno
= CurSprite()->spritesheet
;
947 set
.w
= CurSprite()->w
;
948 set
.h
= CurSprite()->h
;
953 bool ZoomedSpriteSettings::equ(ZoomedSpriteSettings other
)
955 if (sheet_x
!= other
.sheet_x
) return false;
956 if (sheet_y
!= other
.sheet_y
) return false;
957 if (w
!= other
.w
) return false;
958 if (h
!= other
.h
) return false;
959 if (sheetno
!= other
.sheetno
) return false;
960 if (zoom
!= other
.zoom
) return false;
966 void c------------------------------() {}
969 void EditArea::FillBackground(wxDC
*dc
)
971 if (!fBackground
) return;
972 wxBitmap
bg(*fBackground
);
974 int w
= dc
->GetSize().GetWidth();
975 int h
= dc
->GetSize().GetHeight();
977 for(int y
=0;y
<h
;y
+=bg
.GetWidth())
978 for(int x
=0;x
<w
;x
+=bg
.GetHeight())
980 dc
->DrawBitmap(bg
, x
, y
);
984 void EditArea::RefreshNow()