I never coded something like that but I have some ideas.
1. Saving the data to temporary files, the simplest way but the most ressource wasting.
2. Macro based. (look at History window in Adobe Photoshop) You must firsd define few basic types of actions that can be done, I will use 3 (set pixel, Resize X, Resize Y). Those info must be stored in an array (so there can be many of them and will automaticly have a unique ID), you also need a "curentg position" index to know how many of Undo/Redo the user have alraedy used [code] ' Use it for boolean operations const true = -1 const false = 0
TYPE undMacroType Used As Integer ' Tell that this item is used, I use that type of information ' very often because it's very useful for advanced manipulations. ' In an advanced sprite edit it would be useful to have ' an option to delete some Undo info without deleting others Mode As Integer ' The type of action that was done END TYPE
Now you need to store informations about each of the macro. First (the simpler one) the SetPixel macro: [code] TYPE SetPixelInfoType Used As Integer Owner As Integer ' the owner macro ID coordX As Integer coordY As Integer OldColor As Integer ' The color that was previously on that location NewColor As Integer ' The new color END TYPE [/code] So far it was very easy, Now the Resize infos (I'm using it only to show you how to add more complicated actions to Undo and Redo). You can use type for that action without stupidly loosing memory because QB45, QB7.1 and VBDOS does not allow use of Dynamic arrays in TYPE structures. [code] REM Use the following line to enable dynamic arrays without the use of COMMON declaration REM $DYNAMIC DIM SHARED macResize_Used() As Integer DIM SHARED macResize_Owner() As Integer DIM SHARED macResize_Type() As Integer const resize_type_Xp=0, resize_type_Xm = 1 const resize_type_Yp=2, resize_type_Ym = 3 DIM SHARED macResize_Width As Integer DIM SHARED macResize_Height As Integer DIM SHARED macResize_Pic() As Integer ' The pixel colors that was added ' The 'p' after X or Y means that the field was enlarge by Resize_Width/Height ' and the 'm' means that the size was decrement by Width/Height [/code] Remember that after an undo if an action is made you must destroy all avaible REDOs.
Now you must declare an array for undMacroType and SetPixelInfoType [code] DIM SHARED Macros() As undMacroType DIM SHARED macSetPixel() As SetPixelInfoType [/code]
You need a routine that will allocate new macros [code] Function AddUndo() as integer MacPos = MacPos + 1 ' It will destroy all avaible REDOs, but you should change it so it ' to destroy all it's informations held somwhare else redim preserve Macros(MacPos) As undMacroType AddUndo = MacPos ' returns the ID End function [/code]
I'm too tired to continue it today, it's 04:20 a.m. in Poland. I will finish it tomarow
Ok I have some time now to finish it since my Girlfriend is mad at me.
Now the function SetPixel which is the base of all graphical operations: [code] ' Image is an array of your picture data SUB SetPixel(x, y, col, mspi) dim oldcol As integer
oldcol = Image(x,y) Image(x,y) = col macSetPixel(mspi).Used = true macSetPixel(mspi).CoordX = x macSetPixel(mspi).CoordY = y macSetPixel(mspi).OldCol = oldcol macSetPixel(mspi).NewCol = col
Comments
1. Saving the data to temporary files, the simplest way but the most ressource wasting.
2. Macro based. (look at History window in Adobe Photoshop)
You must firsd define few basic types of actions that can be done, I will use 3 (set pixel, Resize X, Resize Y). Those info must be stored in an array (so there can be many of them and will automaticly have a unique ID), you also need a "curentg position" index to know how many of Undo/Redo the user have alraedy used
[code]
' Use it for boolean operations
const true = -1
const false = 0
TYPE undMacroType
Used As Integer ' Tell that this item is used, I use that type of information
' very often because it's very useful for advanced manipulations.
' In an advanced sprite edit it would be useful to have
' an option to delete some Undo info without deleting others
Mode As Integer ' The type of action that was done
END TYPE
const mode_SetPixel = 0, mode_ResizeX = 1, mode_ResizeY = 2
dim shared MacPos As Integer
[/code]
Now you need to store informations about each of the macro. First (the simpler one) the SetPixel macro:
[code]
TYPE SetPixelInfoType
Used As Integer
Owner As Integer ' the owner macro ID
coordX As Integer
coordY As Integer
OldColor As Integer ' The color that was previously on that location
NewColor As Integer ' The new color
END TYPE
[/code]
So far it was very easy, Now the Resize infos (I'm using it only to show you how to add more complicated actions to Undo and Redo).
You can use type for that action without stupidly loosing memory because QB45, QB7.1 and VBDOS does not allow use of Dynamic arrays in TYPE structures.
[code]
REM Use the following line to enable dynamic arrays without the use of COMMON declaration
REM $DYNAMIC
DIM SHARED macResize_Used() As Integer
DIM SHARED macResize_Owner() As Integer
DIM SHARED macResize_Type() As Integer
const resize_type_Xp=0, resize_type_Xm = 1
const resize_type_Yp=2, resize_type_Ym = 3
DIM SHARED macResize_Width As Integer
DIM SHARED macResize_Height As Integer
DIM SHARED macResize_Pic() As Integer ' The pixel colors that was added
' The 'p' after X or Y means that the field was enlarge by Resize_Width/Height
' and the 'm' means that the size was decrement by Width/Height
[/code]
Remember that after an undo if an action is made you must destroy all avaible REDOs.
Now you must declare an array for undMacroType and SetPixelInfoType
[code]
DIM SHARED Macros() As undMacroType
DIM SHARED macSetPixel() As SetPixelInfoType
[/code]
You need a routine that will allocate new macros
[code]
Function AddUndo() as integer
MacPos = MacPos + 1
' It will destroy all avaible REDOs, but you should change it so it
' to destroy all it's informations held somwhare else
redim preserve Macros(MacPos) As undMacroType
AddUndo = MacPos ' returns the ID
End function
[/code]
I'm too tired to continue it today, it's 04:20 a.m. in Poland. I will finish it tomarow
Now the function SetPixel which is the base of all graphical operations:
[code]
' Image is an array of your picture data
SUB SetPixel(x, y, col, mspi)
dim oldcol As integer
oldcol = Image(x,y)
Image(x,y) = col
macSetPixel(mspi).Used = true
macSetPixel(mspi).CoordX = x
macSetPixel(mspi).CoordY = y
macSetPixel(mspi).OldCol = oldcol
macSetPixel(mspi).NewCol = col
END SUB
[/code]
That's all for today