Board index » delphi » FillChar every OTHER char?

FillChar every OTHER char?

Ok, I have something similar to:

type tscreen = array[1..4000] of byte;
var screen: tscreen absolute $B800:$0000; {for color monitors}

I have a procedure that needs to be performed as fast as possible. It
reads a section of a buffer assigns each char to a position in
[var] screen. (I have to go char by char in a loop because it checks
if the position is over 80 columns on the screen, or a CR.) At the
moment, my routine is fairly fast, but I could make it faster if it
didn't have to also assign an attribute to each char in the loop. What
I was thinking was to eliminate that color assignment and just do a
fillchar in the beginning of the routine to make all of the chars on
the screen a certain attribute. Only problem is that [for example] if
I would make everything color 1 with fillchar, there would also be a
bunch of #1's on the screen.

What I would want to do is to fill every OTHER char with the
attribute.. only problem is I have no idea how. Any ideas would be
very much appriciated.

Also, similarly relating, is there a was to do a for loop on every
other char? like "for b := 1 to 11 by 2 do" type thing, so it would do
every other char? I can do this by something like:

var
  b: boolean:
  w: word;
begin
  b := true;
  for w := 1 to 1001 do
  begin
    if b then {do something};
    b := xor true; {toggles the boolean}
  end;
end.

..but I would think there would be a more efficient way?

Thanks in advance for any help! :)

[o------------------o]
| te...@teleport.com |
[o------------------o]

 

Re:FillChar every OTHER char?


In article <57677.te...@teleport.com>, te...@teleport.com says...

Quote

>Ok, I have something similar to:

>type tscreen = array[1..4000] of byte;
>var screen: tscreen absolute $B800:$0000; {for color monitors}

>I have a procedure that needs to be performed as fast as possible. It
>reads a section of a buffer assigns each char to a position in
>[var] screen. (I have to go char by char in a loop because it checks
>if the position is over 80 columns on the screen, or a CR.) At the
>moment, my routine is fairly fast, but I could make it faster if it
>didn't have to also assign an attribute to each char in the loop. What
>I was thinking was to eliminate that color assignment and just do a
>fillchar in the beginning of the routine to make all of the chars on
>the screen a certain attribute. Only problem is that [for example] if
>I would make everything color 1 with fillchar, there would also be a
>bunch of #1's on the screen.

>What I would want to do is to fill every OTHER char with the
>attribute.. only problem is I have no idea how. Any ideas would be
>very much appriciated.

>Also, similarly relating, is there a was to do a for loop on every
>other char? like "for b := 1 to 11 by 2 do" type thing, so it would do
>every other char? I can do this by something like:

>var
>  b: boolean:
>  w: word;
>begin
>  b := true;
>  for w := 1 to 1001 do
>  begin
>    if b then {do something};
>    b := xor true; {toggles the boolean}
>  end;
>end.

>..but I would think there would be a more efficient way?

>Thanks in advance for any help! :)

>[o------------------o]
>| te...@teleport.com |
>[o------------------o]

Try the following:

Begin
  for i := 1 to (maxnumber div 2) do
    DoSomethingWith(i*2);
End;

E. Sorensen

--
Eirik Sorensen  | Akelius AS (a Wolters Kluwer company)     | individualists,
e...@oslonett.no  | P.B. 8917 Youngstorget, 0028 OSLO, Norway | unite!

Re:FillChar every OTHER char?


In article <57677.te...@teleport.com>, "te...@teleport.com" <te...@teleport.com> writes:

Quote

> I have a procedure that needs to be performed as fast as possible. It
> reads a section of a buffer assigns each char to a position in
> [var] screen. (I have to go char by char in a loop because it checks
> if the position is over 80 columns on the screen, or a CR.) At the
> moment, my routine is fairly fast, but I could make it faster if it
> didn't have to also assign an attribute to each char in the loop. What
> I was thinking was to eliminate that color assignment and just do a
> fillchar in the beginning of the routine to make all of the chars on
> the screen a certain attribute. Only problem is that [for example] if
> I would make everything color 1 with fillchar, there would also be a
> bunch of #1's on the screen.

  That's not necessarily a problem, as you're going to overwrite those #1's
  afterwards anyway. But what you really want is to do this in assembly. It's
  fast and not very difficult.
  But I don't really understand why this has to be so fast? Usually, ordinary
  Pascal with writeln is more than fast enough for text screens.

Quote
> Also, similarly relating, is there a was to do a for loop on every
> other char? like "for b := 1 to 11 by 2 do" type thing, so it would do
> every other char?

  Well, yes:

  VAR
    Ix : byte;
  BEGIN
    Ix:=1;

    WHILE Ix<=11 DO
      Inc(Ix,2);
  END.

  --Lars M.

Re:FillChar every OTHER char?


When I had a similar problem, I would most certainly escape to some
Assembler code. The procedure you are describing is not particularly
difficult, so I think that's the best solution.
It is not uncommon to see a tenfold or more increases in speed when
implementing this in Assembler, so I think it pays off.

--
rvd...@ect.nl        
Ruud Th. van der Ham

Re:FillChar every OTHER char?


Quote
"te...@teleport.com" <te...@teleport.com> wrote:
>Ok, I have something similar to:
>type tscreen = array[1..4000] of byte;
>var screen: tscreen absolute $B800:$0000; {for color monitors}
>I have a procedure that needs to be performed as fast as possible. It
>reads a section of a buffer assigns each char to a position in
>[var] screen. (I have to go char by char in a loop because it checks
>if the position is over 80 columns on the screen, or a CR.) At the
>moment, my routine is fairly fast, but I could make it faster if it
>didn't have to also assign an attribute to each char in the loop. What
>I was thinking was to eliminate that color assignment and just do a
>fillchar in the beginning of the routine to make all of the chars on
>the screen a certain attribute. Only problem is that [for example] if
>I would make everything color 1 with fillchar, there would also be a
>bunch of #1's on the screen.
>What I would want to do is to fill every OTHER char with the
>attribute.. only problem is I have no idea how. Any ideas would be
>very much appriciated.

Other than switching to Assembly language (which someone else pointed
out), the other thing you can do is to redefine the buffer area as
another record type and let BP do the work for you.  For example:

Quote
>type tscreen = array[1..4000] of byte;
>var screen: tscreen absolute $B800:$0000; {for color monitors}

Say you have these types:

TYPE
  MyRecType = RECORD
    GoodVal : BYTE;
    IgnoreByte : BYTE;
  END;
  MyRecArrayType = ARRAY [1..2000] OF MyRecType;

In a procedure you can say:

VAR
  MyRedefinedRec : MyRecType ABSOLUTE Screen;

Then just loop through like so:

FOr I := 1 to 2000 DO
  MyRedefineRec[I] := whatever

This will do what you want.  By the way, if you speed it up more,
unroll the loop--that is, change it like this:

For I := 1 to 200 do
  MyRedefineRec[I] := ;
  MyRedefineRec[I+1] := ;
  MyRedefineRec[I+2] := ;
  MyRedefineRec[I+3] := ;
  MyRedefineRec[I+4] := ;
  ...  
  etc.  

Hope that helps.

Mark Dodrill

Re:FillChar every OTHER char?


In article <41uunr$...@gyda.ifi.uio.no> lar...@ifi.uio.no (Lars Marius Garshol) writes:
Quote
>In article <57677.te...@teleport.com>, "te...@teleport.com"

<te...@teleport.com>>writes:

Quote
>> I have a procedure that needs to be performed as fast as possible. It
>> reads a section of a buffer assigns each char to a position in
>> [var] screen. (I have to go char by char in a loop because it checks
>> if the position is over 80 columns on the screen, or a CR.) At the
>> moment, my routine is fairly fast, but I could make it faster if it
>> didn't have to also assign an attribute to each char in the loop. What
>> I was thinking was to eliminate that color assignment and just do a
>> fillchar in the beginning of the routine to make all of the chars on
>> the screen a certain attribute. Only problem is that [for example] if
>> I would make everything color 1 with fillchar, there would also be a
>> bunch of #1's on the screen.

Somewhere in the BP7 on-line HELP, lurking at the bottom of the help for
"inline" is a FillWord.  I've not tried it, but it looks as if you could
easily fill with the word for a space of colour 1.  Fillword may be quicker,
too!

--
John Stockton : mailto:J...@dclf.npl.co.uk from off-site.  MIME.  WP.
 National Physical Laboratory, Teddington, Middlesex, TW11 0LW, UK
  Direct Phone +44 181-943 6087, Nearby Fax +44 181-943 7138  
   Postings out, Email in/out are fast.  Offshore news takes 0..10+
    days to arrive; please mail me a copy of non-UK followups!  
     Regret system puts unzoned (UK civil) time on messages.

Re:FillChar every OTHER char?


Quote
>"te...@teleport.com" <te...@teleport.com> wrote:

>>Ok, I have something similar to:

>>type tscreen = array[1..4000] of byte;
>>var screen: tscreen absolute $B800:$0000; {for color monitors}

>>I have a procedure that needs to be performed as fast as possible. It
>>reads a section of a buffer assigns each char to a position in
>>[var] screen. (I have to go char by char in a loop because it checks
>>if the position is over 80 columns on the screen, or a CR.) At the
>>moment, my routine is fairly fast, but I could make it faster if it
>>didn't have to also assign an attribute to each char in the loop. What
>>I was thinking was to eliminate that color assignment and just do a
>>fillchar in the beginning of the routine to make all of the chars on
>>the screen a certain attribute. Only problem is that [for example] if
>>I would make everything color 1 with fillchar, there would also be a
>>bunch of #1's on the screen.

>>What I would want to do is to fill every OTHER char with the
>>attribute.. only problem is I have no idea how. Any ideas would be
>>very much appriciated.

This procedure will fill every other byte with 'attrib' 'count' times

procedure fillEOchar(var loc;attrib:byte;count:word); assembler;
asm
        les     di,loc
        mov     cx,count
        mov     al,attrib
@@lop:  mov     es:[di],al      
        add     di,2
        dec     cx
        jnz     @@lop
end;

To change all the text on a normal 80x25 screen to green, just do
FillEOChar(ptr(SegB800,1)^,10,2000);  This also works with other pointers,
as well as arrays.

--TCA of NewOrder
newor...@carina.unm.edu
http://www.nmt.edu/~surface/neworder.html

Re:FillChar every OTHER char?


Quote
te...@teleport.com (te...@teleport.com) wrote:

[Big Chunk Deleted]

: Also, similarly relating, is there a was to do a for loop on every
: other char? like "for b := 1 to 11 by 2 do" type thing, so it would do
: every other char? I can do this by something like:

: var
:   b: boolean:
:   w: word;
: begin
:   b := true;
:   for w := 1 to 1001 do
:   begin
:     if b then {do something};
:     b := xor true; {toggles the boolean}
:   end;
: end.

: ..but I would think there would be a more efficient way?

Are you absolutely stuck on a for loop? Why not use something simple like
a while loop? Ex:

var
  b: boolean;
  w: word;

begin
  while w < 1001 do
    begin
      if b then {do something};
      w := w+2;
      b := xor true;
    end;
end.

Sorry if I misunderstood your problem, but you are asking for FREE help. :)
                 Kato - Sorry, not the one you're thinking of...

Other Threads