Copy Link
Add to Bookmark
Report

Demo News 141

eZine's profile picture
Published in 
Demo News
 · 15 Sep 2019

 
______/\__________________________ __ ________________ ___ /\_______
\____ \ ________ _ _ ______ \ / \| \ ________ | \/ ______/
/ | \ _) \ \_/ \ | \ / \ \ _) \ | \______ \
/ | \ \ | \ | \/ \ \ / \ \ / \
\_____ /_______/___| /_______/\____\_____/_______/_________/________/
\_____/ |____/
Subscribers : 2547
DemoNews 141 - 02 February 1997 Archive Size : 3997M

>------------------------------------------------------------------ Contents --

Introduction
Calendar
Week In Review
Top Downloads
New Uploads
Articles
Software Design for Demos - Volume 3 .......... Kiwidog
Advertisement : X'97 Takeover ................. HarleQuiN
General Information

>-------------------------------------------------------------- Introduction --

Hello all, and welcome to DemoNews 141.

_____Introduction

So much to print, so little time. Even after releasing this 60k+ issue of
DemoNews, I have another 110k worth of articles and reviews just waiting to
be read. An article from Trixter, 2 from Shaithis, tons of /music reviews...
For just a little while, I'm probably going to be releasing 2 issues of
DemoNews a week; your standard-style DemoNews on Sunday night, and a
"catchup" issue either Wednesday or Thursday.

It's bad enough that files sit in /incoming as long as they do. It'd be a
travesty to actually have them reviewed and not be able to print them in a
timely fashion, agreed? Anyway, I'm sure things 'll calm down in a month or
so.

_____(knock knock) Anybody home?

With 2600+ subscribers to DemoNews, I expect a few new issues to bounce.
After all, people leave or get kicked out of school, change jobs or are
fired; email address are a dime a dozen and sometimes go away unexpectedly.
You'd be surprised how many issues of DemoNews bounce each week. Back in the
good 'ole days, it'd be about 15 bounces per new issue. It's recently grown
to about 70 or 80.

70 or 80 bounced issues x 60k per issue qualifies as mail bombing myself.
Although the listserver is smart enough to unsubscribe non-functioning
addresses, I still get that initial bounce. And even though they get saved
to a separate mailbox (thank you procmail), I still gotta sift through them
since the occasional DemoNews reply gets mixed in there.

Be kind. If you know you're going to lose the address to which DemoNews is
being sent, mail your friendly South African listserver@unseen.aztec.co.za
with the words "unsubscribe demuan-list".

_____%2B or +?

I'd like to thank Knut Eldhuset who educated me on the finer points of
encoded ascii in CGI search strings. This was the tip I needed to fix a bug
in the HA search engine that caused secondary searches for "****+" to fail.
This gets Slam! rating of 6.

_____Email Gripes

HTML is not yet an acceptable email format. Any mail sent to me in HTML only
will be ignored and deleted. On a related note, please learn how to
uuencode/uudecode if you don't know already.

_____The Cleansing of /incoming

Our /incoming directory is very busy. I want to take a minute to go over the
basic rules for a happy uploading experience:

1. must be .zip format (multi-file uploads may use .arj, .a01, etc.)
2. file.txt description required with each file.zip
please use /incoming/_forms/upload.frm (also see upload.exa)
file.txt must be under 500 bytes!
english only
3. lower case, not UPPER CASE
4. filenames must be 8 characters or less, not counting zip/arj extension
5. files uploaded to appropriate subdirectory
6. corrupted file.zip should be reuploaded as file.zip.good
7. check to see if there is already a file named the same as yours
8. only allowed to upload 1 production per day

Any file breaking a rule is deleted automatically by script.

Uploading means your file will stay on our site unless legitimate reasons
are given for its removal.

Please note that any files in /incoming that break rules #3 or #6 are deleted
automatically at 4AM. For files breaking #2, a second-chance script is used
to try and generate a .txt file based on a file_id.diz within the .zip. If
that fails, the file is automatically deleted.

Rule #8 might seem a bit odd. Rephrased, it might read:

8. if you upload 30 of your productions in one shot, one of our music
reviewers gets stuck spending an unfair amount of time reviewing your
music and ignoring everyone else's.

I've deleted at least 200 unhappy files in the past 2 weeks.

The official rules can be found in /incoming/.message

_____South African Mirror Gone

Please note that our mirror site at ftp.sun.ac.za has been discontinued. They
simply don't have the resources anymore.

_____Conclusion

So what's with people sending html mail anyway? Maybe I should start
replying in tar-gzipped uuencoded style.

Snowman / Hornet - r3cgm@hornet.org

>------------------------------------------------------------------ Calendar --

Date Event Location Contact Points
------------ ------------------- --------- ----------------------------------
31 Jan 1997 PC96 Brazil x@wm.com.br
wm.com.br/~x/pc96.html

* <-- YOU ARE HERE

15 Feb 1997 General Probe 3 Poland s146630@ire.pw.edu.pl
neutron.elka.pw.edu.pl/~mszklano
02 Mar 1997 Invasion Finland invasion@xuq.nullnet.fi
www.koillismaa.fi/invasion
23 Mar 1997 Millennium Israel mlitvak@ort.org.il
26 Mar 1997 The Gathering Norway www.gathering.org
28 Mar 1997 Mekka & Symposium Germany amable@aol.com
28 Mar 1997 SiliConvention Germany www.siliconvention.com
04 Apr 1997 X Takeover Holland x97take@dds.nl
05 Apr 1997 Spring Break USA (CA) whutchin@sdcc13.ucsd.edu
sdcc13.ucsd.edu/~whutchin
11 Apr 1997 The Trip Italy keyby@jnet.it
www.logicom.it/trip
30 May 1997 Scream Canada scream97.educ.infinit.net
furb@total.net
22 Aug 1997 AntIQ Hungary aboy@ttk.jpte.hu
www.jpte.hu/~aboy
25 Aug 1997 The Place To Be 5 France www.mygale.org/05/dadu

>------------------------------------------------------------- Week In Review --

-- /music ------------------------------------------------------------------>

:: Snowman / Hornet - r3cgm@hornet.org

_____Introduction

No room. Must make short!

_____The Good...

Dee Musicdisk Two by Dee. Excellent. Download now!

_____...The Bad, and The Ugly

The "Kx Files" by Kxmode. Lame... ripped off Jester's song. Didn't even
have the good sense to rip something obscure. "Hey Trixter, I'll change the
songtext to The Crossing and say I wrote it... think anyone 'll notice?"
Ripping is the cardinal sin of the scene, an action so reprehensible that we
have a special marker for it. Slam!

_____Conclusion

I am making some people very angry with me by writing reviews like the one
above. That's ok folks, I just call them as I see them.

>------------------------------------------------------------- Top Downloads --

This represents combined ftp/http transfers for the last 7 days.

Total files downloaded : 208,581
Size of files downloaded : 35,807,147k

Times File Description
----- -------------------------------- --------------------------------------

-- /demos ------------------------------------------------------------------>

181 /1995/a/animate.zip Animate by Schwartz
144 /1993/s/symbolog.zip Symbology by Admire
143 /1993/u/unreal11.zip Unreal v1.1 by Future Crew
135 /1993/0-9/2ndreal1.lzh Second Reality by Future Crew [1/2]
128 /1993/0-9/2ndreal2.lzh Second Reality by Future Crew [2/2]
127 /1995/n/nooon_st.zip Stars (bugfixed) by Nooon
108 /1995/c/countdwn.zip Countdown by Realtech
106 /1993/c/cd2_trn.lzh Crystal Dreams 2 by Triton
102 /1996/a/ai_strok.zip Stroke by Ionic of Astroidea
88 /1992/c_dream.lzh Crystal Dreams by Triton

-- /music ------------------------------------------------------------------>

96 /songs/1995/s3m/a/aryx.zip Aryx by K. Koch
95 /songs/1996/s3m/a/athought.zip Another Night of Thought by Zastar
76 /songs/1996/s3m/i/im_empir.zip The Hidden Empire by Karsten Koch
74 /songs/1996/s3m/i/im_chron.zip Chronologie Part 4 (remix) by Karsten
70 /songs/1997/xm/m/mcd-rain.zip Rain by MC Dreamer
56 /disks/1996/f/fm-plast.zip Blur Plastiq by Mellow-D of Five Music
55 /songs/1993/s3m/skyrider.zip Skyrider by Purple Motion of Future Cr
54 /songs/1996/s3m/f/fm-mech8.zip Mechanism Eight by Necros
54 /songs/1996/s3m/c/ccs-eps.zip Epsilon Eclipse by Mayhem
53 /songs/1995/s3m/c/ctgoblin.zip Catch That Goblin by Skaven

-- /graphics --------------------------------------------------------------->

26 /images/1994/i/incest5.zip Incest by Pentalysion
20 /programs/editors/fedit11.zip Font Editor v1.1 by PiCoder
20 /images/1996/a/airwar.zip Air War by Grape
18 /images/1996/a/aa_gargo.zip The Gargoyle by Coolhand
17 /images/1996/a/abc_pien.zip Pani Pienkowa by Grass
16 /programs/vector/veced300.zip 3D Vector Editor by Grey Cat
16 /programs/editors/char_122.zip Char Editor 1.22 by Escape
16 /programs/convert/bmp2avi.zip BMP to AVI by Paul Roberts
15 /programs/editors/gfx2b93.zip Grafx 2.00 Beta 93 by Sunset Design
15 /images/1996/h/hardcore.zip by Boss

-- /code ------------------------------------------------------------------->

63 /tutorials/denthor/tut01new.zip Tutorial 1 in C by Snowman of Hornet
61 /3ds/3dsrdr12.zip 3D Studio .3DS File Reader v1.2 by Jar
60 /effects/water/water.zip Water by De-Phassed
57 /effects/scroll/motionrd.zip Motion Read Me by Patch of Avalanche
56 /tutorials/denthor/tut04new.zip Tutorial 4 in C by Snowman of Hornet
56 /effects/water/hq_water.zip Heart Quake's water source by ARM of I
53 /tutorials/denthor/tut09new.zip Tutorial 9 in C by Snowman of Hornet
53 /tutorials/denthor/tut02new.zip Tutorial 2 in C by Snowman of Hornet
52 /tutorials/denthor/tut06new.zip Tutorial 6 in C by Snowman of Hornet
52 /tutorials/denthor/tut05new.zip Tutorial 5 in C by Snowman of Hornet

-- /incoming --------------------------------------------------------------->

96 /demos/idx-magn.zip
77 /demos/ctswht95.zip
73 /TP96/demo/alto.zip
71 /TP96/demo/megademo.zip
65 /code/wavepic.zip
65 /code/midas060.zip
64 /code/gb_fmint.zip
61 /demos/fishlife.zip
58 /demos/balistic.zip
54 /code/rastrzep.zip

>--------------------------------------------------------------- New Uploads --

All ratings are subjective.

Filename Size Rated Description
------------------------------- ---- ----- ----------------------------------

-- /demos ------------------------------------------------------------------>

/1996/0-9/1k_intro.zip 1 ***+ 1000 Byte Intro by Frenzy : 386DX
/1996/b/burning1.zip 179 *** Burning Chrome by Hellcore :
| 486,GUS/SB
/1996/d/dufhk.zip 4 *+ BBS Harakiri by Darkness Unknown
| Force : 486
/1996/e/e9-fett.zip 4 **** Fettina by Magic of Ethos 9 -
| TP96:in4k:02:
/1996/k/k_storm.zip 3 **+ BBS Dark Storm by Kloon
/1996/k/kk-rvsf.zip 123 *** Reverse (final) by Ketchup Killers
| - WIR96:in64:09: : 486,SVGA,GUS
/1996/m/marsvoya.zip 3 **+ Mars Voyage by Daze of TMB -
| TP96:in4k:08:
/1996/r/riplview.zip 56 **+ Ripple Viewer by Hellcore
/1996/s/shaolin_.zip 543 *** Shaolin by Live : GUS/SB
/1996/s/spasmo.zip 632 **+ Spasmo Vidio by Hirn Tod
/1996/s/stg_ntlf.zip 80 ** Not Too Late (final) by Skytech
| Group - SAT96B:in64:06:
/1996/t/timeout_.zip 3 ** Time Out by Zaifrun of Immaculate
| - TP96:in4k:10:
/1996/z/zrn-16.zip 148 **+ Zauron Is 16 by Index : 386,GUS/SB

-- /music ------------------------------------------------------------------>

/disks/1996/d/dna-unre.zip 1279 ***+ Unreleased - The Lost Collection
| by DNA : The file DNA-UNRE.EXE
| inside this .zip contained the
| Alfons.1344 virus. The
| executable was removed on 29 Jan
| 1997 and repacked.
/disks/1996/e/et9-emsn.zip 364 *** Emissions #1 by Ethos9 :
| Collection of about 40 chip
| songs... some good some bad.
/disks/1996/g/g_bshift.zip 1309 ***+ Blueshift by Beek of Grey : Old
| school style tracking dude.
| Works well. No interface.
/disks/1996/k/kx-files.zip 912 [rip] The Kx Files by Kxmode of Phluid :
| The song kx-break.mod "Breaking
| The Chains" is directly ripped
| from Jester's "Elysium". Only
| the sample text has been
| changed. Ripping is
| dishonorable and Kxmode has
| proven himself an untrustworthy
| tracker.
/disks/1996/m/mfx_co6.zip 869 *** MFX - Compilation 6 by MFX : Wierd
| slow trancy type tunes... long
| samples... no interface. Very
| odd. Very, very odd.
/disks/1996/r/rr_cha-1.zip 903 ***+ Chapter X by Radical Rhythms [1/8]
| : Includes 574k UNIVBE .zip
| file, compressed and
| uncompressed x-play/x-shell.
| Most of the music is ok, but
| they did a _really_ nice job
| with the interface... give 'em a
| star just for that. For a disk
| this large, it's well put
| together.
/disks/1996/r/rr_cha-2.zip 1325 ***+ Chapter X by Radical Rhythms [2/8]
/disks/1996/r/rr_cha-3.zip 1405 ***+ Chapter X by Radical Rhythms [3/8]
/disks/1996/r/rr_cha-4.zip 1308 ***+ Chapter X by Radical Rhythms [4/8]
/disks/1996/r/rr_cha-5.zip 1012 ***+ Chapter X by Radical Rhythms [5/8]
/disks/1996/r/rr_cha-6.zip 1147 ***+ Chapter X by Radical Rhythms [6/8]
/disks/1996/r/rr_cha-7.zip 1178 ***+ Chapter X by Radical Rhythms [7/8]
/disks/1996/r/rr_cha-8.zip 1456 ***+ Chapter X by Radical Rhythms [8/8]
/disks/1996/s/slkkro_1.zip 871 ***+ First Music Pack by Sunlikamelo-D
| : Relaxed, professional,
| inventive and creative music.
| Almost a 4 star.
/disks/1996/s/sr-nueva.zip 675 **+ Nueva Dimension by Sunrise : Not
| bad techno, but tries to put too
| many chords in (and
| unfortunately has poorly tuned
| samples). No interface.
/disks/1996/s/stm121.zip 1203 *** Disk-Volume 12 by SDC, TOM [1/2] :
| Each song in here is in an
| embedded .zip or .arj file,
| highly unwieldly as music disks
| go. This is unfortunate because
| the music is actually pretty
| good and deserving of a higher
| rating had the authors taken
| time to package their tunes
| professionally. No interface.
/disks/1996/s/stm122.zip 1282 *** Disk-Volume 12 by SDC, TOM [2/2]
/disks/1996/t/tm-skew1.zip 1405 *** Skew by T-Matic [1/3] : A very
| wide range of quality levels for
| the songs in this music disk.
/disks/1996/t/tm-skew2.zip 1425 *** Skew by T-Matic [2/3]
/disks/1996/t/tm-skew3.zip 1337 *** Skew by T-Matic [3/3]
/disks/1996/t/tripto3a.zip 1212 **+ Tripout 3 by Trip Productionz
| [1/2] : A few tiny chip .mdl's,
| some that have a really groovy
| beat, no interface.
/disks/1996/t/tripto3b.zip 1253 **+ Tripout 3 by Trip Productionz
| [2/2]
/disks/1996/v/vr-pack1.zip 1023 *+ Music Pack by VampRabbit : A new
| tracker with a little ways to
| go. However, coming from Ohio
| he is destined for success.
/disks/1997/c/cchimera.zip 2947 *+ Contorted Chimera by Drop Zero,
| Contrivance : Perhaps a bit
| unpolished and heavy on the
| high-hats.
/disks/1997/d/dee213.zip 1400 ****+ Dee Musicdisk Two by Dee [1/3] :
| Slam! This is how a music disk
| should be done. Absolutely the
| best interface I've seen for a
| music disk since Epidemic. Not
| only that, but the interface is
| configurable... you can actually
| use it for your own productions.
| The music kicks ass. If you
| only download a couple music
| disks this year, be sure that
| one of them is Dee Musicdisk
| Two!
/disks/1997/d/dee223.zip 1409 ****+ Dee Musicdisk Two by Dee [2/3]
/disks/1997/d/dee233.zip 1285 ****+ Dee Musicdisk Two by Dee [3/3]
/disks/1997/d/dzone.zip 777 *** Danger Zone by DZone : DZone took
| time at least to do an interface
| for this disk. Some songs
| better than others.
/disks/1997/n/ng-dura.zip 1850 ***+ Dura Master by Nearly Gods : Good
| techno! 3 songs in AMF format,
| with a nice player to go along.
| Don't try to play these in Cubic
| Player (out of memory) or under
| Windows 95 (lose keyboard
| handler). Would have given this
| 4 stars if there had been more
| songs.
/disks/1997/p/ph-0197a.zip 1233 ***+ Phluid 01/97 by pHluid [1/2] : One
| of pHluid's better music
| disks... some really great
| tunes. It's unfortunate that
| Kxmode / pHluid was recently
| caught ripping a song.
/disks/1997/p/ph-0197b.zip 1295 ***+ Phluid 01/97 by pHluid [2/2]
/disks/1997/r/rpinflrn.zip 1154 ** The Inflern by Mr. Mortal of Red
| Power : This song could actually
| get 4 stars if the samples were
| updated and the pattern data
| tweaked just a bit.
| Structurally this disk is sound,
| but the samples make it hard to
| listen to.
/disks/1997/s/s-new97.zip 1008 *+ New 97 by Space Invaders : Sounds
| kind of like newbie music, but
| with a lot of potential.
/disks/1997/t/t_mellow.zip 952 *** Melodramatic Tendencies by Troll :
| Decent music, just needs a
| little polishing. Troll has
| much potential.
/disks/1997/t/triphop.zip 1266 *** Triphop by Riders of Skyjump Team
| : Some pretty hip-hoppidy songs
| in here.
/disks/1997/v/v-debut1.zip 796 *** Debut by SML of VSL [1/3] : Songs
| were a bit large (3 were 2 megs
| each). However, they were
| pretty good.
/disks/1997/v/v-debut2.zip 719 *** Debut by SML of VSL [2/3]
/disks/1997/v/v-debut3.zip 1017 *** Debut by SML of VSL [3/3]
/disks/1997/v/visions.zip 1248 ** Visions by Bitstream of Tunnel
| Vision : Music isn't too bad but
| the samples sound muffled.
| Author needs to be more
| aggressive with his style. MDP
| interface.

-- /mags ------------------------------------------------------------------->

/1996/pain0396.zip 271 **+ Pain March 1996 Issue by Pain
/1996/pain0496.zip 335 **+ Pain April 1996 Issue by Pain
/1996/pain0596.zip 197 **+ Pain May 1996 Issue by Pain
/1996/pain0696.zip 157 **+ Pain June 1996 Issue by Pain
/1996/pain0796.zip 144 **+ Pain July 1996 Issue by Pain
/1996/pain0996.zip 151 **+ Pain September 1996 Issue by Pain
/1996/pain1196.zip 260 **+ Pain November 1996 Issue by Pain
/1997/pain0197.zip 410 *** Pain January 1997 Issue by Pain
/1997/rc-vol01.zip 210 **+ Volvo Issue 1 by Rectum Cauda

-- /party ------------------------------------------------------------------>

/invites/1996/ascen96n.zip 79 ** Atlantic Scene '96 Convite &
| Regras by Atlantic Dreams : SB
/invites/1996/atl96tro.zip 66 *+ Atlantic Scene '96 Invitation
| Intro by Atlantic Dremas : SB
/invites/1996/bdn3invi.zip 319 *** BDN 3 Invitation Intro by Funk
/invites/1996/jporno96.zip 608 **+ Jouluporno '96 Invitation Intro by
| Complex, Orange

>------------------------------------------------------------------ Articles --

---------------------------------------------------------------------------->

:: "Software Design for Demos - Volume 3"
:: Kiwidog - chargrove@mail.ravensoft.com

_____Introduction

Many happy returns!

After a couple articles of warm-up info to get everyone going, it's time to
finally start writing some code ('bout time eh? :)

This issue we'll be designing our screen class (actually classes, plural, as
you'll soon see) that we started talking about at the end of the last
article, as the beginning of a (probably pretty substantial) code base we'll
be writing over the next several articles.

It's highly unlikely I'll be able to cover the whole layout of the screen
info this issue, due to the immense size of what needs to be covered, so
we'll probably be doing this over the next several articles before moving on
to the next big topic.

I don't know how long this issue alone will end up being, but my gut tells me
it's gonna be a doozy, so hold on. :)

_____The Usual "But First..."

But First... :)

I got a couple mails this past week regarding the last article, and a few
folks got a bit confused on the whole constructor/destructor thing. Don't
worry, once you see 'em in action here with the screen classes it should all
make perfect sense, so be patient. :)

Also, I've gotten a good volume of mail about what to do with the 3D series,
and an overwhelming majority of you said you just wanted me to release the
articles alone in a .zip to get them out there, so that's what I'm going to
do. It might be another week before I do so (I've been tied up in work
related stuff for a little while), but the new zip will be called
HRN_DN3D.ZIP, and will contain the articles for the first 5 of the series
that went out here in DemoNews, along with five subsequent articles covering
Gouraud Shading, Texture Mapping, Arbitrary Cameras, 3D Clipping, and Spline
Paths, respectively. After some final touchups this week I'll release it;
hopefully that'll be enough info to keep busy for a while. :)

Also, during the naming conventions section of the last article I talked
about prefixes and suffixes, and how for classes I use a prefix/suffixless
system for my own code since all the classes were very intuitively named.
Welp, I broke that "15 character" barrier I talked about during the week, so
in order to not be a hypocrite, I switched to using a prefix. Since I've
seen the "C_" prefix in a lot of places, I decided to give it a try and it
seems to work well. Fortunately since I haven't written any major code with
you guys yet, I can start out with this convention from the outset as far as
the article series goes. So all the classes you'll see written in the series
from this point on will start with capital C in the name.

Just FYI. :)

Ok, I guess that's all the initial junk, and since I doubt I've got a lot of
free space to ramble this time, we better jump on in... :D

_____Of Cabbages and Kings

'"The time has come," the walrus said, "to talk of other things." And while
the walrus probably wasn't coding, he does have a point.

Sometimes you have to sit back for a little bit and think about what it
really is you want to do before you end up doing something rash. The problem
is, demo coding by nature tends to be very _very_ rash, so this can be a
major task mentally. But it's a good habit to get into, because once you can
get used to designing things even slightly in advance of actually coding
them, it makes everything go that much smoother. The longer you think about
your design beforehand, the more bugs, restrictions, and potential
improvements you'll catch in your head before you even lay a finger on the
keyboard.

So before we start coding our screen class, let us ponder. :)

One thing we know we want is non-mode-specific graphics. While doing
multiple color bit-depths is certainly the most difficult part of this, since
all the primitives change, we should at LEAST be able to do multiple
resolutions at the same bit depth without any hassles, and have at least
support somewhere for doing primitives for other bit depths.

Also, we know we want it to be non-platform-specific enough to where it
shouldn't be all too evil to port the video code between DOS and say, DirectX
under Win95. If the design is good enough, very little code should change
relatively in order for everything else to still work.

Part of this non-specificness also brought up the idea of not having screens
bound to any mode at all, so that we could use the same primitives for
arbitrary buffers, bitmaps, dirty rectangles (for situations where they're
needed), and so on.

Sound like a lot to shoot for? It is, but it's feasible. :)

_____Planes, Trains, and Devices

This section will probably seem rather confusing at first. Don't worry about
it, I'm just giving a rough overview of what we're about to do. :) Note that
of course this is just one of an infinite number of design possibilities; if
you like it that's wonderful, but basically I just want to stir up the
gears... as long as this gets you thinking, I've accomplished my goal. :)

Because we want three major things from this (arbitrary resolution, arbitrary
bit depth, and arbitrary platform), we're gonna need a bit of indirection in
our code to get everything done. We're gonna have some kind of "universal"
CScreen that everything above the video layer uses, sure, but CScreen itself
is gonna need to pass some of its responsibility to other classes...
otherwise it would be too hardwired for the kinda design we want.

Let's look at the "arbitrary platform" one first, since it seems like it
would supersede the other two. If we think about it, DOS and Win95 only
really differ in the end by how the video operations work. Instead of just
setting modes and blitting in Win95, you go through DirectDraw (or some other
abstraction mechanism). So the very first thing we'll want is to delegate
the hardware specific stuff, like mode sets and blits, to another layer.
Since most everyone uses offscreen buffers and blits them these days, doing
an abstraction like this is painless... the linear offscreen buffers can be
handled by CScreen while this "other layer" takes care of putting it
onscreen.

Now before we decide what that layer should do exactly, let's look at the
other two requirements. The easiest of the two left is arbitrary resolution.
As far as the CScreen-side buffering stuff goes, this just means a change in
the buffer sizes and the resulting scanline lookup tables. But on the
hardware side, if you decide to use a screen as a fullscreen mode, you're
gonna need another layer below the initial hardware layer, one which is
different for every fullscreen video mode you use. This means now we have
CScreen at the highest level, a platform-specific level below that, and then
another mode-specific level below the platform-specific level. Will that
take care of all the hardware abstraction stuff we need? Hopefully, but let's
check the last requirement, arbitrary bit depth, to make sure.

Bit depth doesn't just affect the hardware mode sets and blits and stuff. It
also affects your drawing primitives, because if you want any speed
whatsoever you'll want primitives that are different for each color bit
depth. Fortunately there are only a few depths to choose from, and even then
you might not use all of them (8 bit palettized and 24 bit truecolor are the
most likely grades), so this isn't a big deal. BUT it does add another layer
of abstraction. Where's that layer go? Well, since the hardware aspect of
bit depth variation (the mode sets and blits) is already taken care of by the
fact that we have a layer to cover all of those modes _regardless_, the only
thing left to deal with is the primitives problem.

We could have put our primitives (drawing lines, cutting and pasting
rectangles, etc) directly into our CScreen class if we were restricting
ourselves to one depth like 256 colors. But by abstracting the primitives
layer from CScreen as well, we cover that problem.

That should take care of all our abstraction... finally, we might also want
some kind of unified daemon-ish class that there's only one of, to control
how the platforms and primitives are applied, as well as to control a couple
other useful globalized things like automatically blitting the active
"fullscreen" CScreen, etc.

So that's five things total... the screen, the platform layer, the mode layer
under the platforms, the primitives layer, and the unified hub. The names I
gave the classes for these:

- CScreen, for the screen class that interfaces with the outside world,

- CVidControl, for the platform "control" mechanism dealing with the mode
"devices" underneath,

- CVidDevice, for each device itself, dealing with a particular mode

- CVidPen, for the primitives, since the primitives act like a pen to draw on
the screen, and

- CVideoDaemon, a class acting as a hub, where only one of them exists which
I named mVD (even though this isn't really a "daemon" in the true sense, I
name my single-instance classes like this because it's easy to recognize
their global purpose... all of my department daemon instances start with a
lowercase m for main with an abbreviation, in this case mVD; I'm just
clarifying incase it sounds odd).

I know the classes may sound kinda wacky and huge, but each one's not really
that big honestly. Hopefully the layout doesn't sound too confusing; if so,
just keep reading and you'll probably pick up on it.

Now, if you code DOS exclusively, you'll only need one CVidControl, maybe
called vid_ControlDOS or whatever. In addition, if you only support a couple
fullscreen modes like Mode 13h or certain VESA modes, you'll only need to
code concrete devices for those modes in particular. Also, if you only
support 256 color modes, you'll only need one concrete pen as well, for 8-bit
color. The point of this architecture is simply EXTENSIBILITY, so that if
you want to add extra support, it'll be easier to build more functionality in
to the system later on.

_____Slipping On Concrete

If you've gotten confused by terms I've been using like layers being "under"
one another, or coding "concrete" versions of a class, it means we'll be
taking advantage of another big thing object-oriented programming allows...

Inheritance.

Inheritance is when you declare classes that "inherit" all the abilities of
their ancestor classes... nearly all the data, the functions, etc. But
inherited (descendent) classes can add extra stuff to the mix, as well as
replace functions given in their ancestors. And when you have a function
somewhere that takes a class parameter that's an ancestor of other classes,
the descendents can _also_ be used as parameters to those functions. Don't
worry about understanding it now, as I'll be going over it later in this
article when we start writing our video code.

Actually, why don't we start the code now... :)

_____CVidDevice - No Guts, No Glory

Since I doubt I have enough space to write all five classes in this issue,
we'll start off taking care of the abstract CVidDevice class and showing a
concrete class of it, to deal with video mode devices. The reason to start
off with the devices before the others is simple; they don't need as much to
exist beforehand... makes 'em easier to explain :)

The abstract video device only has set the ground rules for doing a couple
things: Setting a video mode, blitting a buffer to that video mode, and
setting a palette entry (since palettized modes need this). There are a few
other interfacing functions such as setting the device name and "registering"
the device with the commanding CVidControl, but the core operational stuff is
only a few functions. I should be using the term "methods", since class
functions are called methods, but you get the idea. :)

The first code I need to give is a header containing general definitions used
by just about every other file you'll see from me.

NOTE: Throughout the code you'll see references to "Colony" and the
abbreviations "CL" and "COL". This is because my engine is called Colony
(the group name is Terraformer so it fits), and the vast majority of the code
I use will be directly from this code base. Hence, since this is not just
example code but code that _is_ being used by its creator, should you use it
in your own code base I'd appreciate some greets or other recognition in your
production. I already go to great lengths to write these articles, let alone
give out my code base, so the last thing I need is to get my hard work
ripped. A greeting is all I ask.

I say this because I had a rather INFURIATING experience earlier this month
on EFNet #c where one guy came on and said "check 0ut my kewl 3d codeZ" and
offered an xdcc. Since I was curious as to exactly how "kewl" his code was,
I got the dcc offering and took a look.

The guy had taken the supplement source from my 3D series article #2 and
ripped it VERBATIM, except he took out all the comments and put his own nick
at the top. Needless to say I got right back on IRC and looked for him to
give him a piece of my mind, only to find that he had /quit while I was
reading (hopefully after realizing who he dcc'ed to). I haven't seen him
since, although I'd love the honor. >|0

So, once again, if you use my code at all, please give some recognition in
the end result. And as a warning, if I find someone ripping my code again
_and_ claiming it as their own like that guy did, I will cease writing any
more articles without question and you'll have them to blame, by name. I
tolerate a lot of things in life, but plagiarism is NOT one of them.

Now that that's said,

----begin COLDEFS.H----

//************************************************************************
//** COLDEFS.H
//** Colony Engine Version 0.3
//** Definitions Header
//** Include for all .H files
//************************************************************************

#ifndef _COLDEFS_H_
#define _COLDEFS_H_

#define _COLONY_VERSION_ 0.3

// typedefs
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned long dword;
typedef signed char sbyte;
typedef signed short integer;
typedef signed long longint;

#endif

----end COLDEFS.H------

Here's the class header for CVidDevice, CVIDDEVI.H. I'll explain each
piece of it next...

----begin CVIDDEVI.H----

#ifndef _C_CVIDDEVICE_H_
#define _C_CVIDDEVICE_H_

//**************************************************************************
//**
//** - CVIDDEVICE.H
//** Colony Engine Version 0.3
//** Header - CVidDevice class module
//** LM 1-4-97 Chris Hargrove
//**
//**************************************************************************

//**************************************************************************
//** HEADERS
//**************************************************************************

#include <coldefs.h>

//**************************************************************************
//** DEFINITIONS
//**************************************************************************

#define VID_256 8
#define VID_64k 16
#define VID_16M 24

//**************************************************************************
//** EXTERNAL CLASS DECLARATION
//**************************************************************************

class CVidControl;

//**************************************************************************
//**
//** CLASS CVidDevice
//**
//**************************************************************************

class CVidDevice
{
private:
dword xRes;
dword yRes;
dword bitDepth;
char *sysmarker;
dword type;
char *devname; // mode title
char *devinfo; // any other misc text
void *devdata; // device information, optional

protected:
CVidControl *vidImp; // control interface

void SetDevName(char *ndevname);
void SetDevInfo(char *ndevinfo);
void SetDevData(void *ndevdata);

public:

// Constructors

CVidDevice(CVidControl *nVidImp, dword nxRes, dword nyRes,
dword ntype);
virtual ~CVidDevice();

// Operators

// Functions - Implemented by concrete devices as much as possible

// general mode operations
virtual void Activate();
virtual void Blit(void *src); // fullscreen blit

// color operations
virtual void SetPalIndex(dword index, byte r, byte g, byte b);
virtual void GetPalIndex(dword index, byte &rr, byte &rg, byte &rb);

// info
void GetModeInfo(dword &rxRes, dword &ryRes, dword &rbitDepth);
char *GetDevName();
char *GetDevInfo();
void *GetDevData();

// Friends

};

//**************************************************************************
//**
//** END CLASS
//**
//**************************************************************************

#endif

----end CVIDDEVI.H------

Look menacing? Don't worry, it's simpler than you might think. :)

The first thing is the standard #include <coldefs.h>, which was listed above.
Notice the < > instead of " ".... for convenience I added my code's main
directory as an include directory in my makefiles, so files like coldefs.h
could be used universally without path information. You might find something
like this very handy as well. :)

The three defines given are just aliases to bit depths, and the external
"class CVidControl;" is to let the rest of the header (and compiler) know
that there exists a class data type called CVidControl, so don't be alarmed
when it's used here in various parameters. The actual class definition for
CVidControl will in another one of the .H files, so it'll be resolved when it
comes time to compile CVIDDEVI.CPP.

The rest of the file is the class definition itself, and as you can see
there's a bit of meat in there. In order to explain it, we'll have to cover
a few terms such as "public" "private" and "protected", as well as the term
"virtual" you see a few times up there. :)

_____The Untouchables

One of the big things in object oriented programming is being able to hide
information from other objects. While you can't completely "hide" the class
structure itself in C++ due to the classes usually being in headers, you can
still hide stuff as far as the compiler is concerned. Within a class,
"public:" "private:" and "protected:" are used to accomplish this.

"private:" means anything after it is private to that object alone. That
means the members (variables) and/or methods listed can only be accessed or
called from within the object's methods and nowhere else. For example, in
this class, the "dword xRes" member is only accessible by this object's
members. As far as every other object is concerned, that member doesn't
exist; they can't see it.

"public:" means the exact opposite... the members and methods listed are
totally public, out in the open, and accessible by everyone and everything.
Generally a lot of methods will be public, but you'll want to keep public
members to a minimum.

"protected:" is sort of a mixture of the two, and it deals with the
inheritance thing I mentioned earlier in the article. Protected member
variables and methods are private to just about everything, _except_ derived
classes. Derived classes are the descendents I talked about, and we'll be
making classes derived from CVidDevice to do "concrete" devices like I
mentioned. Any derived classes automatically has access to protected stuff,
while non-derived classes don't; to them, it's the same as private.

You'll see up there that we have the device's mode resolution (xRes, yRes,
and bitDepth), type (at present same as bitDepth but left for expansion) and
some information extras private to the object. Any access to these members
from the outside world has to go through this class's methods, so you control
what can see or modify them.

The controlling interface vidImp and functions for setting device info are
protected, because while the rest of the world shouldn't be able to use them,
derived (concrete) classes will want them to say what mode they're for, what
controller they use, etc.

Finally there are a whole bunch of public methods, which I separate into four
groups, "constructors", "operators", "functions", and "friends". Operators
and Friends I'll get to later on in the series; we don't need them for now.
Functions are just general method functions like you're familiar with. But I
think we should take another look at the first group...

_____What Goes Up Must Come Down

"Constructors" lists all of the constructors and destructors for the class.
While these don't necessarily need to be public (there are a couple neat
things you can do with protected constructors for example), most of them will
be. I mentioned constructors and destructors briefly in the last article,
but now we get to see them put to practical use.

There's only one constructor listed:

CVidDevice(CVidControl *nVidImp, dword nxRes, dword nyRes,
dword ntype);

Notice that it takes parameters, in this case four of them. This is a very
powerful feature of C++ over C; the fact that you can declare an object of a
class and have it take parameters in the declaration right from the start...
this way you can initialize the object any way you see fit. Assuming we had
a CVidControl called vid_ControlDOS, we could instantiate a CVidDevice called
"exampleDev" like this:

CVidDevice exampleDev(&vid_ControlDOS, 320, 200, VID_256);

And it would instantly call the appropriate constructor matching those
parameters when exampleDev is declared. This means that you can have
functions get called _before_ main() is even called, if you happen to declare
any objects globally. Very cool indeed. Plus, if you happen to have
multiple constructors with the same number of parameters, then the compiler
will choose the one that matches the parameters, within limits (you can
sometimes get "ambiguous" errors where the compiler doesn't know which one to
pick, so make sure if you do make constructors in this fashion that they're
fairly explicit).

Because of the whole construction-upon-declaration system, C++ also
eliminates the need to declare all variables before any code in a function is
started. You can declare a variable anywhere in a function now, and if
there's a constructor involved, it'll be called then.

Now one thing we _don't_ have in this class is a "default" constructor,

CVidDevice();

The default constructor is the constructor called if you just declare a class
instance without any variables. Normally a default constructor is just
"assumed" to exist if no other constructors are given, and it'll just
construct the object by filling all the members with zeros or whatever. But
once you declare any explicit constructors like we did, that assumption
disappears. As a result, if you tried this:

CVidDevice exampleDev;

you'd get a compiler error saying that there was no constructor for that form
of declaration. This is good, because for CVidDevice, and hopefully all
classes derived from it, we don't want a default.

Now on to the other half of this process, the destructor.

A destructor, listed just like a default constructor but with a ~ at the
front, is automatically called when the object goes out of scope. For local
instances, this means when the function ends. For globals, it's called after
either main() ends or you call exit() to end the program prematurely. The
"virtual" at the front of this destructor is something totally unrelated (and
not used for all destructors by any means); I'll get to that in a moment.

Destructors are incredibly handy to tearing down an object that was built up
throughout the course of the program. For example, if you allocate memory
for a member pointer, you can have the destructor automatically deallocate
it. If you use a linked list inside, you can make it automatically walk the
list and deallocate everything. It's the object's janitor, so to speak. :)

Now, the only two things left up there that might be confusing for you C
coders are the term "virtual", and that little referencing operator & used in
the declarations of a few of those methods. We'll tackle the & operator
first, since it's quick to explain.

_____References Available Upon Request

C++ is happy to present another wonderful way to pass by reference, thanks to
the & operator. Where in C the only way to pass by reference was with a
pointer using the * operator in the function declarations, C++ allows you to
use & as well. & is the same as * except that inside the function, it looks
like passing by value. It internally substitutes all the value references
with pointer references. For example, look at the following two functions:

void blah1(int *baygle)
{
*baygle = 3;
}

void blah2(int &baygle)
{
baygle = 3;
}

In C++ these two are functionally equivalent; the pointer reference has
automatically been inserted for baygle in the second function because the &
operator was used in the formal parameters. Because of this, calling blah2
doesn't require putting an address-of & at the front of an int passed in,
either...

int temp;
blah1(&temp);
blah2(temp);

Basically this mechanism is very handy but can also be pretty dangerous; once
you use the & operator in a declaration, it's up to YOU to remember that what
you're passing in is by reference not value, and modifying the parameters
WILL alter the actual parameter. So when debating whether to use * or &,
choose, but choose wisely. :)

Okay, now on to the last of the (possibly) unfamiliar stuff...

_____Don't Look At Me, It Was Him!

In order to explain virtual functions, we have to go back to the whole
inheritance thing. As I said, inheritance allows classes to "descend" from
other classes, and to take on their functionality automatically, subsequently
being able to replace any inherited ancestor functions they desire, plus add
any new ones. Declaring a derived class is a piece of cake...

class v320x200 : public CVidDevice
{
public:

// Constructors

v320x200(CVidControl *nVidImp);

// Operators

// Functions

void Activate();
void Blit(void *src);

// Friends

};

Just by adding that ": public CVidDevice" in the declaration, we've just
inherited every public and protected member and method of CVidDevice as our
own. If a function ever takes a CVidDevice as a parameter, we can throw in a
v320x200 instead and the compiler will gladly accept. Derived classes are
happily welcomed where their ancestors tread. :)

A real life example would be animals... if we had an animal class, we could
derive classes like mammal, amphibian, fish, etc. From there we derive even
more classes from those derived classes, to describe different families and
species. But while those classes may be derived, they're all still animals
and should be accepted as such.

So when we derive a class from an ancestor, all the public stuff from the
ancestor is passed on to the derived class, and these derived classes can be
accepted as parameters to functions using their ancestors.

BUT this introduces a small problem. If we pass a class as a parameter into
some function and inside the function we use one of that class's methods, how
does the compiler know what method is being used? The only thing it can do
at compile time is assume that we mean that class's method itself, and not a
method from a derived class (which might also be passed in) which could have
overwritten the method. But that might not be what we want.

For example, say we have an ancestor class "Spider" with a method called
"SearchForFood();" Now many spiders just eat other insects so the method for
the generic spider class would involve the spider walking around the web and
searching for anything that it trapped.

But what about a derived class "BlackWidowSpider" ? A black widow might also
eat its husband after mating, so that's another feeding option. Hence we'd
replace the SearchForFood method with another method that's more specific to
the black widow's feeding style.

Now if we had a function called SpiderThink(Spider &activeSpider), where one
of the options was to call activeSpider.SearchForFood(), how is the compiler
gonna know if we're gonna called SpiderThink with a regular spider or a black
widow? If it doesn't know what (if any) derived classes are gonna be used
instead, it can't generate code, so by default it assumes you mean the
generic spider's SearchForFood method. That would be bad for the black
widow, since that would keep her from enjoying probably one of her favorite
meals.

Isn't there any way for the compiler to know that sometimes you might wanna
use a derived class instead, so it'll wait until runtime to determine which
method to use?

There is. Welcome to virtual functions.

By adding the word "virtual" to the beginning of a function's declaration
inside a base class, the compiler is told "derived classes should have their
functions called instead if they replace the base, so wait until runtime to
resolve any calls for this method". You might think every method function
should be virtual due to how natural it is, but honestly there's no reason
for it a lot of the time... not all classes are intended to have descendents,
and not all references to a class are intended to use derived ones, so you
really only need to use it when you think it applies.

There's also a small overhead issue... since the resolution of the method is
done at runtime, the compiler will generate sets of function pointers in
order to know what to choose. While this is a pretty trivial performance
cost, it's something you wouldn't want to abuse in a putpixel for example.
Fortunately you don't have to go much higher up than a putpixel before the
cost of making a function virtual is effectively meaningless, so there's
nothing to worry about (I find it funny how many people come telling me how
horrible virtual functions are... well of course you don't use them inside a
pixel-by-pixel loop, but you wouldn't use selective function pointers in a
pixel-by-pixel loop either now would you? I thought virtual functions would
be a horrible slowdown at first, but as long as you use them wisely they're
nothing to be worried about).

Now in our CVidDevice class, we have five virtual functions; the destructor,
the Activate function (setting the video mode for fullscreen), the blit, and
the two palette set/get methods. Note that you can't make a constructor
virtual directly (how can you virtualize declaring a variable, when you have
to know what you're declaring? :) but every other method, including the
destructor, is game.

We certainly want to virtualize the destructor because derived devices might
add extra stuff to deallocate (dunno why they would want to, but it could
happen) and since you never know what might be allocating or deallocating a
device, it's a good idea. None of my code yet has done anything more than
declare a prototype instance of each derived (concrete) device, so making the
destructor non-virtual wouldn't make any difference so far, but I like to
leave the option open.

The other four are obviously intended to be virtual... that's the whole point
of this abstraction layer, being able to call a mode set or blit without
having to know which specific mode or which blitter to call at compile time.
We wanna dynamically deal with modes, so we need to dynamically deal with
what functions need calling. Simple as that. :)

(BTW: You can do virtual constructors indirectly by making a virtual method
designed to create a new instance of the current class and pass back the
pointer to the caller; it's a design pattern often called a "factory
method"... you'll probably see them along with many other design patterns
later on in the series).

_____Whoa

Holy cow, I've broken 32k in this article... WAY more than I intended, and I
still haven't scratched the surface. We still have yet to spell out
CVIDDEVI.CPP, as well as the other four primary classes for this video
system, so we've got another few articles left with this topic before moving
on, that much is for sure. We'll finish up with the devices next time, then
take a look at CVidControl, since the two go hand in hand. :)

Until then, :)

Chris Hargrove
a.k.a. Kiwidog / Terraformer, Hornet alumni
Technology Programmer, Raven Software
email: <chargrove@mail.ravensoft.com>

Disclaimer: These articles are in no way affiliated with Raven Software, and
represent the views and opinions of the author solely.

---------------------------------------------------------------------------->

:: "Advertisement : X'97 Takeover"
:: HarleQuiN / SuccesS - arjen@vin.nl

Nostalgia and SuccesS invite you to X'97 Takeover!
04-06 April 1997, The Auditorium, Eindhoven.

That's right, Holland's phattest, dopest, funkiest and fantasticest party
returns once again! Come on down, and taste the atmosphere, the competitions,
the live performances and some of the craziest, zaniest weirdos ever to sit
behind a computer screen!

For more information, please use the following media...

x97take@dds.nl
http://www.hacom.nl/~jal/X97-Takeover

We really hope you're able to come!

>------------------------------------------------------- General Information --

_____The Hornet Archive

Master Site : USA (California) - (ftp|www).hornet.org/pub/demos
Mirrors : Portugal - ftp.telepac.pt/pub/demos
Sweden - ftp.luth.se/pub/msdos/demos
USA (Wisconsin) - ftp.uwp.edu/pub/demos
USA (Pennsylvania) - ftp.co.iup.edu/code (from /demos/code)

_____DemoNews

New issues - /incoming/info
Old issues - /info/demonews
Supplemental files - /info/dn_other

How to subscribe: Mail - listserver@unseen.aztec.co.za
Body - subscribe demuan-list FIRST_NAME LAST_NAME _or_
Body - subscribe demuan-list HANDLE

DemoNews is sent to your e-mail's "Reply-To" field.

How to unsubscribe: Mail - listserver@unseen.aztec.co.za
Body - unsubscribe demuan-list

_____Contact Address

questions@hornet.org

>------------------------------------------------------------------------------

EODN

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT