| ECE291 | Computer Engineering II | Lockwood, Spring 1999 |
Team Members:
| Name | |
| Razvan Mathias | Project Design, Documentation maintenance, Video Decoding |
| Peter Prokopios | Video Display |
| Sidney Thong | Network, AVI Sound |
| Ari Silverman | MAVIS Interface |
| Numbers 1-9 (only on host) | set that number as the length of a side in terms monitors, ie 1=> 1 screen, 2=> 4 screens, 3=> 9 screens... |
| Tab | changes to the next |
| P (only on host) | will pause when playing, or play when paused |
| X (only on host) | Stop all |
| R (only on host) | Rewinds a few frames |
| F (only on host) | Fast Forwards a few frames |
| Up or Down (only on host) | changes the volume of the sound |
| Escape | On Host: stops video and closes all clients
On Clients: closes that individual client |
| Click Play | Plays the video |
| Click Pause | Pauses the video |
| Click Exit | Exits video |
| Click Stop | Stops the video and exits. |
| Click on progress bar | Takes you ahead or behind in the video |
There are many technical
challenges that have to be overcome before this project takes off. The
following is a list of the major tasks and their descriptions:
A messaging system will be used to do all of the synchronization in the project. There are two basic sources for the synchronization messages. The first is the sound playing system, which will send a timing message out every time a buffer has finished emptying. The MainLoop in the application will play the video at it's own pace (generally a bit faster than necessary); this loop will respond to the synchronization messages, which will slow the video down slightly in order to keep in step with the sound. Keeping the sound buffer small enough will ensure that synchronization will occur frequently, making it unnoticable by the human eye.
Actually, two sound buffers will be used. While one is playing, the other will be refilling in the MainLoop. An interrupt will occur when the first buffer has completed playing, triggering a sychronization message (PLAY or IDLE packets) to be propagated to the client subsystems. On the clients, RecievePackets will take the messages and update the local machine's variables to reflect the arrival of the synchronization message. The MainLoop will then respond to these changes as shown:

In addition to the synchronization
messages will be seek messages (or JUMP packets) which will cause the MainLoop
to seek a for a certain location within a file and then enter and idle (paused)
state, waiting for a play message to be created. These messages will
originate in the MouseHandler and KbdHandler functions.
The message structure is made simple so that a
common method can be used to create all outgoing packets from the host
application. The messages contain a type (PLAY, IDLE, JUMP, and EXIT), and
an identifier indicating the frame number. If play is encountered by the
main application, the packet is used for synchronization purposes. If IDLE
is found, the client does nothing (as in the paused state). If JUMP is
found, the client seeks the frame number in the file, and then enters an IDLE
state waiting for a play to be sent by the host (this is done to ensure
synchronization among the different screens). If EXIT is found, the client
application simply quits.
| Packet Name | Additional Information | Description |
| IDLE | GlobalFrameNum | tells clients to enter IDLE state |
| PLAY | GlobalFrameNum | tells clients to enter PLAY state, and also synchronizes them by having them wait if they are ahead |
| STOP | none | tells all clients to enter EXIT state |
| GLOBALNUMSCREENS | Number of Screens | Updates GlobalNumScreens on all client machines |
Memory
allocation requirements:
The allocation of memory will be important in solving the real-mode programming problem. The following is a breakdown of the AVI file as it moves from the file, through the application's memory, and to the respective output devices.

The basic flow of the data is fairly simple. First the file is read from disk. It is then written to two buffers, either video or audio; these buffers simply contain the chunks that were read from the hard disk. The video chunks are decompressed in a buffer in another segment. After this buffer, the correct portion of the image is StretchBlt'ed to the video memory. An uninterrupted sound stream is created and sent to fill one of two buffers; while one buffer fills with data, the other plays on the sound card.
;==============================================================
;CalcIndexY
;Input:
BP is the row to calculate(display) on the screen
;Output: SI will be the calculated bmp row to be used
;Purpose: uses the following equation to calculate bmp
row to display
;
SI=(OffSetY-Row#*VIDHight/SCRhight)*TVIDwidth
;Coded By Peter Prokopios
;==============================================================
InitInterface PROC NEAR
; Purpose: Display the introductions screen and allow the
user to set some
;
initial variables such as the file name and the host status
; Input: none
; Output:
Initializes variables that need to be set by the user
; Coded by : Ari Silverman
;==============================================================
MakeHost PROC NEAR
;
Purpose: fill in the appropriate box on the introduction screen to
indicate
; a
host computer
; Input: none
; Output: Draws a box to the screen
; Coded by : Ari Silverman
MakeClient PROC NEAR
;
Purpose: fill in the appropriate box on the introduction screen to
indicate
; a
host computer
; Input: none
; Output: Draws a box to the screen
; Coded by : Ari Silverman
;==============================================================
SetPallette PROC NEAR
;
Purpose: Sets the pallette for the 256 color registers on the video
card
; Input: ds:[si] contains location of
pallette in memory
; Output: Updates
pallette register
; Coded by : Ari
Silverman
;==============================================================
EnterAVIFile PROC NEAR
;
Purpose: Allows the user to enter which avi file they want to play.
; Does
not let the user enter more than 8.3 characters (DOS filenames)
; and
allows the user to backspace, but not past the first character
; Input: None
; Output:
Changes the file name, and updates the screen
;
Coded by : Ari Silverman
;==============================================================
DisplayFilename PROC NEAR
; Purpose: Displays the avi filename to the screen.
; Input: None
;
Output: Updates the screen
; Coded by
: Ari Silverman
;==============================================================
DrawSolidBox PROC NEAR
;
Purpose: Draws a solid box with variable dimensions, color, and
placement
; Input: di = location on screen
; bx = height
of box
; cx = length of
box
;
al = color of box (corresponding to pallette entry 0....255)
; Output: Updates the screen
; Coded by : Ari Silverman
;==============================================================
OpenFile PROC NEAR
;
Purpose: Opens a file
; Input: dx = offset
of name of file
; Output: ax = file
handle
;
carry is set if unsuccessful
; Coded by : Ari
Silverman
;==============================================================
CloseFile PROC NEAR
;
Purpose: Closes a file
; Input: bx = file
handle
; Output: none
; Coded by : Ari Silverman
;==============================================================
LoadFile PROC NEAR
;
Purpose: Loads data from a file into memory
; Input: bx = file handle
; ds:[dx] = begining
location in memory place where file is to be written
; cx = number of bytes
to be read from file
; Output: carry
is set if unsuccessful
; Coded by : Ari
Silverman
;==============================================================
clrScreen PROC NEAR
;
Purpose: Clears the screen to pallette entry zero
; Input: none
; Output:
Updates the screen
; Coded by : Ari
Silverman
;==============================================================
DrawBMP PROC NEAR
;
Purpose: Streams a bitmap from a file onto the screen
;
Assuming a 320X200 image is to be read (64000 bytes)
; Input: bx = file handler
; file pointer is set to
begining of data to be read
; Output:
Updates the screen
; Coded by : Ari
Silverman
;==============================================================
KbdHandler PROC NEAR
;
Purpose: Process Keyboard inputs
;
Accessed using a doscall
;
Input: none
;
Output: Updates the appropriate variables and calls appropriate
procedures
; Coded by : Ari Silverman
;==============================================================
MouseHandler PROC NEAR
;
Purpose: Process Mouse inputs
;
Accessed by reading status of mouse
;
Input: none
;
Output: Updates the appropriate variables and calls appropriate
procedures
; Coded by : Ari Silverman
;==============================================================
CalcNewFrame PROC NEAR
;
Purpose: Calculate what frame number file should be on based on
jump
; Input: al = percentage
of the way through the file
; Output:
variables updated
; Coded by : Ari
Silverman
;==============================================================
MAVISSendPacket PROC NEAR
; Purpose: Filling RxBuffer with the packet host play status and
send out the packet
; Input: variable
Status
; Output: TXBuffer filled with a
packet of format PacketMsg (1 Byte long)
;
Description: This function makes a library funtion call: SendPacket
; Coded by : Sidney Thong
netpost PROC NEAR
; Purpose:
Callback function for incoming network messages from host
; Update variables
;
Input: BX=Receive Buffer
; AX=Message
Length
; Output: Variables Status updated
; Description: This is a Datagram callback
routine
; Coded by : Sidney
Thong
;====== SoundCallBack
====================================================
; Purpose: SoundCallBack is called whenever the DSP generates an
interrupt
; at the end of playing
each half buffer.
; SoundCallBack is
used to call send packet containing host
; play status so that the clients are
synchronized
; Input: none
; Output: none
;
; Description: This is an ISR Callback function. It switches to
Single cycle mode
;
when there are no more raw sound data to be played.
; Sound Playing is then stop
; Coded by : Sidney Thong
;==============================================================
; SoundCallBackWOSend
;
Purpose: SoundCallBackWOSend is called whenever the DSP generates an
interrupt
; at the end of playing
each half buffer.
; This is
specifically used to play the intro sound
;
Input: none
; Output: none
;
; Description: This is an ISR
Callback function. It keeps looping the IntroSound
; Sound Playing is then stop, and
blaster resources are freed
; Coded by
: Sidney Thong
;====== OpenRawSound
====================================================
; Purpose: OpenRawSound opens a wav file and advances to the
beginning of data
; Input: None.
; Output: wavremaining = bytes of Sound Data.
; SoundSample contains the wav file header
information
; Coded by : Sidney Thong
;====== LoadSoundBuffer
======================================
; Purpose:
This function load half of the SoundBuf with data
; or with zero from the wav file.
; Input: WhichHalfBuf ; WriteFirstHalf
== 1st half,
;
WriteSecondHalf== 2nd half
;
; Output: The following variables are updated
; LastSoundBuf = 1 if just loaded last
quarter buffer
;
LastSoundBufLength = the last number bytes loaded into quarter buffer
; Description: This procedure is called from the call
back function
; to
load the next quarter sound buffer
; Coded by :
Sidney Thong
; ===== InstallSound
=========================================
InstallSound proc near
; Purpose:
Install DMA to play sound and install correct sound call back
functions
; depending whether we are
playing avi file or the intro sound
; Input:
array SoundBuf,SoundBufLenght, WhichSound, WhichHalf
; Output: SoundBufPage, SoundBufOffset, SoundCallBack or
SoundCallBackWOSend
; is set
; Description: This function first compute the linear
address of SoundBuf
; and make sure it does not cross
the page boundary.
; If the page boundary is crossed,
then the buffer is shifted
; by SoundBufLength.
; Coded by : Sidney Thong
;====== PlaySound
============================================
;
Purpose: Open wav file and start playing sound
;
Input: SoundBufOffset, SoundBufPage, SoundBufLength,
; Output: wavremaining updated
;
Description: This function first check if Single cycle mode of
auto-initialize
;
mode is to be used. If sound data is so small that it would only
; fill up the first two
buffer, then single cycle mode is used.
; In this case, sound playing is
then stop, and blaster resources are freed
;
Coded by : Sidney Thong
;==============================================================
SoundCloseFile PROC NEAR
; Purpose: Close the Intro sound file
; Input: SoundFileHandle
; Output:
none
; Coded by : Sidney Thong
;==============================================================
DoIntroduction PROC NEAR
; Purpose: Call the respective functions to Play the intro sound
and run through
; interface
screens
; Input: none
; Output: none
; Coded by : Sidney
Thong
;====== EndSound
============================================
EndSound PROC NEAR
; Purpose:
This procedure changes the dsp playback mode to single-cycle mode
; The
sound is stopped, Blaster resources are freed.
;
Input: none
;
Output: LastSoundBuf reset to 0
;
Coded by : Sidney Thong
;====== EndSound
============================================
ClearSoundBuffer PROC NEAR
;
Purpose: This function fills the entire SoundBuf with zero's.
; This
creates sillence at the sound blaster output.
;
Input: SoundBufPage, SoundBufOffset, SoundBufLength
; Output: none
; Coded by : Sidney Thong
;--------------------------------------------------------------------------
; AVIOpenFile
;
Input: AviName contains the name of the file to open
; Output: AVIFileHandle contains a DOS file handle to the open
file
; Modifies: AX, DX
; Purpose: Opens an AVI file and returns a DOS handle to it
; Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; AVICloseFile
;
Input: AviName contains the name of the file to open
; Output: AVIFileHandle contains a DOS file handle to the open
file
; Modifies: AX, BX
; Purpose: Closes an AVI file
;
Coded By: Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; AVICalcJump
;
Input:
;
; EAX = location to jump to, scaled to
100%
; AVIFileHandle =
handle of open
; Output: FileHandle is set to
point to correct place in file
; Modifies: EAX,
EBX, EDX, DI
; Purpose: Jumps to a percent
location within a file
; Coded By Razvan
Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; CheckJump
;
Input:
; JumpLocation is
the place to jump to
;
AVIFileHandle = handle of open
; Output:
FileHandle is set to point to correct place in file
; Modifies: EAX, EBX, EDX, DI
;
Purpose: Jumps to a percent location within a file
; Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; LoadAVIHeader
;
Input:
; AVIFileHandle =
handle of open
; Output: FileHandle is set to
point to correct place in file
; Modifies: EAX,
EBX, EDX, DI
; Purpose: Loads the info from the
AVI header into the local variables
; Coded By
Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; LoadIndex
;
Input:
; JumpLocation is
the place to jump to
;
AVIFileHandle = handle of open
; Output:
FileHandle is set to point to correct place in file
; Modifies: EAX, EBX, EDX, DI
;
Purpose: Loads the Index into the Index Chunk
;
Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; LoadNextSoundChunk
;
Input: None
; Output: SoundBuf is loaded with
sound
; Modifies: AX, BX, CX, DX
; Purpose: Loads the next sound chunk, but doesn't move ahead too
far in
;
loading to prevent skipping and maintain synchronization
; Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; LoadNextChunk
; Input:
None
; Output:
; ChunkSize, ChunkType
; SoundBuf or VideoChunkBuffer contains the buffer
info
; Modifies: None
; Purpose: Loads the next chunk from the AVI file. If it's a
video chunk
; it
goes into the VideoChunkBuffer. Otherwise it goes into
; the
SoundBuf
; Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; InstallTimer
; Input:
None
; Output: MilliSecCount counts the number of
loops within a millisecond
; Modifies:
None
; Purpose: Sets the timer variable for video
synchronization to the correct
;
value.
; Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; AVIDelay
; Input:
MicroSecPerFrame from the AVI Header, MillSecCount
; Output: none
; Modifies:
none
; Purpose: Delays the correct amount of time
per frame. Uses base 2
;
arithmetic where allowable, to result in quick execution
; Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; AVIDrawFrame
; Input:
VideChunkBuffer
; Output: none
; Modifies: AX, CX, DI
; Purpose:
Draws a frame onto the screen without stretching, used for
;
extending chunk types in the future and debugging
; Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
; SetVideoPalette
;
Input: VideoChunkBuffer must contain the header info
; Output: values to the screen palette
; Modifies: None
; Purpose: Sets
the current palette to the screen's palette
;
Coded By Razvan Mathias
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;CalcOSetX
;Input: MonitX = X
postition of which grid of picture frame to display
;
VIDwidth = width of video portion that will be displayed
;Output:
OffSetX = offset to correctly display image
;Purpose: using following
formula to correctly display image
;
OffsetX = MonitX*VIDwidth
;Coded By Peter
Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;CalcOSetY
;Input:
TVIDhight-1 = last row of bmp segment
;
MonitY = Y postition of which grid of picture frame to display
;
VIDhight = hight of video portion that
will be displayed
;Output:
OffSetY = offset to correctly display image
;Purpose: use the following
formula to correctly calculate offset
;
OffSetY=(TVIDhight-1)-MonitY*VIDhight
;Coded By
Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;StrethBlt
;Input:
VideoChunkBuffer = bmp segment used to display to screen
;
VidGrSEG = segment used to display bmp
;Output:
Stretched portion of bmp
;Purpose: Stretches a portion
of a video onto the appropriate screen
;Coded By
Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;NumOfScrns
;Inputs:
calls functions CalcWidth and Height
;Outputs: initializes
VIDwidth and VIDhight
;Purpose: sets up the grid
size for correct display
;Coded By Peter
Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;CalcWidth
;Inputs:
VIDNumScrn = sqrt of the num of grids to display to
;
TVIDwidth = original video width
;Outputs:
VIDwidth = calculated
video width grid
;Purpose: calculate video
width using the following formula:
;
VIDwidth = TVIDwidth/VIDNumScrn
;
reset OffSetX and MonitX to defaults each time chng of VIDNumScrn
;Coded By Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;CalcHeight
;Inputs:
VIDNumScrn = sqrt of the num of grids to display to
;
TVIDhight = original video height
;Outputs:
VIDhight = calculated
video height grid
;Purpose: calculate video
height using the following formula:
;
VIDhight = TVIDhight/VIDNumScrn
;
reset OffSetY and MonitY to defaults each time chng of VIDNumScrn
;Coded By Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;ChangeScrn
;Input: None, uses
variables VIDNumScrn, MonitX, MonitY,
;
OffSetX, OffSetY
;Output:
MonitX, MonitY, OffSetX, OffSetY
;Purpose: Change the current
BMP grid that should be shown on the screen
;Coded By Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;ChgYCutOff
;Input:
NONE
;Output: YCutOff is
either set to 200 for full screen or 170 for menu
;Purpose: toggles between full and menu screen view used in
kbdhandler
;Coded By Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;DspMenu
;Inputs: NONE
;Outputs: Display to the screen
;Purpose: Prints out the menu
bar to the sreen, reinitializes mouse
;Coded By
Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;CalcScrnNum
;Inputs: MonitY, MonitX,
VIDNumScrn
;Outputs: Display to screen
the current screen number
;Purpose: Calculate the
current screen number using
;
Scrn# = MonitY*VIDNumScrn+(MonitX+1)
;Coded By
Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;CalcResNum
;Inputs: AX = Resolution
Number to print to screen
;
DL = Screen Column to display to
;Outputs: Display to screen
the current video resolution
;Coded By Peter
Prokopios
;Purpose: Display the current
video resolution
;--------------------------------------------------------------------------
;-------------------------------------------------------------------------
;DspResNum
;Input: TVIDhight, TVIDwidth
;Output: Display to screen resolution of current
video
;Purpose: Display resolution
TVIDwidthxTVIDhight
;Coded By Peter
Prokopios
;-------------------------------------------------------------------------
;--------------------------------------------------------------------------
;NumberScrn
;Input: AX =
new number of screens
;Output: YCutOff is
either set to 200 for full screen or 170 for menu
;Purpose: toggles between full and menu screen view used in
kbdhandler
;Coded By Peter Prokopios
;--------------------------------------------------------------------------
;--------------------------------------------------------------------------
;DspNumMenu
;Inputs: NONE
;Outputs: Display to the screen
;Purpose: Prints out the menu
bar to the sreen, reinitializes mouse
;Coded By
Peter Prokopios
;--------------------------------------------------------------------------
; Purpose: Change the frequency to fit playback of
11.025khz and 22.05khz AVI file
; Input: The
following values are used for frequency and the correspoinding Time
Constant
;
Frequency : AL=0 for 11.025kHz, AL=1 for 22.05kHz
; TimeConstant
: A5 for 11.025kHz, D2 for 22.05kHz
; SB_BaseAddr,
DSP_WRITE_PORT, DSP_TIME_CONSTANT
; Output:
none
; Description: The frequency calculation is
done using the following formula
;
TIME_CONSTANT = 256 - 1000000 / frequency (result is rounded off)
; Coded by: Sidney Thong
ECE291 Sound Library Functions for sound playback
ECE291 Network Library for Netbios
; ====== MAIN Routine ====================================================
main proc far
mov
ax, cseg ; Initialize DS register
mov ds, ax
; Begin assuming that we
can play the first sound
MOV Status,
LOADNEXTSOUND
; Initialize network for
the entire message subsystem
Call
NetInit
StartOver:
; Display the introduction
screen
Call
DoIntroduction
; We can only exit the
entire application from this screen
cmp Status, Exit
je ExitNow
; Actual video Playback starts
here.
MOV WhichSound, AVISound
CALL AVIOpenFile
; Load the index of the
file for ff/rew purposes
CALL
LoadIndex
; Load the file's
information into the local variables
CALL
LoadAVIHeader
CALL SetVideoPalette
; Install the frame
timer
CALL InstallTimer
; We assume the first chunk is a sound
chunk. We it to calculate
; our sound buffer sizes.
mov WhichSound, AVISound
CALL LoadNextChunk
; Initializes sound and begins playing the
buffers, only for the host
CMP
HostClientStatus, Client
JE
MainLoop
Call InstallSound
Call PlaySound
MAINLOOP:
; check for input and exit video
playback if necessary
call MouseHandler
call KbdHandler
cmp
Status, Exit
je EndMainLoop
; If there is a jump
message, deal with it and go to IDLE (Pause mode)
Call CheckJump
; If in IDLE mode, we sit
and do nothing
cmp cs:Status, IDLE
jne NotIdle
jmp MAINLOOP
NotIdle:
; grab the next chunk from the
file for processing
CALL
LoadNextChunk
; if the next chunk is the last
one, exit.
cmp
cs:Status, Exit
je
EndMainLoop
cmp ChunkType, 'B'
jne DonePlayingChunk
; if this is a bitmap chunk,
show it and increase the frame number
call StretchBlt
inc NFrames
mov ax, NFrames
cmp ax, NumFrames
je EndMainLoop
DonePlayingChunk:
JMP MAINLOOP
EndMainLoop:
; We must delay for all incoming
network packets to arrive before
; we exit
delay 200
; Clear out and clean Sound
buffer
call
ClearSoundBuffer
call
EndSound
NoUninstallSound:
; close the file, clear the
screen and prepare for intro screen and
; next avi load
Call AVICloseFile
Call clrScreen
MOV Status, LOADNEXTSOUND
mov NFrames, 0
mov YCutOff, 200
mov WhichSound, IntroSound
JMP StartOver
; Jumps here when we're done with the
introscreen, and we've exited the app.
ExitNow:
; Clean the sound buffer, close the file,
change to text mode, and exit
Call EndSound
Call SoundCloseFile
Call AVICloseFile
TMODE
Call NetRelease
Call DOSXIT
main endp
; ---- Play Status Information ---
IDLE EQU 0
PLAY EQU
1
PAUSE EQU 2
STOP EQU
3
EXIT EQU 4
JUMP EQU
5
LOADNEXTSOUND EQU 6
; ---- Network Message Types
& Formats ---
PacketMsg STRUC ; Packet Message Structure
;
Used for synchoronizing clients with host activity.
HostStatus db 0 ; Status of host
JumpTo dd 0
PacketMsg ENDS
ScreenMsg STRUC ; Screen Message
Structure
HostVIDWidth dw
320
HostVIDHight dw 200
HostVIDNumScrn dw 1
ScreenMsg ENDS
;====== Sound Info
=========================================================
; ---- Wave Header Struct----------
WaveHdr STRUC
format
db 'RIFF'
filelen dd ?
wavefmt db 'WAVEfmt_'
fmt_len dd ?
fmt_tag dw ?
channel dw
?
samples dd ?
bytesps dd ?
bkalign dw ?
bitsps dw
?
data db 'data'
datalen dd ?
WaveHdr
Ends
;====== Stack Segment
=====================================================
stkseg segment stack ; *** STACK SEGMENT
***
db 64 dup ('STACK
')
stkseg ends
; --- Define sound buffer segment---
SNDSEG SEGMENT
SoundBuf db 8191 dup (00,00,00,00,00,00,00,00) ; (64KB - 1B)
of empty sound
SNDSEG
ENDS ; Note: 64kB -1B
requires only
; requires a word for addressing.
;====== Define code segment ===============================================
cseg segment public 'CODE' ; *** CODE SEGMENT
***
assume cs:cseg, ds:cseg, ss:stkseg,
es:nothing
;====== External procedures ===============================================
; -- Lib291 Function Calls made to the library used
--
extrn kbdin:near, binasc:near, dspmsg:near,
dspout:near, dosxit:near
extrn kbdine:near,
rsave:near, rrest:near
; -- LibNet (Free) --
extrn NetInit:near, SendPacket:near, NetRelease:near,
NetTest:Near
extrn TXBuffer:byte,
RXBuffer:byte
; -- Sblib291 (Free) --
extrn SB_Init:near, SB_Clean:near, SB_Play:near,
SB_Stop:near
extrn SB_SetCallback:near,
SB_SingleCycle:near
; The following two procedures are the functions extended
in the SB291lib.asm
; coded specifically for
MAVIS.
extrn SB_ChangeVolume:near
extrn SB_ChangeFrequency:near
;====== Variables ========================================================
pbuf db 7 dup(?)
crlf db CR,LF,'$'
Status db 1 ; Play Status: 0=Idle, 1=Play, 2=Pause,
3=Stop, 4=Exit
PUBLIC Status
FrameNumber dw 0
PUBLIC
FrameNumber
grp_name db 'WCE291MAVIS$$$$$'
my_name db 'WCE291Client00$$' ; The '00'
will be the number assigned
; dynamically.
PUBLIC grp_name,
my_name
; Variables for Sound procedures
WriteFirstHalf EQU 0
WriteSecondHalf EQU
1
IntroSound EQU
0
AVISound
EQU 1
SoundBufPage db ?
SoundBufOffset dw ?
SoundBufLength dw Sizeof SoundBuf
LastSoundBufLength dw ?
LastSoundBuf db 0 ; 1 == the last sound buffer is just
read
SoundSample WaveHdr <
>
WhichHalfBuf db 0 ;
WriteFirstHalf == first half of SoundBuf
; WriteSecondHalf ==
second half of SoundBuf
WhichSound dw
0
Volume db 07Fh
SoundChunkSize dw 0
; Variables for wav file
Introwavfile db 'Omavis2.wav',0 ; null terminate file
names
SoundFileHandle dw ?
wavremaining dd 0
; Variables for interface
InterfaceBMP db 10678 dup(0)
NumMenuBMP db 10678 dup(0)
NumStorage db 7 dup('$')
Pallette
db 1024 dup(0) ; holds the pallette for the
startup screens
; Names of the files we will be using
ImageName db 'IntImage.bmp',0
NBarName db 'NumBar.bmp',0
Screen1
db 'Screen1.bmp',0
Screen2 db
'Screen2.bmp',0
Screen3 db 'Screen3.bmp',0
Screen4 db 'Screen4.bmp',0
Aviname db 'test4.avi ',
0 ; holds the name of the
avi file
NumberOfScreens db 1
ScreenNumber db 0
MouseStatus
db 0 ; 0 - mouse button is up, 1 - mouse
; button is down
FrameJump
db 0 ; Holds where to jump in the avi
file
HostClientStatus db
HOST ; Holds whether a host or client is displaying the
video
FirstIntro db
0
; Constants telling whether we are running host or client
mode.
HOST EQU 1
CLIENT EQU 0
; Variables for video playback
AVIFileHandle dw ?
; Local variables used to tell the size and type of the
last loaded chunk.
ChunkSize dw ?
ChunkType db ?
SOUND EQU 1
VIDEO EQU
2
; This buffer is used to load the headers of each
individual chunk
HeaderBuffer db 30
dup(' ')
; This structure will contain the only information we
need from the actual header
; chunk in the
AVI
PaletteOffset EQU
0C8h
;================ VARIABLES USED BY STRETCHBLT FUNCTION ===================
;screen width and height, in video mode 320x200
SCRwidth DW 320
SCRhight
DW 200
;video portion that will be displayed on
monitor
VIDwidth DW ?
VIDhight DW ?
;Sqrt of the Num of
Grids the BMP is split into, default is 1
VIDNumScrn DW 1
;total video width
and height
TVIDwidth DW ?
TVIDhight DW ?
;which monitor is
being used to display bmp, DEFAULT MonitX & Y = 0
MonitX DW 0
MonitY DW 0
;offset to correctly display image, OffSetX=0,
OffSetY=(TVIDhight-1)
OffSetX DW 0
OffSetY DW ?
;used by
host computer on whether to print Control panel or not
;initialy this is equal to SCRhight=200, Host
YCutOff=SCRhight-30
YCutOff DW 200
;used to correctly display the number menu; DEFAULT =
0
YNumCutOff DW 0
;==========================================================================
;Variables grabbed from avi file
MicroSecPerFrame DD 0
IndexBufferSize DD 0 ; size of the index
buffer
NumFrames DW
0 ; Total number of
frames
JumpLocation DD 0 ;
Used to determine the local jump location when
; Status==JUMP
; frame number we're on.
NFrames DW 0
; number of loops in Delay function for one
millisecond
MilliSecCount DD 0
; These are all standard for most AVI files.
; The files ***MUST*** be decompressed RGB
666 format with
; 11 KHz sound.
The test files were created using MainActor
; a video creation utility.
; First chunk in AVI RIFF file is the AVI Main Header Chunk
AVIHeaderOffset
EQU 0Ch
MainAVIHeaderType STRUC
dwMicroSecPerFrame
DD 0
dwMaxBytesPerSec DD
0
dwReserved1
DD 0
dwFlags
DD 0
dwTotalFrames
DD 0
dwInitialFrames
DD 0
dwStreams
DD 0
dwSuggestedBufferSize DD 0
dwWidth
DD 0
dwHeight
DD 0
dwScale
DD 0
dwRate
DD 0
dwStart
DD 0
dwLength
DD 0
MainAVIHeaderType
ENDS
strhOffset EQU 64
AVIStreamHeader STRUC
fccType
DB 'vids'
fccHandler
DB 'dvsd'
dwFlags
DD 0
wPriority
DW 0
wLanguage
DW 0
dwInitialFrames
DD 0
dwScale
DD 100
dwRate
DD 2997
dwStart
DD 0
dwLength
DD 2192
dwSuggestedBufferSize DD 120000
dwQuality
DD 0
dwSampleSize
DD 0
rcFrame
DD 0,0,720,480
AVIStreamHeader
ENDS
strfOffset EQU 0A0h
; This is actually a header at the beginning of the file
telling
; us about the dimensions and colors of
the file
BMPFormat STRUC
; --- BitMapInfoHeader --- ; 40 bytes
BISize
DD ? ; Size of BitMapInfoHeader (28h = 40d)
BIWidth
DD ? ; # Pixel Rows
BIHeight DD
? ; # Pixel Columns
BIPlanes DW
1 ;
BIBitCount DW ? ;
Log2(palette size) = 4 for 16-color image
BICompression DD 0 ; RGB = 0 =
Uncompressed
BISizeImage DD ? ; Size of
Image (Bytes)
BIXPelsPerMeter
DD ? ;
BIYPelsPerMeter DD ? ;
BIColorsUsed DD
0 ; 0=All
BIColorsImportant
DD 0 ;
RGBQuad DB 16 dup (
4 dup(?) ) ; Blue, Green, Red, Unused
BMPFormat
ENDS
moviChunkOffset EQU
0D4h