1 /* Mednafen - Multi-system Emulator
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 // Code for drawing save states and mooovies
19 // all functions should be called from the main thread
20 #include "main.h"
21 #include "video.h"
22 #include <string.h>
23 #include <trio/trio.h>
24
25 static MDFN_Surface *PreviewSurface = NULL, *TextSurface = NULL;
26 static MDFN_Rect PreviewRect, TextRect;
27
28 static StateStatusStruct *StateStatus;
29 static uint32 StateShow;
30 static bool IsMovie;
31
DrawStateMovieRow(MDFN_Surface * surface,int * nstatus,int cur,int recently_saved,const char * text)32 void DrawStateMovieRow(MDFN_Surface *surface, int *nstatus, int cur, int recently_saved, const char *text)
33 {
34 MDFN_DrawFillRect(surface, 0, 0, 230, 40, surface->MakeColor(0x00, 0x00, 0x00, 170));
35
36 // nstatus
37 for(int i = 1; i < 11; i++)
38 {
39 char stringie[2];
40 uint32 bordercol;
41 uint32 rect_bg_color = surface->MakeColor(0x00, 0x00, 0x00, 0xFF);
42
43 if(cur == (i % 10))
44 bordercol = surface->MakeColor(0x60, 0x20, 0xb0, 0xFF);
45 else
46 bordercol = surface->MakeColor(0, 0, 0, 0xFF);
47
48 stringie[0] = '0' + (i % 10);
49 stringie[1] = 0;
50
51 if(nstatus[i % 10])
52 {
53 rect_bg_color = surface->MakeColor(0x00, 0x38, 0x28, 0xFF);
54
55 if(recently_saved == (i % 10))
56 rect_bg_color = surface->MakeColor(0x48, 0x00, 0x34, 0xFF);
57 }
58
59 MDFN_DrawFillRect(surface, (i - 1) * 23, 0, 23, 18 + 1, bordercol, rect_bg_color);
60
61 DrawTextShadow(surface, (i - 1) * 23 + 7, 0, stringie, surface->MakeColor(0xE0, 0xFF, 0xE0, 0xFF), surface->MakeColor(0x00, 0x00, 0x00, 0xFF), MDFN_FONT_9x18_18x18);
62 }
63 DrawTextShadow(surface, 0, 20, text, surface->MakeColor(0xE0, 0xFF, 0xE0, 0xFF), surface->MakeColor(0x00, 0x00, 0x00, 0xFF), MDFN_FONT_9x18_18x18, 230);
64 }
65
66
SaveStatesActive(void)67 bool SaveStatesActive(void)
68 {
69 return(StateStatus);
70 }
71
SSCleanup(void)72 static void SSCleanup(void)
73 {
74 if(PreviewSurface)
75 {
76 delete PreviewSurface;
77 PreviewSurface = NULL;
78 }
79
80 if(TextSurface)
81 {
82 delete TextSurface;
83 TextSurface = NULL;
84 }
85
86 if(StateStatus)
87 {
88 if(StateStatus->gfx)
89 delete[] StateStatus->gfx;
90
91 delete StateStatus;
92 StateStatus = NULL;
93 }
94 }
95
96 // TODO: Handle memory allocation errors.
DrawSaveStates(int32 screen_w,int32 screen_h,double exs,double eys,int rs,int gs,int bs,int as)97 void DrawSaveStates(int32 screen_w, int32 screen_h, double exs, double eys, int rs, int gs, int bs, int as)
98 {
99 if(StateShow <= Time::MonoMS())
100 {
101 SSCleanup();
102 }
103
104 if(StateStatus)
105 {
106 if(!PreviewSurface)
107 {
108 PreviewSurface = new MDFN_Surface(NULL, StateStatus->w + 2, StateStatus->h + 2, StateStatus->w + 2, MDFN_PixelFormat(MDFN_COLORSPACE_RGB, rs, gs, bs, as));
109
110 PreviewRect.x = PreviewRect.y = 0;
111 PreviewRect.w = StateStatus->w + 2;
112 PreviewRect.h = StateStatus->h + 2;
113
114 MDFN_DrawFillRect(PreviewSurface, 0, 0, StateStatus->w + 2, StateStatus->h + 2, PreviewSurface->MakeColor(0x00, 0x00, 0x9F, 0xFF), PreviewSurface->MakeColor(0x00, 0x00, 0x00, 0x80));
115
116 uint32 *psp = PreviewSurface->pixels;
117
118 psp += PreviewSurface->pitchinpix;
119 psp++;
120
121 if(StateStatus->gfx)
122 {
123 for(uint32 y = 0; y < StateStatus->h; y++)
124 {
125 uint8 *src_row = StateStatus->gfx + y * StateStatus->w * 3;
126
127 for(uint32 x = 0; x < StateStatus->w; x++)
128 {
129 psp[x] = PreviewSurface->MakeColor(src_row[0], src_row[1], src_row[2], 0xFF);
130 src_row += 3;
131 }
132 psp += PreviewSurface->pitchinpix;
133 }
134 }
135
136 if(!TextSurface)
137 {
138 TextSurface = new MDFN_Surface(NULL, 230, 40, 230, MDFN_PixelFormat(MDFN_COLORSPACE_RGB, rs, gs, bs, as));
139
140 TextRect.x = TextRect.y = 0;
141 TextRect.w = 230;
142 TextRect.h = 40;
143 }
144
145 if(IsMovie)
146 {
147 char text[256];
148
149 if(StateStatus->current_movie > 0)
150 trio_snprintf(text, 256, _("-recording movie %d-"), StateStatus->current_movie-1);
151 else if (StateStatus->current_movie < 0)
152 trio_snprintf(text, 256, _("-playing movie %d-"),-1 - StateStatus->current_movie);
153 else
154 trio_snprintf(text, 256, _("-select movie-"));
155
156 DrawStateMovieRow(TextSurface, StateStatus->status, StateStatus->current, StateStatus->recently_saved, text);
157 }
158 else
159 DrawStateMovieRow(TextSurface, StateStatus->status, StateStatus->current, StateStatus->recently_saved, _("-select state-"));
160 }
161 } // end if(StateStatus)
162
163 if(PreviewSurface)
164 {
165 MDFN_Rect tdrect, drect;
166
167 int meow = ((screen_w / CurGame->nominal_width) + 1) / 2;
168 if(!meow) meow = 1;
169
170 tdrect.w = TextRect.w * meow;
171 tdrect.h = TextRect.h * meow;
172 tdrect.x = (screen_w - tdrect.w) / 2;
173 tdrect.y = screen_h - tdrect.h;
174
175 BlitRaw(TextSurface, &TextRect, &tdrect);
176
177 drect.w = PreviewRect.w * meow;
178 drect.h = PreviewRect.h * meow;
179 drect.x = (screen_w - drect.w) / 2;
180 drect.y = screen_h - drect.h - tdrect.h - 4;
181
182 BlitRaw(PreviewSurface, &PreviewRect, &drect);
183
184 }
185
186 }
187
MT_SetStateStatus(StateStatusStruct * status)188 void MT_SetStateStatus(StateStatusStruct *status)
189 {
190 SSCleanup();
191
192 IsMovie = FALSE;
193 StateStatus = status;
194
195 if(status)
196 StateShow = Time::MonoMS() + MDFN_GetSettingUI("osd.state_display_time");
197 else
198 StateShow = 0;
199 }
200
MT_SetMovieStatus(StateStatusStruct * status)201 void MT_SetMovieStatus(StateStatusStruct *status)
202 {
203 SSCleanup();
204
205 IsMovie = TRUE;
206 StateStatus = status;
207
208 if(status)
209 StateShow = Time::MonoMS() + MDFN_GetSettingUI("osd.state_display_time");
210 else
211 StateShow = 0;
212 }
213
214