$include "keysyms.icn" # $include "C:\Program Files\Unicon\ipl\gincl\keysyms.icn" link printf # link graphics link enqueue link "cve-lib" link "cve2-lib" link "chat_window" link "SH118b" # keep each room in a separate file and # link them all here class World( Rooms, curr_room, cam, posx, posy, posz, lookx, looky, lookz, cam_lx, cam_lz, cam_angle, framefactor, stepdelta, g_priority, lod01, texture_path, texture_dir, current_texture, server, port, event_source_list, g_win, c_win, net , chat ) method process_cmd_line( args ) # parse cmd line and set parms here # if av[1] == "-port" then port := integer(av[2]) end method build() g_win := open("SH118b", "gl", "size=800,750", "bg=grey", "inputmask=k") | close("can't open 3D window") set_window( g_win) put( event_source_list, g_win ) NextRoom := SH118b( self) curr_room := NextRoom.build() # kinda sloppy here cam := Camera( self) chat := Chat_win( self ) end method set_window(win) if \win then &window := win else fail end method render() set_window( g_win ) every (!Rooms).render( self) Eye(cam.posx, cam.posy, cam.posz, cam.lookx, cam.looky, cam.lookz) end # search texture_path for texture tex - follows usual path # semantics and returns tex from first directory in the path # which contains it. # maybe should allow tex to include its own path for force # only one directory to be searched method find_texture(tex) if \tex then { every path := !texture_path do { fname := path || tex # write( " searching for: texture: ", tex, " at ", fname ) s := stat( fname ) | next # write( " texture: ", tex, " found at ", fname ) # current_texture := fname return fname } } write( " texture: ", tex, " not found on texture_path " ) end method close( msg ) if \msg then write ( msg ) # do any cleanup here #??? if \net then close(net) exit( 0 ) end # this is now in World, since it handles events from all windows method event_loop() xdelta := 0.00 ydelta := lookdelta := 0.00 cam.cam_move(xdelta) repeat { # L := (select(event_source_list,0) | []) # the ,0 may be needed to drive the *L = 0 condition L := (select(event_source_list) | []) # if *Pending() = 0 then if *L = 0 then { # if xdelta ~= 0 then cam_move(xdelta) # if ydelta ~= 0 then cam_orient_yaxis(ydelta) # if lookdelta ~= 0 then # looky +:= lookdelta # if (\curr_room.nearest_door).openness then # { # if 0 < curr_room.nearest_door.openness < 1 then # { curr_room.nearest_door.swing_door( self ) } # } } else { every x := !L do { case x of { c_win: #send user input to the server { set_window( c_win ) chat.handle_chat_window() set_window( g_win ) } net: { # note: blocks if no newline or EOF is to be found. fix. s := read(net) | break write("netread: ", image(s)) chat.ClientCommand(s) WSync() } g_win: { set_window( g_win ) # cam.speed_control() count := g_priority while count > 0 do { if *Pending(g_win) = 0 then break count -:= 1 case ev := Event(g_win) of { Key_Up: { cam.cam_move(xdelta := cam.stepdelta) # Move Foward # Enqueue(g_win, ev) # cam.speed_control() } Key_Down: { cam.cam_move(xdelta := -cam.stepdelta) # Move Backward # Enqueue(g_win, ev) } -166 | -168 | (-(Key_Up|Key_Down) - 128) : { # purge event list of Key_Up Key_Down events len := *Pending( g_win ) while len > 0 do { ev1 := Event(g_win) len -:= 1 if ( ev1 === Key_Up | ev1 === Key_Down ) then next else Enqueue( g_win, ev1 ) } } Key_Left: { ydelta := -1*cam.stepdelta # while Pending()[1] === -Key_Left-128 & # Pending()[4] === Key_Left do # { # Event(); Event(); ydelta -:= stepdelta # } cam.cam_orient_yaxis(ydelta) # Turn Left # Enqueue(ev) } Key_Right: { ydelta := cam.stepdelta # while Pending()[1] === -Key_Right-128 & # Pending()[4] === Key_Right do # { # Event(); Event(); ydelta +:= stepdelta # } cam.cam_orient_yaxis(ydelta) # Turn_Right # Enqueue(ev) } -165 | -167 | (-(Key_Left|Key_Right) - 128) : { # purge event list of Key_Left Key_Right events len := *Pending( g_win ) while len > 0 do { ev1 := Event(g_win) len -:= 1 if ( ev1 === Key_Left | ev1 === Key_Right ) then next else Enqueue( g_win, ev1 ) } } "w": cam.looky +:= (lookdelta := cam.stepdelta ) #Look Up "s": cam.looky +:= (lookdelta := -1*cam.stepdelta ) #Look Down -215 | -211 : dum_lookdelta := 0 "q": close(" CVE closed from q key " ) "r": { # reset to initial camera position cam.reset() xdelta := ydelta := lookdelta := 0.00 cam.cam_move(0.00) } "c": { chat.chat_create() } "d": { # this opens the nearest door curr_room.select_nearest_door(cam.posx, cam.posy, cam.posz) # can door be null???? # write ( " door openness ", curr_room.nearest_door.openness ) if curr_room.nearest_door.openness < 0.00 then { curr_room.nearest_door.openness := 0.00 curr_room.nearest_door.direction *:= -1 next } if curr_room.nearest_door.openness > 1.00 then { curr_room.nearest_door.openness := 1.00 curr_room.nearest_door.direction *:= -1 next } # if (\curr_room.nearest_door).openness then # { # if 0 < curr_room.nearest_door.openness < 1 then # { curr_room.nearest_door.swing_door( self ) Enqueue( ev ) # } # } } } Eye(cam.posx, cam.posy, cam.posz, cam.lookx, cam.looky, cam.lookz) } } } # case x of } # every x := !L } # if *L = 0 then ... else } # repeat end # method event_loop initially Rooms := [ ] curr_room := &null cam := &null # the camera chat := &null # the chat window # These parms are intended to gather all the global variables and parameters # in one place for consistent management. Their initial values should be # set by editing here. posx := 58.00 # current eye x,y,z position posy := 1.50 # places camera in SH118b posz := 18.00 lookx := 51.00 # current look x position and so on looky := 1.50 lookz := 18.00 cam_lx := 0.00 # eye angles for orientation cam_lz := -1.00 cam_angle := 0.00 framefactor := 30.00 # attempt to control movement speed # larger framefactor ==> slower movement stepdelta := 0.05 # default step size when moving- # slower movement may need smaller steps to # avoid looking jumpy lod01 := 0.60 # bounding box offset to avoid pixellation g_priority := 10 # number of graphics events processed before # looking for others texture_path := [ "textures\\default\\", "textures\\ziad\\" ] # texture_dir := "textures\\default\\" # windows only, at the moment current_texture := find_texture("wall2.gif") # no longer a global variable # network and chat window parms # server := "unicon.cs.nmsu.edu" server := "" port := "4500" event_source_list := [] # windows + net sockets that need to be handled in # the event loop # global User, Cmds g_win := &null # 3D graphic window c_win := &null # chat window net := &null # socket to server end # class World # ====== end of file ==========================================================