1 /*
2  * Schism Tracker - a cross-platform Impulse Tracker clone
3  * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
4  * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
5  * copyright (c) 2009 Storlek & Mrs. Brisby
6  * copyright (c) 2010-2012 Storlek
7  * URL: http://schismtracker.org/
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23 #include "headers.h"
24 #include "song.h"
25 #include "it.h"
26 
27 static int _cache_ok = 0;
28 void memused_songchanged(void)
29 {
30 	_cache_ok = 0;
31 }
32 
33 
34 /* packed patterns */
35 unsigned int memused_patterns(void)
36 {
37 	unsigned int i, nm, rows, q;
38 	static unsigned int p_cached;
39 	song_note_t *ptr;
40 
41 	if (_cache_ok & 1) return p_cached;
42 	_cache_ok |= 1;
43 
44 	q = 0;
45 	nm = csf_get_num_patterns(current_song);
46 	for (i = 0; i < nm; i++) {
47 		if (csf_pattern_is_empty(current_song, i)) continue;
48 		rows = song_get_pattern(i, &ptr);
49 		q += (rows*256);
50 	}
51 	return p_cached = q;
52 }
53 
54 unsigned int memused_clipboard(void)
55 {
56 	unsigned int q = 0;
57 	static unsigned int c_cached;
58 
59 	if (_cache_ok & 2) return c_cached;
60 	_cache_ok |= 2;
61 
62 	memused_get_pattern_saved(&q, NULL);
63 	c_cached = q*256;
64 	return c_cached;
65 }
66 unsigned int memused_history(void)
67 {
68 	static unsigned int h_cached;
69 	unsigned int q = 0;
70 	if (_cache_ok & 4) return h_cached;
71 	_cache_ok |= 4;
72 	memused_get_pattern_saved(NULL, &q);
73 	return h_cached = (q * 256);
74 }
75 unsigned int memused_samples(void)
76 {
77 	song_sample_t *s;
78 	static unsigned int s_cache;
79 	unsigned int q, qs;
80 	int i;
81 
82 	if (_cache_ok & 8) return s_cache;
83 	_cache_ok |= 8;
84 
85 	q = 0;
86 	for (i = 0; i < MAX_SAMPLES; i++) {
87 		s = song_get_sample(i);
88 		qs = s->length;
89 		if (s->flags & CHN_STEREO) qs *= 2;
90 		if (s->flags & CHN_16BIT) qs *= 2;
91 		q += qs;
92 	}
93 	return s_cache = q;
94 }
95 unsigned int memused_instruments(void)
96 {
97 	static unsigned int i_cache;
98 	unsigned int q;
99 	int i;
100 
101 	if (_cache_ok & 16) return i_cache;
102 	_cache_ok |= 16;
103 
104 	q = 0;
105 	for (i = 0; i < MAX_INSTRUMENTS; i++) {
106 		if (csf_instrument_is_empty(current_song->instruments[i])) continue;
107 		q += 512;
108 	}
109 	return i_cache = q;
110 }
111 unsigned int memused_songmessage(void)
112 {
113 	static unsigned int m_cache;
114 	if (_cache_ok & 32) return m_cache;
115 	_cache_ok |= 32;
116 	return m_cache = strlen(current_song->message);
117 }
118 
119 
120 /* this makes an effort to calculate about how much memory IT would report
121 is being taken up by the current song.
122 
123 it's pure, unadulterated crack, but the routines are useful for schism mode :)
124 */
125 static unsigned int _align4k(unsigned int q) {
126 	return ((q + 0xfff) & ~0xfff);
127 }
128 unsigned int memused_ems(void)
129 {
130 	return _align4k(memused_samples())
131 		+ _align4k(memused_history())
132 		+ _align4k(memused_patterns());
133 }
134 unsigned int memused_lowmem(void)
135 {
136 	return memused_songmessage() + memused_instruments()
137 		+ memused_clipboard();
138 }
139