1. EMEMCOPY.E
Well....
> sequence virtualmonitor
> virtualmonitor = {{},{}}
> wt = 1023
> ht = 767
> virtualmonitor[1] = {wt, ht}
> virtualmonitor[2] = allocate(wt*ht)
> display_svga_image(1, virtualmonitor[2], {wt,ht}, {0,0})
The reason the image is skewing is the virtual screen is not as wide as the real
one. So the library copies in all the bytes but it's just not big enough. It
should be one pixel to the left.
Try allocating the correct width but still 767 high. See if it works and if it
is skewed.
I guess from the call it tries to copy the full buffer. Try allocating the
correct size. Fill the bytes that you weren't copying ( the last 767+1024 , at
virtualmonitor[2] + 1023*767 ) with a set colour, say Magenta (Pink-Ish :
63,63,00) and then if you see a Magenta line around the bottom it is copying the
full screen. Otherwise the library might be of by one, copying to little. But
that shouldn't cause a Causeway Exception.
---
Sincerely,
Mathew Hounsell
Mat.Hounsell at Mailexcite.Com
Free web-based email, Forever, From anywhere!
http://www.mailexcite.com
2. Re: EMEMCOPY.E
Here's a routine that displays a virtual
image to a VESA SVGA screen using Bolin's
ememcopy. I just pulled it out of my sprite
engine (which I will finish one of these
days), no promises, but I think you'll find
it useful. It differs from Bolin's routines
in that it includes a source_add parameter
so that a section of a large virtual screen
can be displayed, allowing for fast-scrolling.
Call Pete's svga_mode() routine instaed of
graphics_mode()
--- code begins ---
atom ememaddr
sequence rin,rout
integer bytes_per_line,gran
global function svga_mode(integer mode)
-- Openly stolen from SVGA.E
-- by Pete Eberlein <xseal at harborside.com>
atom data
if set_up_emc() then end if
rin=repeat(0,10)
ememaddr=allocate_low(26)
lock_memory(ememaddr,26)
poke(ememaddr,1)
poke(ememaddr+25,0)
data = allocate_low(256)
if data then
rin[REG_AX] = #4F01
rin[REG_CX] = mode
rin[REG_ES] = floor(data / 16)
rin[REG_DI] = and_bits(data, 15)
rout = dos_interrupt(#10, rin)
gran = (peek(data + 4) + 256 * peek(data + 5))*1024
bytes_per_line = peek(data + #10) + 256 * peek(data + #11)
free_low(data)
end if
return graphics_mode(mode) or (data = 0) or (rout[REG_AX] != #4F)
end function
global procedure display_vimage( -- G.Burke 3/98
sequence p, -- Screen pos for image {x,y}
atom saddr, -- Base address of virtual img.
integer w, -- Width of image to display
integer h, -- Height of image to display
integer sad) -- Source add -> No. of bytes
-- between end of one pixel line
-- and start of next. sad = 0 if
-- displaying entire vscreen.
--
--
integer os,bank,bos,los,line,pline,nlines,dad,vsw
sequence data
vsw=w+sad
data={}
pline=0
dad=bytes_per_line-w
os=p[1]+p[2]*bytes_per_line
bank=floor(os/gran)
bos=remainder(os,gran)
while 1 do
os=(bank+1)*gran
line=floor(os/bytes_per_line)-p[2]+1
los=remainder(os,bytes_per_line)-p[1]
nlines=line-pline
if line>h then
if h-pline then
data=data&bank&saddrA0000+bos&w&h-pline&sad&dad
end if
exit
elsif los<0 then
data=data&bank&saddrA0000+bos&w&nlines&sad&dad
saddr=saddr+(nlines-1)*vsw
bank=bank+1
bos=-los
line=line-1
elsif los>=w then
data=data&bank&saddrA0000+bos&w&nlines&sad&dad
saddr=saddr+nlines*vsw
bank=bank+1
bos=bytes_per_line-los
else
data=data&bank&saddrA0000+bos&w&nlines&sad&dad
saddr=saddr+(nlines-1)*vsw
bos=bos+nlines*bytes_per_line
data=data&bank&saddrA0000+bos&los&1&0&0
bank=bank+1
saddr=saddr+los
los=w-los
data=data&bank&saddrA0000&los&1&0&0
saddr=saddr+los+sad
bos=los+dad
end if
pline=line
end while
bos=1 -- recycle as counter
rin=repeat(0,10)
rin[REG_AX]=#4F05
set_emc_address(ememaddr)
while bos<length(data) do
if data[bos]!=rin[REG_DX] then
rin[REG_DX]=data[bos]
rout=dos_interrupt(#10,rin)
end if
poke4(ememaddr+1,data[bos+1..bos+6])
e_mem_copy()
bos=bos+7
end while
rin[REG_DX]=0
rout=dos_interrupt(#10,rin)
end procedure
--- code ends ---
Example:
atom my_vs_address
integer my_vs_width,
my_vs_height,
screenX,
screenY
this_wide,
this_high,
Xstart_here,
Ystart_here
(assumes screen exists and variables contain values)
If you have a virtual screen at address my_vs_address,
that is my_vs_width wide, and my_vs_height high, and
you want to display a section of it that is this_wide
and this_high, offset from the top left corner of the
virtual screen Xstart_here pixels to the right and
Ystart_here pixels down, at screen position (screenX,
screenY) then use:
display_vimage({screenX,screenY},
my_vs_address + my_vs_width*Ystart_here + Xstart_here,
this_wide,
this_high,
my_vs_width - this_wide)
Hope this helps,
(not to mention works
Graeme.
----------------------------------------------------