From: Rene S. <sa...@us...> - 2004-09-22 19:22:56
|
Update of /cvsroot/jake2/jake2/src/jake2/sys In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11556/src/jake2/sys Modified Files: IN.java Sys.java Log Message: major refactoring in game, server and client package Index: IN.java =================================================================== RCS file: /cvsroot/jake2/jake2/src/jake2/sys/IN.java,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** IN.java 8 Sep 2004 09:37:39 -0000 1.4 --- IN.java 22 Sep 2004 19:22:14 -0000 1.5 *************** *** 6,27 **** */ /* ! Copyright (C) 1997-2001 Id Software, Inc. ! This program is free software; you can redistribute it and/or ! modify it under the terms of the GNU General Public License ! as published by the Free Software Foundation; either version 2 ! of the License, or (at your option) any later version. ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! See the GNU General Public License for more details. ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! */ package jake2.sys; --- 6,27 ---- */ /* ! Copyright (C) 1997-2001 Id Software, Inc. ! This program is free software; you can redistribute it and/or ! modify it under the terms of the GNU General Public License ! as published by the Free Software Foundation; either version 2 ! of the License, or (at your option) any later version. ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! See the GNU General Public License for more details. ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! */ package jake2.sys; *************** *** 33,38 **** import jake2.qcommon.Cvar; import jake2.qcommon.xcommand_t; ! import java.awt.*; import javax.swing.ImageIcon; --- 33,41 ---- import jake2.qcommon.Cvar; import jake2.qcommon.xcommand_t; + import jake2.util.Math3D; ! import java.awt.Component; ! import java.awt.Cursor; ! import java.awt.Point; import javax.swing.ImageIcon; *************** *** 43,208 **** public final class IN extends Globals { ! static Component c = null; ! static Cursor emptyCursor = null; ! static boolean mouse_avail = true; ! static boolean mouse_active = false; ! static boolean ignorefirst = false; ! static int mouse_buttonstate; ! static int mouse_oldbuttonstate; ! static int old_mouse_x; ! static int old_mouse_y; ! static boolean mlooking; ! ! public static void ActivateMouse() { ! if (!mouse_avail || c == null) return; ! if (!mouse_active) { ! KBD.mx = KBD.my = 0; // don't spazz ! install_grabs(); ! mouse_active = true; ! } ! } ! public static void DeactivateMouse() { ! // if (!mouse_avail || c == null) return; ! if (mouse_active) { ! uninstall_grabs(); ! mouse_active = false; ! } ! } ! private static void install_grabs() { ! if (emptyCursor == null) { ! ImageIcon emptyIcon = new ImageIcon(new byte[0]); ! emptyCursor = c.getToolkit().createCustomCursor(emptyIcon.getImage(), new Point(0, 0), "emptyCursor"); ! } ! c.setCursor(emptyCursor); ! KBD.centerMouse(); ! ignorefirst = true; ! } ! private static void uninstall_grabs() { ! c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); ! } ! public static void toggleMouse() { ! if (mouse_avail) { ! mouse_avail=false; ! DeactivateMouse(); ! } else { ! mouse_avail=true; ! ActivateMouse(); ! } ! } ! public static void Init() { ! in_mouse = Cvar.Get("in_mouse", "1", CVAR_ARCHIVE); ! in_joystick = Cvar.Get("in_joystick", "0", CVAR_ARCHIVE); ! } ! public static void Shutdown() { ! mouse_avail = false; ! } ! public static void Real_IN_Init() { ! // mouse variables ! Globals.m_filter = Cvar.Get("m_filter", "0", 0); ! Globals.in_mouse = Cvar.Get("in_mouse", "1", CVAR_ARCHIVE); ! Globals.freelook = Cvar.Get("freelook", "1", 0 ); ! Globals.lookstrafe = Cvar.Get("lookstrafe", "0", 0); ! Globals.sensitivity = Cvar.Get("sensitivity", "3", 0); ! Globals.m_pitch = Cvar.Get("m_pitch", "0.022", 0); ! Globals.m_yaw = Cvar.Get("m_yaw", "0.022", 0); ! Globals.m_forward = Cvar.Get("m_forward", "1", 0); ! Globals.m_side = Cvar.Get("m_side", "0.8", 0); ! ! Cmd.AddCommand("+mlook", new xcommand_t() { ! public void execute() {MLookDown();}}); ! Cmd.AddCommand("-mlook", new xcommand_t() { ! public void execute() {MLookUp();}}); ! ! Cmd.AddCommand ("force_centerview", new xcommand_t() { ! public void execute() {Force_CenterView_f();}}); ! Cmd.AddCommand ("togglemouse", new xcommand_t() { ! public void execute() {toggleMouse();}}); ! ! IN.mouse_avail = true; ! } ! public static void Commands() { ! int i; ! ! if (!IN.mouse_avail) ! return; ! ! for (i=0 ; i<3 ; i++) { ! if ( (IN.mouse_buttonstate & (1<<i)) != 0 && (IN.mouse_oldbuttonstate & (1<<i)) == 0 ) ! KBD.Do_Key_Event(Key.K_MOUSE1 + i, true); ! ! if ( (IN.mouse_buttonstate & (1<<i)) == 0 && (IN.mouse_oldbuttonstate & (1<<i)) != 0 ) ! KBD.Do_Key_Event(Key.K_MOUSE1 + i, false); ! } ! IN.mouse_oldbuttonstate = IN.mouse_buttonstate; ! } ! public static void Frame() { ! if ( !cl.refresh_prepped || cls.key_dest == key_console || cls.key_dest == key_menu) ! DeactivateMouse(); ! else ! ActivateMouse(); ! } ! public static void CenterView() { ! cl.viewangles[PITCH] = -SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]); ! } ! ! public static void Move(usercmd_t cmd) { ! if (!IN.mouse_avail) ! return; ! ! if (Globals.m_filter.value != 0.0f) { ! KBD.mx = (KBD.mx + IN.old_mouse_x) / 2; ! KBD.my = (KBD.my + IN.old_mouse_y) / 2; ! } ! ! IN.old_mouse_x = KBD.mx; ! IN.old_mouse_y = KBD.my; ! ! KBD.mx = (int)(KBD.mx * Globals.sensitivity.value); ! KBD.my = (int)(KBD.my * Globals.sensitivity.value); ! ! // add mouse X/Y movement to cmd ! if ( (CL_input.in_strafe.state & 1) != 0 || ((Globals.lookstrafe.value != 0) && IN.mlooking )) { ! cmd.sidemove += Globals.m_side.value * KBD.mx; ! } else { ! Globals.cl.viewangles[YAW] -= Globals.m_yaw.value * KBD.mx; ! } ! ! if ( (IN.mlooking || Globals.freelook.value != 0.0f) && (CL_input.in_strafe.state & 1) == 0) { ! Globals.cl.viewangles[PITCH] += Globals.m_pitch.value * KBD.my; ! } else { ! cmd.forwardmove -= Globals.m_forward.value * KBD.my; ! } ! KBD.mx = KBD.my = 0; ! } ! static void MLookDown() { ! mlooking = true; ! } ! static void MLookUp() { ! mlooking = false; ! CenterView(); ! } ! static void Force_CenterView_f() { ! Globals.cl.viewangles[PITCH] = 0; ! } ! } --- 46,236 ---- public final class IN extends Globals { ! static Component c = null; ! static Cursor emptyCursor = null; ! static boolean mouse_avail = true; ! static boolean mouse_active = false; ! static boolean ignorefirst = false; ! static int mouse_buttonstate; ! static int mouse_oldbuttonstate; ! static int old_mouse_x; ! static int old_mouse_y; ! static boolean mlooking; ! public static void ActivateMouse() { ! if (!mouse_avail || c == null) ! return; ! if (!mouse_active) { ! KBD.mx = KBD.my = 0; // don't spazz ! install_grabs(); ! mouse_active = true; ! } ! } ! public static void DeactivateMouse() { ! // if (!mouse_avail || c == null) return; ! if (mouse_active) { ! uninstall_grabs(); ! mouse_active = false; ! } ! } ! private static void install_grabs() { ! if (emptyCursor == null) { ! ImageIcon emptyIcon = new ImageIcon(new byte[0]); ! emptyCursor = c.getToolkit().createCustomCursor( ! emptyIcon.getImage(), new Point(0, 0), "emptyCursor"); ! } ! c.setCursor(emptyCursor); ! KBD.centerMouse(); ! ignorefirst = true; ! } ! private static void uninstall_grabs() { ! c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); ! } ! public static void toggleMouse() { ! if (mouse_avail) { ! mouse_avail = false; ! DeactivateMouse(); ! } else { ! mouse_avail = true; ! ActivateMouse(); ! } ! } ! public static void Init() { ! in_mouse = Cvar.Get("in_mouse", "1", CVAR_ARCHIVE); ! in_joystick = Cvar.Get("in_joystick", "0", CVAR_ARCHIVE); ! } ! public static void Shutdown() { ! mouse_avail = false; ! } ! public static void Real_IN_Init() { ! // mouse variables ! Globals.m_filter = Cvar.Get("m_filter", "0", 0); ! Globals.in_mouse = Cvar.Get("in_mouse", "1", CVAR_ARCHIVE); ! Globals.freelook = Cvar.Get("freelook", "1", 0); ! Globals.lookstrafe = Cvar.Get("lookstrafe", "0", 0); ! Globals.sensitivity = Cvar.Get("sensitivity", "3", 0); ! Globals.m_pitch = Cvar.Get("m_pitch", "0.022", 0); ! Globals.m_yaw = Cvar.Get("m_yaw", "0.022", 0); ! Globals.m_forward = Cvar.Get("m_forward", "1", 0); ! Globals.m_side = Cvar.Get("m_side", "0.8", 0); ! Cmd.AddCommand("+mlook", new xcommand_t() { ! public void execute() { ! MLookDown(); ! } ! }); ! Cmd.AddCommand("-mlook", new xcommand_t() { ! public void execute() { ! MLookUp(); ! } ! }); ! Cmd.AddCommand("force_centerview", new xcommand_t() { ! public void execute() { ! Force_CenterView_f(); ! } ! }); ! Cmd.AddCommand("togglemouse", new xcommand_t() { ! public void execute() { ! toggleMouse(); ! } ! }); ! ! IN.mouse_avail = true; ! } ! ! public static void Commands() { ! int i; ! ! if (!IN.mouse_avail) ! return; ! ! for (i = 0; i < 3; i++) { ! if ((IN.mouse_buttonstate & (1 << i)) != 0 ! && (IN.mouse_oldbuttonstate & (1 << i)) == 0) ! KBD.Do_Key_Event(Key.K_MOUSE1 + i, true); ! ! if ((IN.mouse_buttonstate & (1 << i)) == 0 ! && (IN.mouse_oldbuttonstate & (1 << i)) != 0) ! KBD.Do_Key_Event(Key.K_MOUSE1 + i, false); ! } ! IN.mouse_oldbuttonstate = IN.mouse_buttonstate; ! } ! ! public static void Frame() { ! ! if (!cl.refresh_prepped || cls.key_dest == key_console ! || cls.key_dest == key_menu) ! DeactivateMouse(); ! else ! ActivateMouse(); ! } ! ! public static void CenterView() { ! cl.viewangles[PITCH] = -Math3D ! .SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]); ! } ! ! public static void Move(usercmd_t cmd) { ! if (!IN.mouse_avail) ! return; ! ! if (Globals.m_filter.value != 0.0f) { ! KBD.mx = (KBD.mx + IN.old_mouse_x) / 2; ! KBD.my = (KBD.my + IN.old_mouse_y) / 2; ! } ! ! IN.old_mouse_x = KBD.mx; ! IN.old_mouse_y = KBD.my; ! ! KBD.mx = (int) (KBD.mx * Globals.sensitivity.value); ! KBD.my = (int) (KBD.my * Globals.sensitivity.value); ! ! // add mouse X/Y movement to cmd ! if ((CL_input.in_strafe.state & 1) != 0 ! || ((Globals.lookstrafe.value != 0) && IN.mlooking)) { ! cmd.sidemove += Globals.m_side.value * KBD.mx; ! } else { ! Globals.cl.viewangles[YAW] -= Globals.m_yaw.value * KBD.mx; ! } ! ! if ((IN.mlooking || Globals.freelook.value != 0.0f) ! && (CL_input.in_strafe.state & 1) == 0) { ! Globals.cl.viewangles[PITCH] += Globals.m_pitch.value * KBD.my; ! } else { ! cmd.forwardmove -= Globals.m_forward.value * KBD.my; ! } ! KBD.mx = KBD.my = 0; ! } ! ! static void MLookDown() { ! mlooking = true; ! } ! ! static void MLookUp() { ! mlooking = false; ! CenterView(); ! } ! ! static void Force_CenterView_f() { ! Globals.cl.viewangles[PITCH] = 0; ! } ! ! } \ No newline at end of file Index: Sys.java =================================================================== RCS file: /cvsroot/jake2/jake2/src/jake2/sys/Sys.java,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** Sys.java 10 Sep 2004 19:02:56 -0000 1.8 --- Sys.java 22 Sep 2004 19:22:14 -0000 1.9 *************** *** 6,27 **** */ /* ! Copyright (C) 1997-2001 Id Software, Inc. ! This program is free software; you can redistribute it and/or ! modify it under the terms of the GNU General Public License ! as published by the Free Software Foundation; either version 2 ! of the License, or (at your option) any later version. ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! See the GNU General Public License for more details. ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! */ package jake2.sys; --- 6,27 ---- */ /* ! Copyright (C) 1997-2001 Id Software, Inc. ! This program is free software; you can redistribute it and/or ! modify it under the terms of the GNU General Public License ! as published by the Free Software Foundation; either version 2 ! of the License, or (at your option) any later version. ! This program is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! See the GNU General Public License for more details. ! You should have received a copy of the GNU General Public License ! along with this program; if not, write to the Free Software ! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! */ package jake2.sys; *************** *** 41,246 **** public final class Sys extends Defines { ! public static void Error(String error) { ! CL.Shutdown(); ! //StackTrace(); ! new Exception(error).printStackTrace(); ! System.exit(1); ! } ! public static void Quit() { ! CL.Shutdown(); ! System.exit(0); ! } ! //ok! ! public static File[] FindAll(String path, int musthave, int canthave) { ! int index= path.lastIndexOf('/'); ! if (index != -1) { ! findbase= path.substring(0, index); ! findpattern= path.substring(index + 1, path.length()); ! } ! else { ! findbase= path; ! findpattern= "*"; ! } ! if (findpattern.equals("*.*")) { ! findpattern= "*"; ! } ! File fdir= new File(findbase); ! if (!fdir.exists()) ! return null; ! FilenameFilter filter= new FileFilter(findpattern, musthave, canthave); ! return fdir.listFiles(filter); ! } ! /** ! * Match the pattern findpattern against the filename. ! * ! * In the pattern string, `*' matches any sequence of characters, ! * `?' matches any character, [SET] matches any character in the specified set, ! * [!SET] matches any character not in the specified set. ! * A set is composed of characters or ranges; a range looks like ! * character hyphen character (as in 0-9 or A-Z). ! * [0-9a-zA-Z_] is the set of characters allowed in C identifiers. ! * Any other character in the pattern must be matched exactly. ! * To suppress the special syntactic significance of any of `[]*?!-\', ! * and match the character exactly, precede it with a `\'. ! */ ! static class FileFilter implements FilenameFilter { ! String regexpr; ! int musthave, canthave; ! FileFilter(String findpattern, int musthave, int canthave) { ! this.regexpr= convert2regexpr(findpattern); ! this.musthave= musthave; ! this.canthave= canthave; ! } ! /* ! * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) ! */ ! public boolean accept(File dir, String name) { ! if (name.matches(regexpr)) { ! return CompareAttributes(dir, musthave, canthave); ! } ! return false; ! } ! String convert2regexpr(String pattern) { ! StringBuffer sb= new StringBuffer(); ! char c; ! boolean escape= false; ! String subst; ! // convert pattern ! for (int i= 0; i < pattern.length(); i++) { ! c= pattern.charAt(i); ! subst= null; ! switch (c) { ! case '*' : ! subst= (!escape) ? ".*" : "*"; ! break; ! case '.' : ! subst= (!escape) ? "\\." : "."; ! break; ! case '!' : ! subst= (!escape) ? "^" : "!"; ! break; ! case '?' : ! subst= (!escape) ? "." : "?"; ! break; ! case '\\' : ! escape= !escape; ! break; ! default : ! escape= false; ! } ! if (subst != null) { ! sb.append(subst); ! escape= false; ! } ! else ! sb.append(c); ! } ! // the converted pattern ! String regexpr= sb.toString(); ! //Com.DPrintf("pattern: " + pattern + " regexpr: " + regexpr + '\n'); ! try { ! Pattern.compile(regexpr); ! } ! catch (PatternSyntaxException e) { ! Com.Printf("invalid file pattern ( *.* is used instead )\n"); ! return ".*"; // the default ! } ! return regexpr; ! } ! boolean CompareAttributes(File dir, int musthave, int canthave) { ! // . and .. never match ! String name= dir.getName(); ! if (name.equals(".") || name.equals("..")) ! return false; ! return true; ! } ! } ! private static long secbase= System.currentTimeMillis(); ! public static int Milliseconds() { ! return Globals.curtime= (int) (System.currentTimeMillis() - secbase); ! } ! //============================================ ! static File[] fdir; ! static int fileindex; ! static String findbase; ! static String findpattern; ! // ok. ! public static File FindFirst(String path, int musthave, int canthave) { ! if (fdir != null) ! Sys.Error("Sys_BeginFind without close"); ! // COM_FilePath (path, findbase); ! fdir= FindAll(path, canthave, musthave); ! fileindex= 0; ! if (fdir == null) ! return null; ! return FindNext(); ! } ! public static File FindNext() { ! if (fileindex >= fdir.length) ! return null; ! return fdir[fileindex++]; ! } ! public static void FindClose() { ! fdir= null; ! } ! public static void SendKeyEvents() { ! KBD.Update(); ! // grab frame time ! Globals.sys_frame_time= Sys.Milliseconds(); ! } ! public static String GetClipboardData() { ! // TODO: implement GetClipboardData ! return null; ! } ! public static void ConsoleOutput(String msg) { ! if (Globals.nostdout != null && Globals.nostdout.value != 0) ! return; ! System.out.print(msg); ! } ! } --- 41,248 ---- public final class Sys extends Defines { ! public static void Error(String error) { ! CL.Shutdown(); ! //StackTrace(); ! new Exception(error).printStackTrace(); ! System.exit(1); ! } ! public static void Quit() { ! CL.Shutdown(); ! System.exit(0); ! } ! //ok! ! public static File[] FindAll(String path, int musthave, int canthave) { ! int index = path.lastIndexOf('/'); ! if (index != -1) { ! findbase = path.substring(0, index); ! findpattern = path.substring(index + 1, path.length()); ! } else { ! findbase = path; ! findpattern = "*"; ! } ! if (findpattern.equals("*.*")) { ! findpattern = "*"; ! } ! File fdir = new File(findbase); ! if (!fdir.exists()) ! return null; ! FilenameFilter filter = new FileFilter(findpattern, musthave, canthave); ! return fdir.listFiles(filter); ! } ! /** ! * Match the pattern findpattern against the filename. ! * ! * In the pattern string, `*' matches any sequence of characters, `?' ! * matches any character, [SET] matches any character in the specified set, ! * [!SET] matches any character not in the specified set. A set is composed ! * of characters or ranges; a range looks like character hyphen character ! * (as in 0-9 or A-Z). [0-9a-zA-Z_] is the set of characters allowed in C ! * identifiers. Any other character in the pattern must be matched exactly. ! * To suppress the special syntactic significance of any of `[]*?!-\', and ! * match the character exactly, precede it with a `\'. ! */ ! static class FileFilter implements FilenameFilter { ! String regexpr; ! int musthave, canthave; ! FileFilter(String findpattern, int musthave, int canthave) { ! this.regexpr = convert2regexpr(findpattern); ! this.musthave = musthave; ! this.canthave = canthave; ! } ! /* ! * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) ! */ ! public boolean accept(File dir, String name) { ! if (name.matches(regexpr)) { ! return CompareAttributes(dir, musthave, canthave); ! } ! return false; ! } ! String convert2regexpr(String pattern) { ! StringBuffer sb = new StringBuffer(); ! char c; ! boolean escape = false; ! String subst; ! // convert pattern ! for (int i = 0; i < pattern.length(); i++) { ! c = pattern.charAt(i); ! subst = null; ! switch (c) { ! case '*': ! subst = (!escape) ? ".*" : "*"; ! break; ! case '.': ! subst = (!escape) ? "\\." : "."; ! break; ! case '!': ! subst = (!escape) ? "^" : "!"; ! break; ! case '?': ! subst = (!escape) ? "." : "?"; ! break; ! case '\\': ! escape = !escape; ! break; ! default: ! escape = false; ! } ! if (subst != null) { ! sb.append(subst); ! escape = false; ! } else ! sb.append(c); ! } ! // the converted pattern ! String regexpr = sb.toString(); ! //Com.DPrintf("pattern: " + pattern + " regexpr: " + regexpr + ! // '\n'); ! try { ! Pattern.compile(regexpr); ! } catch (PatternSyntaxException e) { ! Com.Printf("invalid file pattern ( *.* is used instead )\n"); ! return ".*"; // the default ! } ! return regexpr; ! } ! boolean CompareAttributes(File dir, int musthave, int canthave) { ! // . and .. never match ! String name = dir.getName(); ! if (name.equals(".") || name.equals("..")) ! return false; ! return true; ! } ! } ! private static long secbase = System.currentTimeMillis(); ! public static int Milliseconds() { ! return Globals.curtime = (int) (System.currentTimeMillis() - secbase); ! } ! //============================================ ! static File[] fdir; ! static int fileindex; ! static String findbase; ! static String findpattern; ! // ok. ! public static File FindFirst(String path, int musthave, int canthave) { ! if (fdir != null) ! Sys.Error("Sys_BeginFind without close"); ! // COM_FilePath (path, findbase); ! fdir = FindAll(path, canthave, musthave); ! fileindex = 0; ! if (fdir == null) ! return null; ! return FindNext(); ! } ! public static File FindNext() { ! if (fileindex >= fdir.length) ! return null; ! return fdir[fileindex++]; ! } ! public static void FindClose() { ! fdir = null; ! } ! public static void SendKeyEvents() { ! KBD.Update(); ! ! // grab frame time ! Globals.sys_frame_time = Sys.Milliseconds(); ! } ! ! public static String GetClipboardData() { ! // TODO: implement GetClipboardData ! return null; ! } ! ! public static void ConsoleOutput(String msg) { ! if (Globals.nostdout != null && Globals.nostdout.value != 0) ! return; ! ! System.out.print(msg); ! } ! ! } \ No newline at end of file |