Other Programming Languages
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me
Go Back   Dev Shed ForumsProgramming Languages - MoreOther Programming Languages

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
Stay one step ahead of the competition. Evaluate and give feedback on some of the hottest web development tools on the market today. Make your opinion heard! Click Here
  #1  
Old April 1st, 2008, 12:25 AM
Treymac Treymac is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2007
Posts: 27 Treymac User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 h 32 m 22 sec
Reputation Power: 0
Drawing a square

Hey guys. I'm DOS programming in 16-bit, using INT 10H.

So I know how to create a line, basically by drawing a pixel, and creating a loop to continue drawing pixels beside each other. But I don't know how to create a square. Does anybody have any ideas how I could create a square?

I could create a procedure to repeat the code that draws a line, to produce a bunch of lines that are on top of each other, which would look like a square. I don't think this is the most efficient way, and could cause me more problems down the road as I try to move the square around the screen.

Anyways, any help would be really appreciated. Thanks.

Last edited by Treymac : April 1st, 2008 at 12:25 AM. Reason: typo

Reply With Quote
  #2  
Old April 24th, 2008, 01:52 PM
SimonB2 SimonB2 is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Apr 2008
Posts: 7 SimonB2 Negative: is most likely a SPAMMER and a traitor to the cause. 
Time spent in forums: 3 h 47 m 58 sec
Reputation Power: 0
Thumbs up

G'day.

That is how you do it, just be sure to use a function that only draws horizontal lines, as opposed to a generic line algo.

The optimizations available depend on the language you're using and the screen mode you're in.

If you're using mode 0x13h (320x200x256 cols) and doing it in assembly I've got some routines that are fairly speedy. Part of the trick is to write to the screen memory directly, and in a loop - as opposed to calling a Pixel function.

as an (ashamedly, rather rough) example, to draw a square that's 4x4 in the top left corner of the screen, using color 10d:

Code:
; To assemble and link from within WinAsm Studio, you must have a special 16-bit linker, 
; such as the one in the archive at this URL- http://win32assembly.online.fr/files/Lnk563.exe
; Run the archive to unpack Link.exe, rename the Link.exe file to Link16.exe and copy it
; into the \masm32\bin folder.
;
; To produce a .COM file, .model must be tiny, also you must add /tiny to the linker command line

.model tiny
.data
      
.code
	.startup
	mov ax, 013h		; SetVidMode(0x13)
	int     010h

	mov ax, 0A000h		;segment of screen mem for this mode (and some others)
	mov ds, ax
	xor si, si		; point to pixel 0,0
	mov ax, 0A0Ah		; 10d, 10d
	mov cx, 4		; want to do a 4 pixel side-length  square
	mov bx, 2		; doing two pixels at once, need to move SI forwards by 2 each time 
lineloop:
	mov ds:[si], ax
	add si, bx
	mov ds:[si], ax		; look ma! two pixels at once (we can do more)
	add si, 318
	dec cx			; decrement our loop counter
	jnz lineloop		; and go back for more, while loop counter <> 0
	
	mov   ah,0		; getch()
	int   16h

	mov ax, 03h		; SetVidMode(0x03)
	int     010h

	.exit
end


Another tip worth pointing out is that bit-shift operations were quicker than multiply instructions last time I looked.

So, assuming you were using mode 13h, if you wanted to draw a pixel at 10,30 using C you'd simply have a pointer that pointed to screen memory, and just use it like any other array
Screen[30*200 + 10] = colour;

But there's a quicker way than 30*200.
It's 30*8 + 30*64 + 30*128. Now, while that may seem like a contradiction, 8, 64 and 128 are all powers of 2, so you can use the bit shift operations to calculate them.
e.g
offset = 30<<3 + 30<<6 + 30<<7;
[EDIT]
should have been:
offset = (30<<3 + 30<<6 + 30<<7) + 10;
[/EDIT]

For clarity's sake I've done the full shift each time, but using the registers, you can simply accumulate the previous result.
This is also unoptimized, for clarity's sake.

e.g
Code:
	mov	ax, 30		; we want to draw on line 30
	shl	ax, 3		; ax = 8*30
	mov	bx, ax		; bx = 8*30
	shl	ax, 3		; ax = 64*30
	add	bx, ax		; bx = 8*30 + 64*30
	shl	ax, 1		; ax = 128*30
	add	bx, ax		; bx = 8*30 + 64*30 + 128*30 
	mov	si, bx		; si = 8*30 + 64*30 + 128*30  ----> 200 * 30
[EDIT - I forgot]
	mov	ax, 10
	add	si, ax
[/EDIT]

It's more instructions than a simple MUL, but with pipelining taken into account you can run several of them per clock cycle. When I was last playing with ASM (486 era) A mul took many more cycles than that little snippet. Once you've got your index into the array that's screen memory, all you have to do is write a byte to ds:[si], then increment si to point at the next pixel. MUCH quicker than going through the whole operation of calculating an offset for each pixel.

Last edited by SimonB2 : April 25th, 2008 at 05:33 AM. Reason: missed a couple of instructions

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming Languages - MoreOther Programming Languages > Drawing a square


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump


Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 





© 2003-2008 by Developer Shed. All rights reserved. DS Cluster 6 hosted by Hostway