View difference between Paste ID: zZNLvKg9 and 1UB9Wwbd
SHOW: | | - or go back to the newest paste.
1
grid = {};
2
iodispatch = {};
3
vspacing = 4;
4
hspacing = 4;
5
cursor = 0;
6
cellcount = 0;
7
pageofs = 0;
8
9
vertex_shader = [[
10
uniform int n_ticks;
11
12
void main(void)
13
{
14
    gl_TexCoord[0] = gl_MultiTexCoord0;
15
    gl_TexCoord[0].s = gl_TexCoord[0].s + fract(n_ticks / 64.0);
16
    gl_TexCoord[0].t = gl_TexCoord[0].t + fract(n_ticks / 64.0);
17
    gl_Position = ftransform();
18
}]];
19
20
fragment_shader = [[
21
#version 120
22
uniform sampler2D tex;
23
24
void main() {
25
    vec4 color = texture2D(tex, gl_TexCoord[0].st);
26
	gl_FragColor = color;
27
}
28
]];
29
30
local function ledconfig_iofun(iotbl)
31
	local restbl = keyconfig:match(iotbl);
32
33
	if (iotbl.active and restbl and restbl[1] and
34
	    ledconfig:input(restbl[1]) == true) then
35
	   gridle_input = keyconfig.iofun;
36
	end
37
end
38
39
function gridle()
40
    system_load("scripts/keyconf.lua")();
41
    system_load("scripts/keyconf_mame.lua")();
42
    system_load("scripts/ledconf.lua")();
43
44
    games = list_games( {} );
45
    if (#games == 0) then
46
        error "No games found";
47
        shutdown();
48
    end
49
50
    keyconfig = keyconf_create(1, {
51
        "rMENU_ESCAPE", "rMENU_LEFT", "rMENU_RIGHT", "rMENU_UP",
52
        "rMENU_DOWN", "rMENU_SELECT", "rGROW_ICONS", "rSHRINK_ICONS" } );
53
    keyconfig.iofun = gridle_input;
54
	if (keyconfig.active == false) then
55
		gridle_input = function(iotbl) -- keyconfig io function hook
56
			if (keyconfig:input(iotbl) == true) then
57
				keyconf_tomame(keyconfig, "_mame/cfg/default.cfg");
58
59
				ledconfig = ledconf_create( keyconfig:labels() );
60
				if (ledconfig.active == false) then
61
					gridle_input = ledconfig_iofun;
62
				else -- no LED controller present, or LED configuration already exists
63
					gridle_input = keyconfig.iofun;
64
				end
65
			end
66
		end
67
	else
68
		ledconfig = ledconf_create( keyconfig:labels() );
69
		if (ledconfig.active == false) then
70
            gridle_input = ledconf_iofun;
71
		end
72
	end
73
74
    iodispatch["GROW_ICONS"]   = function(iotbl) resize_grid(16); end
75
    iodispatch["SHRINK_ICONS"] = function(iotbl) resize_grid(-16); end
76
    iodispatch["MENU_UP"]      = function(iotbl) play_sample("click.wav"); move_cursor( -1 * ncw); end
77
    iodispatch["MENU_DOWN"]    = function(iotbl) play_sample("click.wav"); move_cursor( ncw ); end
78
    iodispatch["MENU_LEFT"]    = function(iotbl) play_sample("click.wav"); move_cursor( -1 ); end
79
    iodispatch["MENU_RIGHT"]   = function(iotbl) play_sample("click.wav"); move_cursor( 1 ); end
80
    iodispatch["MENU_ESCAPE"]  = function(iotbl) shutdown(); end
81
    iodispatch["MENU_SELECT"]  = function(iotbl) if (games[cursor + pageofs + 1]) then
82
    launch_target( games[cursor + pageofs + 1].title, LAUNCH_EXTERNAL); end end
83
84
    build_grid(128, 128);
85
86
    switch_default_texmode( TEX_REPEAT, TEX_REPEAT );
87
    bgimage = load_image("background.png");
88
    resize_image(bgimage, VRESW, VRESH);
89
    image_scale_txcos(bgimage, VRESW / 32, VRESH / 32);
90
    image_program(bgimage, vertex_shader, fragment_shader);
91
92
    show_image(bgimage);
93
    switch_default_texmode( TEX_CLAMP, TEX_CLAMP );
94
end
95
96
function cell_coords(x, y)
97
    return (0.5 * borderw) + x * (cell_width + hspacing), (0.5 * borderh) + y * (cell_height + vspacing);
98
end
99
100
function blend_gridcell(val, dt)
101
    local cursor_row = math.floor(cursor / ncw);
102
    gridcell_vid = grid[ cursor_row ][ cursor - cursor_row * ncw ];
103
104
    if (gridcell_vid) then
105
	    instant_image_transform(gridcell_vid);
106
	    blend_image(gridcell_vid, val, dt);
107
    end
108
end
109
110
function resize_grid(step)
111
 local new_cellw = cell_width; local new_cellh = cell_width;
112
113
 -- find the next grid size that would involve a density change
114
 repeat
115
    new_cellw = new_cellw + step;
116
 until math.floor(VRESW / (new_cellw + hspacing)) ~= ncw;
117
118
 repeat
119
    new_cellh = new_cellh + step;
120
 until math.floor(VRESH / (new_cellh + vspacing)) ~= nch;
121
122
-- safety checks
123
 if (new_cellw < 64 or new_cellw > VRESW * 0.75) then return; end
124
 if (new_cellh < 64 or new_cellh > VRESH * 0.75) then return; end
125
126
 cell_width = new_cellw;
127
 cell_height = new_cellh;
128
129
 local currgame = pageofs + cursor;
130
 local new_ncc = math.floor( VRESW / (new_cellw + hspacing) ) * math.floor( VRESH / (new_cellh + vspacing) );
131
 pageofs = math.floor( currgame / new_ncc ) * new_ncc;
132
 cursor = currgame - pageofs;
133
 if (cursor < 0) then cursor = 0; end
134
135
-- remove the old grid
136
 erase_grid(true);
137
 build_grid(cell_width, cell_height);
138
end
139
140
function move_cursor( ofs )
141
    blend_gridcell(0.3, 10);
142
    local pageofs_cur = pageofs;
143
	cursor = cursor + ofs;
144
145
-- paging calculations
146
	if (ofs > 0) then -- right/forward
147
		if (cursor >= ncc) then -- move right or "forward"
148
			cursor = cursor - ncc;
149
			pageofs_cur = pageofs_cur + ncc;
150
		end
151
152
		-- wrap around on overflow
153
		if (pageofs_cur + cursor >= #games) then
154
			pageofs_cur = 0;
155
			cursor = 0;
156
		end
157
	elseif (ofs < 0) then -- left/backward
158
		if (cursor < 0) then -- step back a page
159
			pageofs_cur = pageofs_cur - ncc;
160
			cursor = ncc - ( -1 * cursor);
161
162
			if (pageofs_cur < 0) then -- wrap page around
163
				pageofs_cur = math.floor(#games / ncc) * ncc;
164
			end
165
166
			if (cursor < 0 or cursor >= #games - pageofs_cur) then
167
				cursor = #games - pageofs_cur - 1;
168
			end
169
		end
170
	end
171
172
    local x,y = cell_coords(math.floor(cursor % ncw), math.floor(cursor / ncw));
173
174
-- reload images of the page has changed
175
	if (pageofs_cur ~= pageofs) then
176
		erase_grid(false);
177
		pageofs = pageofs_cur;
178
		build_grid(cell_width, cell_height);
179
	end
180
181
    blend_gridcell(1.0, 10);
182
    local game = games[cursor + pageofs + 1];
183
    setname = game and game.setname or nil;
184
185
    if (movievid) then
186
        expire_image(movievid, 40);
187
        blend_image(movievid, 0.0, 40);
188
        audio_gain(movieaid, 0.0, 40);
189
    end
190
191
    if (game and ledconfig) then
192
    	ledconfig:toggle(game.players, game.buttons);
193
    end
194
195
-- look for a movie, if one exists, enable a timer that we'll check for later
196
    if (setname and resource( "movies/" .. setname .. ".avi")) then
197
        movievid, movieaid = load_movie( "movies/" .. setname .. ".avi" );
198
        if (movievid and movieaid and movievid ~= BADID and movieaid ~= BADID) then
199
            audio_gain(movieaid, 0.0);
200
            move_image(movievid, x, y);
201
            hide_image(movievid);
202
            order_image(movievid, 3);
203
            resize_image(movievid, cell_width, cell_height);
204
            movietimer = 10;
205
        end
206
    else
207
        moviefile = "";
208
        movietimer = nil;
209
    end
210
211
end
212
213
function get_image(romset)
214
    local rvid = BADID;
215
216
    if resource("screenshots/" .. romset .. ".png") then
217
        rvid = load_image("screenshots/" .. romset .. ".png");
218
    end
219
220
    if (rvid == BADID) then
221
        rvid = render_text( [[\#000088\ffonts/default.ttf,96 ]] .. romset );
222
    end
223
224
    return rvid;
225
end
226
227
function erase_grid(rebuild)
228
    cellcount = 0;
229
230
    for row=0, nch-1 do
231
     for col=0, ncw-1 do
232
      if (grid[row][col]) then
233
234
        if (rebuild) then
235
            delete_image(grid[row][col]);
236
        else
237
            local delay = 10 + math.random(10, 30);
238
            local x, y = cell_coords(row, col);
239
            expire_image(grid[row][col], delay);
240
            rotate_image(grid[row][col], 270.0, delay);
241
            scale_image(grid[row][col], 0.01, 0.01, delay);
242
        end
243
244
       grid[row][col] = nil;
245
      end
246
     end
247
    end
248
249
end
250
251
function gridle_clock_pulse()
252
    if (movietimer) then
253
        movietimer = movietimer - 1;
254
        if (movietimer <= 0) then
255
            play_movie(movievid);
256
            blend_image(movievid, 1.0, 10);
257
            audio_gain(movieaid, 1.0, 40);
258
            movietimer = nil;
259
        end
260
    end
261
end
262
263
function build_grid(width, height)
264
--  figure out how many full cells we can fit with the current resolution
265
    ncw = math.floor(VRESW / (width + hspacing));
266
    nch = math.floor(VRESH / (height + vspacing));
267
    ncc = ncw * nch;
268
    cell_width = width;
269
    cell_height = height;
270
271
--  figure out how much "empty" space we'll have to pad with
272
    borderw = VRESW % (width + hspacing);
273
    borderh = VRESH % (height + vspacing);
274
275
    for row=0, nch-1 do
276
        grid[row] = {};
277
        for col=0, ncw-1 do
278
            local gameno = (row * ncw + col + pageofs + 1); -- games is 1 indexed
279
            if (games[gameno] == nil) then break; end
280
            local vid = get_image(games[gameno]["setname"]);
281
            resize_image(vid, cell_width, cell_height);
282
            move_image(vid,cell_coords(col, row));
283
            order_image(vid, 2);
284
	        blend_image(vid, 0.3);
285
--
286
	        local whitebg = fill_surface(cell_width, cell_height, 255, 255, 255);
287
	        order_image(whitebg, 1);
288
	        show_image(whitebg);
289
	        link_image(whitebg, vid);
290
		image_mask_clear(whitebg, MASK_SCALE);
291
	        image_mask_clear(whitebg, MASK_ORIENTATION);
292
	        image_mask_clear(whitebg, MASK_OPACITY);
293
294
            grid[row][col] = vid;
295
            cellcount = cellcount + 1;
296
        end
297
    end
298
299
    move_cursor(0);
300
end
301
302
function gridle_input(iotbl)
303
 local restbl = keyconfig:match(iotbl);
304
 if (restbl and iotbl.active) then
305
  for ind,val in pairs(restbl) do
306
   if (iodispatch[val]) then
307
     iodispatch[val](restbl);
308
   end
309
  end
310
 end
311
end