/ld27

To get this branch, use:
bzr branch http://9ix.org/bzr/ld27

« back to all changes in this revision

Viewing changes to zoetrope/core/app.lua

  • Committer: Josh C
  • Date: 2014-07-04 22:05:15 UTC
  • Revision ID: josh@9ix.org-20140704220515-1lyoulmix915mlcp
propagate scaling / translate properly

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
-- Class: App
 
2
-- An app is where all the magic happens. :) It contains a
1
3
-- view, the group where all major action happens, as well as the
2
4
-- meta view, which persists across views. Only one app may run at
3
5
-- a time.
7
7
-- An app's job is to get things up and running -- most of its logic
8
8
-- lives in its onRun handler, but for a simple app, you can also
9
9
-- use the onUpdate handler instead of writing a custom <View>.
 
10
--
10
11
-- Once an app has begun running, it may be accessed globally via
11
12
-- <the>.app.
12
13
--
28
28
        -- Property: name
29
29
        -- This is shown in the window title bar.
30
30
        name = 'Zoetrope',
31
 
        
 
31
 
32
32
        -- Property: icon
33
33
        -- A path to an image to use as the window icon (a 32x32 PNG is recommended).
34
 
        -- This doesn't affect the actual executable's icon in the taskbar or dock. 
 
34
        -- This doesn't affect the actual executable's icon in the taskbar or dock.
35
35
 
36
36
        -- Property: fps
37
37
        -- Maximum frames per second requested. In practice, your
38
38
        -- FPS may vary from frame to frame. Every event handler (e.g. onUpdate)
39
39
        -- is passed the exact elapsed time in seconds.
40
40
        fps = 60,
41
 
        
 
41
 
42
42
        -- Property: timeScale
43
43
        -- Multiplier for elapsed time; 1.0 is normal, 0 is completely frozen.
44
44
        timeScale = 1,
45
 
        
 
45
 
46
46
        -- Property: active
47
47
        -- If false, nothing receives update-related events, including the meta view.
48
48
        -- These events specifically are onStartFrame, onUpdate, and onEndFrame.
52
52
        -- Should the app automatically set its active property to false when its
53
53
        -- window loses focus?
54
54
        deactivateOnBlur = true,
55
 
        
 
55
 
56
56
        -- Property: view
57
57
        -- The current <View>. When the app is running, this is also accessible
58
58
        -- globally via <the>.view. In order to switch views, you must set this
99
99
                obj = self:extend(obj)
100
100
 
101
101
                -- set icon if possible
102
 
                
 
102
 
103
103
                if self.icon then
104
 
                        love.graphics.setIcon(Cached:image(self.icon))
 
104
                        love.window.setIcon(Cached:image(self.icon))
105
105
                end
106
 
        
 
106
 
107
107
                -- view containers
108
108
 
109
 
                obj.meta = obj.meta or Group:new()
110
 
                obj.view = obj.view or View:new()               
111
 
                
 
109
                obj.meta = obj.meta or View:new()
 
110
                obj.view = obj.view or View:new()
 
111
 
112
112
                -- input
113
113
 
114
114
                if love.keyboard then
136
136
 
137
137
                -- screen dimensions and state
138
138
 
139
 
                obj.width, obj.height, obj.fullscreen = love.graphics.getMode()
 
139
    local w, h, flags = love.window.getMode()
 
140
    if not obj.width then obj.width = w end
 
141
    if not obj.height then obj.height = h end
 
142
    obj.windowflags = flags
 
143
                obj.fullscreen = obj.windowflags.fullscreen
140
144
 
141
145
                -- housekeeping
142
 
                
 
146
 
143
147
                the.app = obj
144
148
                if obj.onNew then obj:onNew() end
145
149
                return obj
150
154
        --
151
155
        -- Arguments:
152
156
        --              none
153
 
        -- 
 
157
        --
154
158
        -- Returns:
155
159
        --              nothing
156
160
 
164
168
                -- attach debug console
165
169
 
166
170
                if DEBUG then
167
 
                        self.console = DebugConsole:new()
168
 
                        self.meta:add(self.console)
 
171
                        debugger.init()
169
172
                end
170
173
 
171
174
                -- set up callbacks
172
 
                
173
 
                love.graphics.setCaption(self.name)
 
175
 
 
176
                love.window.setTitle(self.name)
174
177
                love.update = function (elapsed) self:update(elapsed) end
175
178
                love.draw = function() self:draw() end
176
 
                love.focus = function (value) self:onFocus(value) end   
 
179
                love.focus = function (value) self:onFocus(value) end
177
180
 
178
181
                if self.onRun then self:onRun() end
179
 
                self._nextFrameTime = love.timer.getMicroTime()
 
182
                self._nextFrameTime = love.timer.getTime()
180
183
        end,
181
 
        
 
184
 
182
185
        -- Method: quit
183
186
        -- Quits the application immediately.
184
187
        --
200
203
        --
201
204
        -- Returns:
202
205
        --              nothing
203
 
        
 
206
 
204
207
        useSysCursor = function (self, value)
205
208
                if STRICT then
206
209
                        assert(value == true or value == false,
228
231
                        assert(not self.fullscreen, 'asked to enter fullscreen when already in fullscreen')
229
232
                end
230
233
 
231
 
                local modes = love.graphics.getModes()
 
234
                local modes = love.window.getFullscreenModes()
232
235
 
233
236
                if not hint then
234
237
                        if self.width * 9 == self.height * 16 then
246
249
                for _, mode in pairs(modes) do
247
250
                        mode.area = mode.width * mode.height
248
251
 
249
 
                        if (mode.area > bestMode.area) and 
 
252
                        if (mode.area > bestMode.area) and
250
253
                           ((hint == 'letterbox' and mode.width == self.width) or
251
254
                            (hint == 'pillar' and mode.height == self.height)) then
252
255
                                        bestMode = mode
256
259
                -- if we found a match, switch to it
257
260
 
258
261
                if bestMode.width then
259
 
                        love.graphics.setMode(bestMode.width, bestMode.height, true)
 
262
                        love.window.setMode(bestMode.width, bestMode.height, {fullscreen = true})
260
263
                        self.fullscreen = true
261
264
 
262
265
                        -- and adjust inset and scissor
284
287
                if STRICT then
285
288
                        assert(self.fullscreen, 'asked to exit fullscreen when already out of fullscreen')
286
289
                end
287
 
        
288
 
                love.graphics.setMode(self.width, self.height, false)
 
290
 
 
291
                love.window.setMode(self.width, self.height, {fullscreen = false})
289
292
                love.graphics.setScissor(0, 0, self.width, self.height)
290
293
                self.fullscreen = false
291
294
                self.inset.x = 0
335
338
        --
336
339
        -- Arguments:
337
340
        --              sprite - sprite to add
338
 
        -- 
 
341
        --
339
342
        -- Returns:
340
 
        --              nothing
 
343
        --              sprite added
341
344
 
342
345
        add = function (self, sprite)
343
 
                self.view:add(sprite)
 
346
                return self.view:add(sprite)
344
347
        end,
345
348
 
346
349
        -- Method: remove
365
368
                elapsed = elapsed * self.timeScale
366
369
 
367
370
                -- sync the.view with our current view
368
 
                
 
371
 
369
372
                local view = self.view
370
373
                if the.view ~= view then the.view = view end
371
374
 
381
384
 
382
385
                -- update everyone
383
386
                -- all update events bubble up from child to parent
384
 
                -- (we consider the meta view a little 
 
387
                -- (we consider the meta view a little
385
388
 
386
389
                view:startFrame(elapsed)
387
390
                self.meta:startFrame(elapsed)
388
391
                if self.onStartFrame then self:onStartFrame(elapsed) end
389
 
                
390
 
                view:update(elapsed)    
 
392
 
 
393
                view:update(elapsed)
391
394
                self.meta:update(elapsed)
392
395
                if self.onUpdate then self:onUpdate(elapsed) end
393
396
 
395
398
                self.meta:endFrame(elapsed)
396
399
                if self.onEndFrame then self:onEndFrame(elapsed) end
397
400
        end,
398
 
        
 
401
 
399
402
        draw = function (self)
400
 
drawStart = love.timer.getMicroTime()
 
403
drawStart = love.timer.getTime()
401
404
                local inset = self.inset.x ~= 0 or self.inset.y ~= 0
402
405
 
403
406
                if inset then love.graphics.translate(self.inset.x, self.inset.y) end
407
410
 
408
411
                -- sleep off any unneeded time to keep up at our FPS
409
412
 
410
 
                local now = love.timer.getMicroTime()
 
413
                local now = love.timer.getTime()
411
414
the.drawTook = now - drawStart
412
415
                if self._nextFrameTime < now then
413
416
                        self._nextFrameTime = now
437
440
                        result = result .. 'inactive'
438
441
                end
439
442
 
440
 
                return result .. ', ' .. self.fps .. ' fps, ' .. self.view:count(true) .. ' sprites)'
 
443
                return result .. ', ' .. tostring(self.fps) .. ' fps, ' .. self.view:count(true) .. ' sprites)'
441
444
        end
442
445
}