News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

DrawPicture

Started by TomRiddle, February 21, 2007, 12:15:16 PM

Previous topic - Next topic

TomRiddle

The Goal: Draw a Picture at coordinates, with an independent Width/Height, using XMin/XMax and YMin/YMax as the screen.

The idea, a DrawPicture Macro/Procedure that can draw a picture in any screen mode(or even on a flat surface).

I wrote it in QBasic for ease, now just need to convert it to assembly!

Lets look at the Inner Loop :)
FOR Y = 0 TO YLen
  FOR X = 0 TO XLen
   POKE ViewStart, C(DataStart)
   ViewStart = ViewStart + 1
   DataStart = DataStart + 1
  NEXT X
  ViewStart = ViewStart + ViewChange
  DataStart = DataStart + DataChange
NEXT Y

Hmm, the For Loops will be the hardest, considering everything else is either a Inc/Mov/Add
The next hard part will be using Signed Numbers(I don't use them very often).

Ohh well, back to the labratory.

Still Needs:
Bits Per Pixel Calculations, right now its "flat 256", so it can only use 8-bit color modes.
Scaling/Rotating would be nice.

DECLARE SUB DrawPicture (XStart%, YStart%, XLen%, YLen%, XMin%, YMin%, XMax%, YMax%)

DEFINT A-Z

' 8x8 Picture
'DIM SHARED C(0 TO 63) AS INTEGER
'DATA 1,1,1,1,1,1,1,1
'DATA 1,2,2,0,0,2,2,1
'DATA 1,2,2,0,0,2,2,1
'DATA 1,0,0,4,4,0,0,1
'DATA 1,0,0,4,4,0,0,1
'DATA 1,2,2,0,0,2,2,1
'DATA 1,2,2,0,0,2,2,1
'DATA 1,1,1,1,1,1,1,1
'FOR Temp = 0 TO 63: READ C(Temp): NEXT Temp

' 320x2 Picture
DIM SHARED C(0 TO 639)
FOR Temp = 0 TO 639: C(Temp) = 4: NEXT Temp
C(0) = 15
C(319) = 15
C(320) = 14
C(639) = 14

' Set Screen/Set Segment/Draw Picture
SCREEN 13
DEF SEG = 40960

' 8x8 Picture
'DrawPicture -1, -1, 7, 7, 0, 0, 319, 199
'DrawPicture 313, -1, 7, 7, 0, 0, 319, 199
'DrawPicture -1, 193, 7, 7, 0, 0, 319, 199
'DrawPicture 313, 193, 7, 7, 0, 0, 319, 199

' 321x1 Picture
DrawPicture 319, -1, 319, 1, 0, 0, 319, 199

DO: LOOP WHILE INKEY$ <> CHR$(27)

SUB DrawPicture (XStart, YStart, W, H, XMin, YMin, XMax, YMax)
' Right Now, all Longs
DIM DataStart AS LONG
DIM DataChange AS LONG
DIM ViewStart AS LONG
DIM ViewChange AS LONG

IF XStart + W < XMin OR XStart > XMax OR YStart + H < YMin OR YStart > YMax THEN EXIT SUB

DataStart = 0
DataChange = 0
ViewChange = 0

IF XStart < XMin THEN
  XLen = W - ABS(XStart)
  DataStart = ABS(XStart)
  DataChange = ABS(XStart)
  ViewStart = XMin
  ViewChange = XMax - W + ABS(XStart)
ELSE
  ViewStart = XStart
  IF XStart + W > XMax THEN
   XLen = XMax - XStart
   DataChange = W - XLen
   ViewChange = XStart
  ELSE
   XLen = W
  END IF
END IF

IF YStart < YMin THEN
  YLen = H - ABS(YStart)
  DataStart = DataStart + ((W + 1) * ABS(YStart))
ELSE
  ViewStart = ViewStart + (ABS(YStart) * (XMax + 1&))
  IF YStart + H > YMax THEN
   YLen = YMax - YStart
  ELSE
   YLen = H
  END IF
END IF

FOR Y = 0 TO YLen
  FOR X = 0 TO XLen
   POKE ViewStart, C(DataStart)
   ViewStart = ViewStart + 1
   DataStart = DataStart + 1
  NEXT X
  ViewStart = ViewStart + ViewChange
  DataStart = DataStart + DataChange
NEXT Y
END SUB


I just counted them btw, 8 separate values in the Loop:
Y(Ax), YLen(Cx), X(Bx), XLen(Dx), ViewStart(Es:Di), DataStart(Ds:Si), ViewChange, DataChange

Need 2 more...

Ohh well, tell me what you guys think! :D

TomRiddle

It's not great, but it somewhat works.  :'(

Ohh, and NO, it's not Masm32 compatible.  The code is pretty self-explanitory though.

VideoDrawPicture Macro Picture, XStart, YStart, W, H, XMin, YMin, XMax, YMax
;Local L_LeftChange, L_RightChange, L_NoXChange, L_FinishXChange, L_BottomChange, L_TopChange, L_FinishYChange, L_NoYChange, LoopY, LoopX, L_Exit
  ; Ds:Si = Picture/DataStart, Es:Di = Screen/ViewStart
  MoveSegOff Picture,Ds,Si,Ax
  MoveSR Es,Ax,0A000h

  ; XStart > XMax, XStart + W < XMin, YStart > YMax, YStart + H < YMin
  Move Ax, XStart
  CompareAndJumpIfGreater Ax, XMax, L_Exit
  Addition Ax, W
  CompareAndJumpIfLess Ax, XMin, L_Exit
  Move Ax, YStart
  CompareAndJumpIfGreater Ax, YMax, L_Exit
  Addition Ax, H
  CompareAndJumpIfLess Ax, YMin, L_Exit

; If XStart < XMin Then Goto L_LeftChange
Move Ax, XStart
CompareAndJumpIfLess Ax, XMin, L_LeftChange
; Else
; ViewStart = XStart
Move Di, XStart
; If XStart + W > XMax Then Goto L_RightChange Else Goto L_NoXChange
Addition Ax, W
CompareAndJumpIfGreaterElseJump Ax, XMax, L_RightChange, L_NoXChange
L_LeftChange:
  ; DataStart = ABS(XStart)
  Move Ax, XStart
  TestAndJumpIfZero Ax, 1000000000000000b, L_NoLeftChange
   Not Ax
   Increase Ax
  L_NoLeftChange:
  Move Si, Ax
  ; DataChange = ABS(XStart)
  PushWord Ax
  ; ViewChange = XMax - W + ABS(XStart)
  Addition Ax, W
  Move Dx, XMax
  Subtraction Dx, Ax
  PushWord Dx
  ; XLen = W - ABS(XStart)
  Move Cx, W
  Subtraction Cx, Ax
  PushWord Cx
  ; ViewStart = XMin
  Move Di, XMin
  Jump L_FinishXChange
L_RightChange:
  ; XLen = XMax - XStart
  Move Cx, XMax
  Subtraction Cx, XStart
  ; DataChange = W - XLen
  Move Bx, W
  Subtraction Bx, Cx
  PushWord Bx
  ; ViewChange = XStart
  Move Ax, XStart
  PushWord Ax, Cx
  Jump L_FinishXChange
L_NoXChange:
  ; XLen = W
  MoveZero Ax
  Move Bx,W, Cx, XMax-W
  PushWord Ax, Cx, Bx
L_FinishXChange:

; If YStart < YMin Then L_TopChange
Move Ax, YStart
CompareAndJumpIfLess Ax, YMin, L_TopChange
; ViewStart = ViewStart + (ABS(YStart) * (XMax + 1&))
Move Ax, YStart
TestAndJumpIfZero Ax, 1000000000000000b, L_NoRegYChange
  Not Ax
  Increase Ax
L_NoRegYChange:
Move Dx, XMax
Increase Dx
IMul Dx
Addition Di, Ax
; If YStart + H > YMax Then Goto L_BottomChange
Move Ax, YStart
Addition Ax, H
CompareAndJumpIfGreater Ax, YMax, L_BottomChange
; Else
; YLen = H
Move Ax, H
PushWord Ax
Jump L_FinishYChange
L_BottomChange:
  ; YLen = YMax - YStart
  Move Ax, YMax
  Subtraction Ax, YStart
  PushWord Ax
  Jump L_FinishYChange
L_TopChange:
  ; YLen = H - ABS(YStart)
  Move Ax, YStart
  TestAndJumpIfZero Ax, 1000000000000000b, L_NoTopChange
   Not Ax
   Increase Ax
  L_NoTopChange:
  Move Dx, Ax
  Subtraction Ax, H
  PushWord Ax
  ; DataStart = DataStart + ((W + 1) * ABS(YStart))
  Move Ax, W
  Increase Ax
  IMul Dx
  Addition Si, Ax
L_FinishYChange:
; The Stack
;  DataChange
;  ViewChange
;  XLen
;  YLen
; Data
;  Si, Di

PopWord Dx, Cx
Increase Dx, Cx
MoveZero Bx, Ax

LoopY:
LoopX:
  PushWord Ax
  Move Al,Ds:[Si], Es:[Di],Al
  PopWord Ax
  Increase Di, Si, Ax
  CompareAndJumpIfNotEqual Ax, Cx, LoopX
PopWord Ax, Bp
Addition Di,Ax, Si,Bp
PushWord Bp, Ax
MoveZero Ax
Increase Bx
CompareAndJumpIfNotEqual Bx, Dx, LoopY

L_Exit:
EndM